smsprotocols/smsstack/gsmu/src/Gsmuelem.cpp
branchopencode
changeset 24 6638e7f4bd8f
parent 20 244d7c5f118e
--- a/smsprotocols/smsstack/gsmu/src/Gsmuelem.cpp	Mon May 03 13:37:20 2010 +0300
+++ b/smsprotocols/smsstack/gsmu/src/Gsmuelem.cpp	Thu May 06 15:10:38 2010 +0100
@@ -1,6436 +1,6436 @@
-// Copyright (c) 1999-2009 Nokia Corporation and/or its subsidiary(-ies).
-// All rights reserved.
-// This component and the accompanying materials are made available
-// under the terms of "Eclipse Public License v1.0"
-// which accompanies this distribution, and is available
-// at the URL "http://www.eclipse.org/legal/epl-v10.html".
-//
-// Initial Contributors:
-// Nokia Corporation - initial contribution.
-//
-// Contributors:
-//
-// Description:
-// This file implements the different PDU elements
-// 
-//
-
-/**
- @file
-*/
-
-#include <gsmuelem.h>
-#include <gsmumsg.h>
-#include "Gsmumain.h"
-#include <gsmusar.h>
-#include "gsmupriv.h"
-#include <s32strm.h>
-#include <etelmm.h>
-#include <gsmuetel.h>
-#include <exterror.h>
-#include <emsinformationelement.h>
-#include <emsformatie.h>
-#include <charconv.h>
-
-/**
- *  Question Mark character.
- */
-const TInt  KReplacementCharacter = 0x003f;
-
-
-/**
- *  Constructs the object with a descriptor. The extraction mark and next character members are initialised to point to the start of the string.
- *  
- *  @param aSource Descriptor to be assigned by reference
- */
-TGsmuLex8::TGsmuLex8(const TDesC8& aSource): TLex8(aSource)
-	{
-	//NOP
-	} // TGsmuLex8::TGsmuLex8
-
-
-/**
- *  Gets the next character in the string and increments the next character position.
- *  
- *  @return The next character in the string
- *  @leave Leaves with KErrGsmuDecoding if at end of string
- */
-TUint8 TGsmuLex8::GetL()
-	{
-	if (Eos())
-		LeaveL();
-
-	return static_cast<TUint8>(Get());
-	} // TGsmuLex8::GetL
-
-
-/**
- *  Increments the next character position by aNumber
- *  
- *  @param aNumber The number of characters to increment the next character position by.
- *  @leave If the increment puts the next character position before the start or beyond the end of the string, the function leaves with KErrGsmuDecoding.
- */
-void TGsmuLex8::IncL(TInt aNumber)
-	{
-	if (aNumber != 0)
-		{
-		if (aNumber < 0 || Eos() || Remainder().Length() < aNumber)
-			LeaveL();
-		else
-			Inc(aNumber);
-		}
-	} // TGsmuLex8::IncL
-
-
-/**
- *  Checks there are enough remaining characters, then returns a TPtrC containing the next aLength characters. Does not increment the current position.
- *  
- *  @param aLength Number of characters to return
- *  @return Remainder().Left(aLength)
- *  @leave Leaves with KErrGsmuDecoding if there are insufficient characters remaining
- */
-TPtrC8 TGsmuLex8::NextWithNoIncL(TInt aLength) const
-	{
-	return NextWithNoIncL(aLength, EFalse);
-	}
-
-/**
- * Checks there are enough remaining characters, then returns a TPtrC containing the next aLength characters. Does not increment the current position.
- *
- * @param aLength Number of characters to return
- * @param aAcceptTruncation ETrue if a mismatch between length indicator and actual length is acceptable. EFalse otherwise.
- * @return Remainder().Left(aLength) if aAcceptTruncation is EFalse. Remainder() otherwise.
- * @leave Leaves with KErrGsmuDecoding if there are insufficient characters remaining, unless aAcceptTruncation is ETrue.
- */
-TPtrC8 TGsmuLex8::NextWithNoIncL(TInt aLength, TBool aAcceptTruncation) const
-	{
-	const TPtrC8 remainder(Remainder());
-
-	if ( (aLength < 0) || (remainder.Length()< aLength && !aAcceptTruncation) )
-		{
-		LeaveL();
-		}
-	
-  if (!aAcceptTruncation)
-		{
-		return Remainder().Left(aLength);
-		}
-	// aAcceptTruncation is ETrue
-	else if (remainder.Length() < aLength)
-		{
-		return Remainder();
-		}
-	// otherwise, no need for truncation:
-  
-	return Remainder().Left(aLength);
-	}
-
-
-/**
- *  Calls TGsmuLeax8::NextWithNoIncL then increments the next character position by aLength
- *  
- *  @param aLength Number of characters to return and increment the next character position
- *  @return Remainder().Left(aLength)
- *  @leave If the increment puts the next character position before the start or beyond the end of the string, the function leaves with KErrGsmuDecoding.
- */
-TPtrC8 TGsmuLex8::NextAndIncL(TInt aLength)
-	{
-	const TPtrC8 next(NextWithNoIncL(aLength));
-	IncL(aLength);
-	return next;
-	} // TGsmuLeax8::NextWithNoIncL
-
-
-const TSmsOctet& TSmsOctet::operator = (TInt aValue)
-	{
-	iValue = static_cast<TUint8>(aValue);
-	return *this;
-	} // TSmsOctet::operator
-
-
-TUint8* TSmsOctet::EncodeL(TUint8* aPtr) const
-	{
-	*aPtr=iValue;
-	return aPtr+1;
-	} // TSmsOctet::EncodeL
-
-
-TSmsFirstOctet::TSmsFirstOctet(TInt aValue):
-	TSmsOctet(aValue)
-	{
-	} // TSmsFirstOctet::TSmsFirstOctet
-
-
-const TSmsFirstOctet& TSmsFirstOctet::operator = (TInt aValue)
-	{
-	TSmsOctet::operator = (aValue);
-	return *this;
-	} // TSmsFirstOctet::operator
-
-
-TSmsFailureCause::TSmsFailureCause():
-	TSmsOctet(ESmsErrorUnspecified)
-	{
-	} // TSmsFailureCause::TSmsFailureCause
-
-
-TSmsStatus::TSmsStatus():
-	TSmsOctet(ESmsShortMessageReceivedBySME)
-	{
-	} // TSmsStatus::TSmsStatus
-
-
-CSmsCommandData* CSmsCommandData::NewL(TSmsFirstOctet& aFirstOctet)
-	{
-	LOGGSMU1("CSmsCommandData::NewL()");
-
-	CSmsCommandData* commanddata=new(ELeave) CSmsCommandData(aFirstOctet);
-	CleanupStack::PushL(commanddata);
-	TPtrC8 ptr;
-	commanddata->SetDataL(ptr);
-	CleanupStack::Pop();
-	return commanddata;
-	} // CSmsCommandData::NewL
-
-
-CSmsCommandData::~CSmsCommandData()
-	{
-	iInformationElementArray.ResetAndDestroy();
-	delete iBuffer;
-	} // CSmsCommandData::NewL
-
-
-/**
- *  Duplicates this CSmsCommandData object.
- * 
- *  @return  Pointer to the newly created CSmsCommandData object.
- */
-CSmsCommandData* CSmsCommandData::DuplicateL() const
-	{
-	LOGGSMU1("CSmsCommandData::DuplicateL()");
-
-	CSmsCommandData*  smsCommandData = CSmsCommandData::NewL(iFirstOctet);
-	CleanupStack::PushL(smsCommandData);
-
-	smsCommandData->SetDataL(Data());
-
-	for (TInt ie = 0;  ie < iInformationElementArray.Count();  ie++)
-		{
-		smsCommandData->AddInformationElementL(iInformationElementArray[ie]->Identifier(),
-											   iInformationElementArray[ie]->Data());
-		}
-
-	CleanupStack::Pop(smsCommandData);
-
-	return smsCommandData;
-	} // CSmsCommandData::DuplicateL
-
-
-CSmsInformationElement& CSmsCommandData::InformationElement(TInt aIndex) const
-	{
-	LOGGSMU1("CSmsCommandData::InformationElement()");
-
-	CSmsInformationElement* ie=iInformationElementArray[aIndex];
-	return *ie;
-	} // CSmsCommandData::InformationElement
-
-
-CSmsInformationElement*& CSmsCommandData::InformationElementPtr(TInt aIndex)
-    {
-    // Ignore in code coverage - not used in SMS stack and not exported
-    // but cannot be removed as impacts public header.
-    BULLSEYE_OFF    
-    LOGGSMU1("CSmsCommandData::InformationElementPtr()");
-    return iInformationElementArray[aIndex];
-    BULLSEYE_RESTORE
-    }
-
-TBool CSmsCommandData::InformationElementIndex(CSmsInformationElement::TSmsInformationElementIdentifier aIdentifier,
-		TInt& aIndex) const
-	{
-	LOGGSMU1("CSmsCommandData::InformationElementIndex()");
-
-	TBool found=EFalse;
-	TInt count=NumInformationElements();
-	for (TInt i=0; (!found) && (i<count); i++)
-		if (InformationElement(i).Identifier()==aIdentifier)
-			{
-			found=ETrue;
-			aIndex=i;
-			}
-	return found;
-	} // CSmsCommandData::InformationElementIndex
-
-
-void CSmsCommandData::AddInformationElementL(const TSmsId aIdentifier,const TDesC8& aData)
-	{
-	LOGGSMU1("CSmsCommandData::AddInformationElementL()");
-
-	//
-	// Currently there is no restriction on how many instances of an information element can be
-	// placed in the collection.
-	// No restriction will be placed on the number of Special SMS Message Indications that can be
-	// added in order to maintain FC.
-	// (cf CSmsUserData::AddInformationElementL(const TSmsId aIdentifier,const TDesC8& aData);
-	//
-	CSmsInformationElement* informationelement=CSmsInformationElement::NewL(aIdentifier,aData);
-	CleanupStack::PushL(informationelement);
-	iInformationElementArray.AppendL(informationelement);
-	CleanupStack::Pop();
-	if (NumInformationElements()>=1)
-		SetHeaderPresent(ETrue);
-	} // CSmsCommandData::AddInformationElementL
-
-
-void CSmsCommandData::RemoveInformationElement(TInt aIndex)
-	{
-	LOGGSMU1("CSmsCommandData::RemoveInformationElement()");
-	// Since iInformationElementArray[aIndex] is removed from iInformationElementArray, no double free issue.
-	// coverity[double_free]
-	delete iInformationElementArray[aIndex];
-	iInformationElementArray[aIndex] = NULL;
-	iInformationElementArray.Delete(aIndex);
-
-	if (NumInformationElements()==0)
-		{
-		SetHeaderPresent(EFalse);
-		}
-	} // CSmsCommandData::RemoveInformationElement
-
-
-TPtrC8 CSmsCommandData::Data() const
-	{
-	LOGGSMU1("CSmsCommandData::Data()");
-
-	TPtrC8 ptr;
-	ptr.Set(iBuffer->Des());
-	return ptr;
-	} // CSmsCommandData::Data
-
-
-void CSmsCommandData::SetDataL(const TDesC8& aData)
-	{
-	LOGGSMU1("CSmsCommandData::SetDataL()");
-
-	TInt length=aData.Length();
-	__ASSERT_DEBUG(length<=KSmsMaxDataSize,Panic(KGsmuPanicCommandDataLengthTooLong));
-	HBufC8* buffer=HBufC8::NewL(length);
-	delete iBuffer;
-	iBuffer=buffer;
-	iBuffer->Des().SetLength(length);
-	iBuffer->Des().Copy(aData);
-	} // CSmsCommandData::SetDataL
-
-
-TUint8* CSmsCommandData::EncodeL(TUint8* aPtr) const
-	{
-	LOGGSMU1("CSmsCommandData::EncodeL()");
-
-	__ASSERT_DEBUG(iBuffer->Length()<=MaxDataLength(),Panic(KGsmuPanicCommandDataBufferTooLong));
-	TSmsOctet datalength=iBuffer->Length()+TSmsOctet(TotalHeaderLengthInUDLUnits());
-	aPtr=datalength.EncodeL(aPtr);
-	TPtr8 ptr((TUint8*) aPtr,datalength);
-
-    if (HeaderPresent())
-        {
-		TSmsOctet headerLength(HeaderLength());
-		aPtr=headerLength.EncodeL(aPtr);
-		for (TInt i=0; i<NumInformationElements(); i++)
-		    {
-			aPtr=iInformationElementArray[i]->EncodeL(aPtr);
-		    }
-        }
-
-	ptr.Copy(iBuffer->Des());
-	aPtr+=TInt(iBuffer->Length());
-	return aPtr;
-	} // CSmsCommandData::EncodeL
-
-
-void CSmsCommandData::DecodeL(TGsmuLex8& aPdu)
-	{
-	LOGGSMU1("CSmsCommandData::DecodeL()");
-
-	iInformationElementArray.ResetAndDestroy();
-	const TBool headerPresent=HeaderPresent();
-	TSmsOctet dataLength;
-	dataLength.DecodeL(aPdu);
-
-	if (headerPresent)
-		{
-		TSmsOctet headerLength;
-		headerLength.DecodeL(aPdu);
-		if ((1+headerLength)>KSmsMaxDataSize)
-			User::Leave(KErrGsmSMSTpduNotSupported);
-		while (HeaderLength()<headerLength)
-			{
-			CSmsInformationElement* informationElement=CSmsInformationElement::NewL();
-			CleanupStack::PushL(informationElement);
-			informationElement->DecodeL(aPdu);
-			iInformationElementArray.AppendL(informationElement);
-			CleanupStack::Pop(informationElement);
-			}
-		if (HeaderLength()!=headerLength)
-			User::Leave(KErrGsmSMSTpduNotSupported);
-		}
-	const TInt totalHeaderLength=TotalHeaderLengthInUDLUnits();
-	const TInt totalDataLength=dataLength-totalHeaderLength;
-	const TPtrC8 next(aPdu.NextAndIncL(totalDataLength));
-	SetDataL(next);
-	} // CSmsCommandData::DecodeL
-
-
-void CSmsCommandData::InternalizeL(RReadStream& aStream)
-	{
-	iInformationElementArray.ResetAndDestroy();
-	TInt numInformationElements=aStream.ReadInt32L();
-	for (TInt i=0; i<numInformationElements; i++)
-		{
-		CSmsInformationElement* informationElement=CSmsInformationElement::NewL();
-		CleanupStack::PushL(informationElement);
-		aStream >> *informationElement;
-		iInformationElementArray.AppendL(informationElement);
-		CleanupStack::Pop();
-		}
-	HBufC8* buffer=HBufC8::NewL(aStream,KSmsMaxDataSize);
-	delete iBuffer;
-	iBuffer=buffer;
-	} // CSmsCommandData::InternalizeL
-
-
-void CSmsCommandData::ExternalizeL(RWriteStream& aStream) const
-	{
-	TInt numInformationElements=iInformationElementArray.Count();
-	aStream.WriteInt32L(numInformationElements);
-	for (TInt i=0; i<numInformationElements; i++)
-		aStream << *iInformationElementArray[i];
-	aStream << *iBuffer;
-	} // CSmsCommandData::ExternalizeL
-
-
-CSmsCommandData::CSmsCommandData(TSmsFirstOctet& aFirstOctet):
-	iFirstOctet(aFirstOctet),
-	iInformationElementArray(8)
-	{
-	} // CSmsCommandData::CSmsCommandData
-
-
-TInt CSmsCommandData::HeaderLength() const
-	{
-	LOGGSMU1("CSmsCommandData::HeaderLength()");
-
-	TInt headerLength=0;
-	for (TInt i=0; i<NumInformationElements(); i++)
-		headerLength+=iInformationElementArray[i]->Length();
-	return headerLength;
-	} // CSmsCommandData::HeaderLength
-
-
-TInt CSmsCommandData::TotalHeaderLengthInUDLUnits() const
-	{
-	LOGGSMU1("CSmsCommandData::TotalHeaderLengthInUDLUnits()");
-
-	if (iInformationElementArray.Count()==0)
-		return 0;
-	else
-		return (HeaderLength()+1);   // +1 stands for  UDHL
-	} // CSmsCommandData::TotalHeaderLengthInUDLUnits
-
-
-TBool CSmsCommandData::HeaderPresent() const
-	{
-	LOGGSMU1("CSmsCommandData::HeaderPresent()");
-
-	return (iFirstOctet&TSmsFirstOctet::ESmsUDHIMask)==TSmsFirstOctet::ESmsUDHIHeaderPresent;
-	} // CSmsCommandData::HeaderPresent
-
-
-void CSmsCommandData::SetHeaderPresent(TBool aHeaderPresent)
-	{
-	LOGGSMU1("CSmsCommandData::SetHeaderPresent()");
-
-	iFirstOctet=aHeaderPresent? (iFirstOctet&(~TSmsFirstOctet::ESmsUDHIMask))|TSmsFirstOctet::ESmsUDHIHeaderPresent: (iFirstOctet&(~TSmsFirstOctet::ESmsUDHIMask))|TSmsFirstOctet::ESmsUDHIHeaderNotPresent;
-	} // CSmsCommandData::SetHeaderPresent
-
-
-TSmsParameterIndicator::TSmsParameterIndicator():
-	TSmsOctet(ESmsPIDProtocolIdentifierPresent|ESmsPIDUserDataPresent|ESmsPIDDataCodingSchemePresent)
-	{
-	} // TSmsParameterIndicator::TSmsParameterIndicator
-
-
-TSmsCommandType::TSmsCommandType():
-	TSmsOctet(ESmsCommandTypeEnquiry)
-	{
-	} // TSmsCommandType::TSmsCommandType
-
-
-TSmsProtocolIdentifier::TSmsProtocolIdentifier():
-	TSmsOctet((TInt)ESmsPIDTelematicInterworking|(TInt)ESmsNoTelematicDevice)
-	{
-	} // TSmsProtocolIdentifier::TSmsProtocolIdentifier
-
-
-TSmsProtocolIdentifier::TSmsTelematicDeviceIndicator TSmsProtocolIdentifier::TelematicDeviceIndicator() const
-	{
-	__ASSERT_DEBUG(PIDType()==ESmsPIDTelematicInterworking,Panic(KGsmuPanicNoTelematicInterworking));
-	return (TSmsTelematicDeviceIndicator) (iValue&EPIDTelematicDeviceIndicatorMask);
-	} // TSmsProtocolIdentifier::TSmsTelematicDeviceIndicator
-
-
-void TSmsProtocolIdentifier::SetTelematicDeviceIndicator(TSmsTelematicDeviceIndicator aIndicator)
-	{
-	LOGGSMU1("TSmsProtocolIdentifier::SetTelematicDeviceIndicator()");
-
-	__ASSERT_DEBUG(PIDType()==ESmsPIDTelematicInterworking,Panic(KGsmuPanicNoTelematicInterworking));
-
-	//iValue=(TUint8) ((iValue&ESmsPIDTypeMask)|aIndicator);
-	iValue=(TUint8) ((iValue&(~EPIDTelematicDeviceIndicatorMask))|aIndicator);
-	} // TSmsProtocolIdentifier::SetTelematicDeviceIndicator
-
-
-TSmsProtocolIdentifier::TSmsTelematicDeviceType TSmsProtocolIdentifier::TelematicDeviceType() const
-	{
-	__ASSERT_DEBUG(TelematicDeviceIndicator()==ESmsTelematicDevice,Panic(KGsmuPanicNoTelematicDevice));
-	return (TSmsTelematicDeviceType) (iValue&ESmsTelematicDeviceTypeMask);
-	} // TSmsProtocolIdentifier::TSmsTelematicDeviceType
-
-
-void TSmsProtocolIdentifier::SetTelematicDeviceType(TSmsTelematicDeviceType aDeviceType)
-	{
-	LOGGSMU1("TSmsProtocolIdentifier::SetTelematicDeviceType()");
-
-	__ASSERT_DEBUG(TelematicDeviceIndicator()==ESmsTelematicDevice,Panic(KGsmuPanicNoTelematicDevice));
-	iValue=(TUint8) ((iValue&(~ESmsTelematicDeviceTypeMask))|aDeviceType);
-	} // TSmsProtocolIdentifier::SetTelematicDeviceType
-
-
-TInt TSmsProtocolIdentifier::ShortMessageALProtocol() const
-    {
-    // Ignore in code coverage - not used in SMS stack and not exported
-    // but cannot be removed as impacts public header.
-    BULLSEYE_OFF    
-    LOGGSMU1("TSmsProtocolIdentifier::ShortMessageALProtocol()");
-    
-    __ASSERT_DEBUG(TelematicDeviceIndicator()==ESmsNoTelematicDevice,Panic(KGsmuPanicNoTelematicDevice));
-    return (TSmsShortMessageALProtocol) (iValue&ESmsShortMessageALProtocolMask);
-    BULLSEYE_RESTORE
-    }
-
-void TSmsProtocolIdentifier::SetShortMessageALProtocol(TSmsShortMessageALProtocol aProtocol)
-    {
-    // Ignore in code coverage - not used in SMS stack and not exported
-    // but cannot be removed as impacts public header.
-    BULLSEYE_OFF    
-    LOGGSMU1("TSmsProtocolIdentifier::SetShortMessageALProtocol()");
-    
-    __ASSERT_DEBUG(TelematicDeviceIndicator()==ESmsNoTelematicDevice,Panic(KGsmuPanicNoTelematicDevice));
-    iValue=(TUint8) ((iValue&(~ESmsShortMessageALProtocolMask))|aProtocol);
-    BULLSEYE_RESTORE
-    }
-
-TInt TSmsProtocolIdentifier::ShortMessageType() const
-	{
-	LOGGSMU1("TSmsProtocolIdentifier::ShortMessageType()");
-
-	__ASSERT_DEBUG(PIDType()==ESmsPIDShortMessageType,Panic(KGsmuPanicNoShortMessageType));
-	return (TSmsShortMessageType) (iValue&ESmsShortMessageTypeMask);
-	} // TSmsProtocolIdentifier::ShortMessageType
-
-
-void TSmsProtocolIdentifier::SetShortMessageType(TSmsShortMessageType aShortMessageType)
-	{
-	LOGGSMU1("TSmsProtocolIdentifier::SetShortMessageType()");
-
-	__ASSERT_DEBUG(PIDType()==ESmsPIDShortMessageType,Panic(KGsmuPanicNoShortMessageType));
-	//iValue=(TUint8) ((iValue&(~ESmsPIDTypeMask))|aShortMessageType);
-	iValue=(TUint8) ((iValue&(~ESmsShortMessageTypeMask))|aShortMessageType);
-	} // TSmsProtocolIdentifier::SetShortMessageType
-
-
-TSmsDataCodingScheme::TSmsDataCodingScheme():
-	TSmsOctet((TInt)ESmsDCSTextUncompressedWithNoClassInfo|(TInt)ESmsAlphabet7Bit|(TInt)ESmsClass0)
-	// Constructor is expected to set the octet = 0, This is needed by
-	// CSmsDeliverReport::DecodeL, CSmsSubmitReport::DecodeL and CSmsStatusReport::DecodeL, per
-	// 23.040 v6.5.0 section 9.2.3.27.
-	{
-	} // CSmsDeliverReport::DecodeL
-
-
-TBool TSmsDataCodingScheme::TextCompressed() const
-	{
-	LOGGSMU1("TSmsDataCodingScheme::TextCompressed()");
-
-	TInt bits7to4=Bits7To4();
-	return (bits7to4==ESmsDCSTextCompressedWithNoClassInfo)    || (bits7to4==ESmsDCSTextCompressedWithClassInfo)      ||
-           (bits7to4==ESmsDCSAutoDelNoClassInfoCompressedText) || (bits7to4==ESmsDCSAutoDelClassInfoTextCompressedText);
-	} // TSmsDataCodingScheme::TextCompressed
-
-
-void TSmsDataCodingScheme::SetTextCompressed(TBool aCompressed)
-	{
-	LOGGSMU1("TSmsDataCodingScheme::SetTextCompressed()");
-
-	TInt bits7to4=Bits7To4();
-	if (aCompressed)
-		{
-		switch (bits7to4)
-			{
-			case (ESmsDCSTextUncompressedWithNoClassInfo):
-				{
-				iValue=(TUint8) (ESmsDCSTextCompressedWithNoClassInfo|(iValue&(~ESmsDCSBits7To4Mask)));
-				break;
-				}
-			case (ESmsDCSAutoDelNoClassInfoUncompressedText):
-				{
-				iValue=(TUint8) (ESmsDCSAutoDelNoClassInfoCompressedText|(iValue&(~ESmsDCSBits7To4Mask)));
-				break;
-				}
-			case (ESmsDCSAutoDelClassInfoUncompressedText):
-				{
-				iValue=(TUint8) (ESmsDCSAutoDelClassInfoTextCompressedText|(iValue&(~ESmsDCSBits7To4Mask)));
-				break;
-				}
-			case (ESmsDCSTextUncompressedWithClassInfo):
-			case (ESmsDCSTextUncompressed7BitOr8Bit):
-				{
-				iValue=(TUint8) (ESmsDCSTextCompressedWithClassInfo|(iValue&(~ESmsDCSBits7To4Mask)));
-				break;
-				}
-			case (ESmsDCSTextCompressedWithNoClassInfo):
-			case (ESmsDCSTextCompressedWithClassInfo):
-			case (ESmsDCSAutoDelNoClassInfoCompressedText):
-			case (ESmsDCSAutoDelClassInfoTextCompressedText):
-				break;
-			default:
-                break;
-                // has to be tested, what happens in this default case
-				//Panic(KGsmuPanicNotSupportedWithDCSBits7To4);
-			}
-		}
-	else
-		{
-		switch (bits7to4)
-			{
-			case (ESmsDCSTextCompressedWithNoClassInfo):
-				{
-				iValue=(TUint8) (ESmsDCSTextUncompressedWithNoClassInfo|(iValue&(~ESmsDCSBits7To4Mask)));
-				break;
-				}
-			case (ESmsDCSTextCompressedWithClassInfo):
-				{
-				iValue=(TUint8) (ESmsDCSTextUncompressedWithClassInfo|(iValue&(~ESmsDCSBits7To4Mask)));
-				break;
-				}
-			case (ESmsDCSAutoDelNoClassInfoCompressedText):
-				{
-				iValue=(TUint8) (ESmsDCSAutoDelNoClassInfoUncompressedText|(iValue&(~ESmsDCSBits7To4Mask)));
-				break;
-				}
-			case (ESmsDCSAutoDelClassInfoTextCompressedText):
-				{
-				iValue=(TUint8) ( ESmsDCSAutoDelClassInfoUncompressedText|(iValue&(~ESmsDCSBits7To4Mask)));
-				break;
-				}
-			case (ESmsDCSTextUncompressedWithNoClassInfo):
-			case (ESmsDCSTextUncompressedWithClassInfo):
-            case (ESmsDCSAutoDelClassInfoUncompressedText):
-            case (ESmsDCSAutoDelNoClassInfoUncompressedText):
-			case (ESmsDCSTextUncompressed7BitOr8Bit):
-			default:
-				{
-				}
-			}
-		}
-	} // TSmsDataCodingScheme::SetTextCompressed
-
-
-TSmsDataCodingScheme::TSmsAlphabet TSmsDataCodingScheme::Alphabet() const
-	{
-	LOGGSMU1("TSmsDataCodingScheme::TSmsAlphabet()");
-
-	TInt bits7to4=Bits7To4();
-	TInt alphabet=ESmsAlphabet7Bit;
-	switch (bits7to4)
-		{
-		case (ESmsDCSTextUncompressedWithNoClassInfo):
-		case (ESmsDCSTextUncompressedWithClassInfo):
-		case (ESmsDCSTextCompressedWithNoClassInfo):  //  Alphabet not used in these cases
-		case (ESmsDCSTextCompressedWithClassInfo):
-		case (ESmsDCSAutoDelNoClassInfoUncompressedText):
-		case (ESmsDCSAutoDelClassInfoUncompressedText):
-		case (ESmsDCSAutoDelNoClassInfoCompressedText):
-		case (ESmsDCSAutoDelClassInfoTextCompressedText):
-			{
-			alphabet=iValue&ESmsAlphabetMask;
-			break;
-			}
-		case (ESmsDCSTextUncompressed7BitOr8Bit):
-			{
-			alphabet=iValue&ESmsAlphabet8Bit;  //  N.B. only one bit used to code alphabet
-			break;
-			}
-		case (ESmsDCSMessageWaitingIndicationDiscardMessage):
-		case (ESmsDCSMessageWaitingIndication7Bit):
-			{
-			alphabet=ESmsAlphabet7Bit;
-			break;
-			}
-		case (ESmsDCSMessageWaitingIndicationUCS2):
-			{
-			alphabet=ESmsAlphabetUCS2;
-			break;
-			}
-		default:
-		    LOGGSMU1("TSmsDataCodingScheme::Alphabet() WARNING! default case has been reached");
-            break;
- 		}
-	return (TSmsAlphabet) alphabet;
-	} // TSmsDataCodingScheme::TSmsAlphabet
-
-void TSmsDataCodingScheme::SetAlphabet(TSmsAlphabet aAlphabet)
-	{
-	LOGGSMU1("TSmsDataCodingScheme::SetAlphabet()");
-
-	TInt bits7to4=Bits7To4();
-	switch (bits7to4)
-		{
-		case (ESmsDCSTextUncompressedWithNoClassInfo):
-		case (ESmsDCSTextUncompressedWithClassInfo):
-		case (ESmsDCSTextCompressedWithNoClassInfo):  //  Alphabet not used in these cases
-		case (ESmsDCSTextCompressedWithClassInfo):
-		case (ESmsDCSAutoDelNoClassInfoUncompressedText):
-		case (ESmsDCSAutoDelClassInfoUncompressedText):
-		case (ESmsDCSAutoDelNoClassInfoCompressedText):
-		case (ESmsDCSAutoDelClassInfoTextCompressedText):
-			{
-			iValue=(TUint8) ((iValue&(~ESmsAlphabetMask))|aAlphabet);
-			break;
-			}
-		case (ESmsDCSTextUncompressed7BitOr8Bit):
-			{
-			if ((aAlphabet==ESmsAlphabet7Bit) || (aAlphabet==ESmsAlphabet8Bit))
-				{
-				iValue=(TUint8) ((iValue&(~ESmsAlphabet8Bit))|aAlphabet);  //  N.B. only one bit used to code alphabet
-				}
-			break;
-			}
-		case (ESmsDCSMessageWaitingIndicationDiscardMessage):
-			{
-            if (aAlphabet!=ESmsAlphabet7Bit)
-                {
-                LOGGSMU3("TSmsDataCodingScheme::SetAlphabet() WARNING! Not Supported With Discard Message  [Bits7To4=%d], [aAlphabet=%d]", bits7to4, aAlphabet);
-                }
-			break;
-			}
-		case (ESmsDCSMessageWaitingIndication7Bit):
-			{
- 			if (aAlphabet==ESmsAlphabetUCS2)
- 			    {
-				iValue=(TUint8) (ESmsDCSMessageWaitingIndicationUCS2|(iValue&(~ESmsDCSBits7To4Mask)));
- 			    }
- 			else 
-                {
-        		LOGGSMU3("TSmsDataCodingScheme::SetAlphabet() WARNING! Not Supported With Discard Message  [Bits7To4=%d], [aAlphabet=%d]", bits7to4, aAlphabet);
-			    }	     
-			break;
-			}
-		case (ESmsDCSMessageWaitingIndicationUCS2):
-			{
-  			if (aAlphabet==ESmsAlphabet7Bit)
-			    {
-				iValue=(TUint8) (ESmsDCSMessageWaitingIndication7Bit|(iValue&(~ESmsDCSBits7To4Mask)));
-			    }
-			else 
-			    {
-				LOGGSMU3("TSmsDataCodingScheme::SetAlphabet() WARNING! Not Supported With Discard Message  [Bits7To4=%d], [aAlphabet=%d]", bits7to4, aAlphabet);
-			    }
-			break;
-			}
-		default:
-		    LOGGSMU1("TSmsDataCodingScheme::SetAlphabet() WARNING! default case has been reached");
-            break;
-      		}
-	} // TSmsDataCodingScheme::SetAlphabet
-
-
-TBool TSmsDataCodingScheme::Class(TSmsClass& aClass) const
-	{
-	LOGGSMU1("TSmsDataCodingScheme::Class()");
-
-	switch (Bits7To4())
-		{
-		case (ESmsDCSTextUncompressedWithClassInfo):
-		case (ESmsDCSTextCompressedWithClassInfo):
-		case (ESmsDCSAutoDelClassInfoUncompressedText):
-		case (ESmsDCSAutoDelClassInfoTextCompressedText):
-		case (ESmsDCSTextUncompressed7BitOr8Bit):
-			aClass=(TSmsClass) (iValue&ESmsClassMask);
-			return ETrue;
-		default:
-			return EFalse;
-		}
-	} // TSmsDataCodingScheme::Class
-
-
-void TSmsDataCodingScheme::SetClass(TBool aClassDefined,TSmsDataCodingScheme::TSmsClass aClass)
-	{
-	LOGGSMU1("TSmsDataCodingScheme::SetClass()");
-
-	TInt bits7to4=Bits7To4();
-	if (aClassDefined)
-		{
-		switch (bits7to4)
-			{
-			case (ESmsDCSTextUncompressedWithNoClassInfo):
-				{
-				iValue=(TUint8) (ESmsDCSTextUncompressedWithClassInfo|(iValue&ESmsAlphabetMask|aClass));
-				break;
-				}
-			case (ESmsDCSTextCompressedWithNoClassInfo):
-				{
-				iValue=(TUint8) (ESmsDCSTextCompressedWithClassInfo|(iValue&ESmsAlphabetMask|aClass));
-				break;
-				}
-			case (ESmsDCSAutoDelNoClassInfoUncompressedText):
-				{
-				iValue=(TUint8) (ESmsDCSAutoDelClassInfoUncompressedText|(iValue&ESmsAlphabetMask|aClass));
-				break;
-				}
-			case (ESmsDCSAutoDelNoClassInfoCompressedText):
-				{
-				iValue=(TUint8) (ESmsDCSAutoDelClassInfoTextCompressedText|(iValue&ESmsAlphabetMask|aClass));
-				break;
-				}
-			case (ESmsDCSTextUncompressedWithClassInfo):
-			case (ESmsDCSTextCompressedWithClassInfo):
-			case (ESmsDCSAutoDelClassInfoUncompressedText):
-			case (ESmsDCSAutoDelClassInfoTextCompressedText):
-			case (ESmsDCSTextUncompressed7BitOr8Bit):
-
-				{
-				iValue=(TUint8) (iValue&(~ESmsClassMask)|aClass);
-				break;
-				}
-			default:
-		        LOGGSMU1("WARNING! default case has been reached");
-                break;
-			}
-		}
-	else
-		{
-		switch (bits7to4)
-			{
-			case (ESmsDCSTextUncompressedWithClassInfo):
-				{
-				iValue=(TUint8) (ESmsDCSTextUncompressedWithNoClassInfo|(iValue&ESmsAlphabetMask)|aClass);
-				break;
-				}
-			case (ESmsDCSTextCompressedWithClassInfo):
-				{
-				iValue=(TUint8) (ESmsDCSTextCompressedWithNoClassInfo|(iValue&ESmsAlphabetMask)|aClass);
-				break;
-				}
-			case (ESmsDCSAutoDelClassInfoUncompressedText):
-				{
-				iValue=(TUint8) (ESmsDCSAutoDelNoClassInfoUncompressedText|(iValue&ESmsAlphabetMask)|aClass);
-				break;
-				}
-			case (ESmsDCSAutoDelClassInfoTextCompressedText):
-				{
-				iValue=(TUint8) (ESmsDCSAutoDelNoClassInfoCompressedText|(iValue&ESmsAlphabetMask)|aClass);
-				break;
-				}
-			case (ESmsDCSTextUncompressed7BitOr8Bit):
-				{
-				iValue=(TUint8) (ESmsDCSTextUncompressedWithNoClassInfo|(iValue&ESmsAlphabetMask)|aClass);
-				break;
-				}
-			case (ESmsDCSTextUncompressedWithNoClassInfo):
-			case (ESmsDCSTextCompressedWithNoClassInfo):
-			case (ESmsDCSAutoDelNoClassInfoUncompressedText):
-			case (ESmsDCSAutoDelNoClassInfoCompressedText):
-			case (ESmsDCSMessageWaitingIndicationDiscardMessage):
-			case (ESmsDCSMessageWaitingIndication7Bit):
-			case (ESmsDCSMessageWaitingIndicationUCS2):
-			default:
-				{
-				}
-			}
-		}
-	} // TSmsDataCodingScheme::SetClass
-
-
-TSmsDataCodingScheme::TSmsIndicationState TSmsDataCodingScheme::IndicationState() const
-	{
-	LOGGSMU1("TSmsDataCodingScheme::IndicationState()");
-
-	TInt bits7to4=Bits7To4();
-	TSmsIndicationState state=ESmsIndicationInactive;
-	switch (bits7to4)
-		{
-		case (ESmsDCSMessageWaitingIndicationDiscardMessage):
-		case (ESmsDCSMessageWaitingIndication7Bit):
-		case (ESmsDCSMessageWaitingIndicationUCS2):
-			{
-			state=(TSmsIndicationState) (iValue&ESmsIndicationStateMask);
-			break;
-			}
-		default:
-		    LOGGSMU1("WARNING! default case has been reached");
-            break;
-  		}
-	return state;
-	} // TSmsDataCodingScheme::TSmsIndicationState
-
-
-void TSmsDataCodingScheme::SetIndicationState(TSmsIndicationState aState)
-	{
-	LOGGSMU1("TSmsDataCodingScheme::SetIndicationState()");
-
-	TInt bits7to4=Bits7To4();
-	switch (bits7to4)
-		{
-		case (ESmsDCSMessageWaitingIndicationDiscardMessage):
-		case (ESmsDCSMessageWaitingIndication7Bit):
-		case (ESmsDCSMessageWaitingIndicationUCS2):
-			{
-			iValue=(TUint8) (aState | (iValue&(~ESmsIndicationStateMask)));
-			break;
-			}
-		default:
-		    LOGGSMU1("TSmsDataCodingScheme::SetIndicationState() WARNING! default case has been reached");
-            break;
-  		}
-	} // TSmsDataCodingScheme::SetIndicationState
-
-
-TSmsDataCodingScheme::TSmsIndicationType TSmsDataCodingScheme::IndicationType() const
-	{
-	LOGGSMU1("TSmsDataCodingScheme::IndicationType()");
-
-	TInt bits7to4=Bits7To4();
-	TSmsIndicationType type=ESmsVoicemailMessageWaiting;
-	switch (bits7to4)
-		{
-		case (ESmsDCSMessageWaitingIndicationDiscardMessage):
-		case (ESmsDCSMessageWaitingIndication7Bit):
-		case (ESmsDCSMessageWaitingIndicationUCS2):
-			{
-			type=(TSmsIndicationType) (iValue&ESmsIndicationTypeMask);
-			break;
-			}
-		default:
-		    LOGGSMU1("TSmsDataCodingScheme::IndicationType() WARNING default case has been reached");
-            break;
-		}
-	return type;
-	} // TSmsDataCodingScheme::TSmsIndicationType
-
-
-void TSmsDataCodingScheme::SetIndicationType(TSmsIndicationType aType)
-	{
-	LOGGSMU1("TSmsDataCodingScheme::SetIndicationType()");
-
-	TInt bits7to4=Bits7To4();
-	switch (bits7to4)
-		{
-		case (ESmsDCSMessageWaitingIndicationDiscardMessage):
-		case (ESmsDCSMessageWaitingIndication7Bit):
-		case (ESmsDCSMessageWaitingIndicationUCS2):
-			{
-			iValue=(TUint8) (aType | (iValue&(~ESmsIndicationTypeMask)));
-			break;
-			}
-		default:
-		    LOGGSMU1("TSmsDataCodingScheme::SetIndicationType() WARNING! default case has been reached");
-            break;
- 		}
-	} // TSmsDataCodingScheme::SetIndicationType
-
-
-/**
- *  Allocates and creates a CSmsAlphabetConverter object, specifying an Alphabet
- *  Coding scheme and a Binary flag.
- *  
- *  @param aCharacterSetConverter Pre-initialised character set converter
- *  @param aFs File system handle
- *  @param aSmsAlphabet Data coding scheme alphabet
- *  @param aIsBinary Set to true for WAP or compressed data
- *  @return New CSmsAlphabetConverter object
- *  @capability None
- */
-EXPORT_C CSmsAlphabetConverter* CSmsAlphabetConverter::NewLC(CCnvCharacterSetConverter& aCharacterSetConverter,RFs& aFs,TSmsDataCodingScheme::TSmsAlphabet aSmsAlphabet,TBool aIsBinary)
-	{
-	LOGGSMU1("CSmsAlphabetConverter::NewLC()");
-
-	CSmsAlphabetConverter* converter=new (ELeave)CSmsAlphabetConverter(aCharacterSetConverter,aFs,aSmsAlphabet,aIsBinary);
-	CleanupStack::PushL(converter);
-	converter->ConstructL();
-	return converter;
-	} // CSmsAlphabetConverter::NewLC
-
-
-/**
- *  Destructor.
- *  @capability None
- */
-EXPORT_C CSmsAlphabetConverter::~CSmsAlphabetConverter()
-    {
-    delete iConvertedNativeCharacters;
-    delete iConvertedUDElements;
-    delete iUnconvertedNativeCharacters;
-    delete iUnconvertedUDElements;
-    } // CSmsAlphabetConverter::NewLC
-
-
-//
-// C'tor - standard stuff
-//
-CSmsAlphabetConverter::CSmsAlphabetConverter(CCnvCharacterSetConverter& aCharacterSetConverter,RFs& aFs,TSmsDataCodingScheme::TSmsAlphabet aSmsAlphabet,TBool aIsBinary)
-    : iCharacterSetConverter(aCharacterSetConverter),
-    iFs(aFs),
-    iSmsAlphabet(aSmsAlphabet),
-    iIsBinary(aIsBinary),
-    iUnconvertedNativeCharactersPtr(NULL,0),
-    iUnconvertedUDElementsPtr(NULL,0)
-    {
-    } // CSmsAlphabetConverter::CSmsAlphabetConverter
-
-
-//
-// Ensures this is a supported character set if not binary conversion
-//
-void CSmsAlphabetConverter::ConstructL()
-	{
-	LOGGSMU1("CSmsAlphabetConverter::ConstructL()");
-
-
-	if (!iIsBinary)
-		{
-		switch (iSmsAlphabet)
-			{
-			case TSmsDataCodingScheme::ESmsAlphabet7Bit:
-			case TSmsDataCodingScheme::ESmsAlphabet8Bit:
-			case TSmsDataCodingScheme::ESmsAlphabetUCS2:
-				{
-				// Supported
-				break;
-				}
-			default:
-				{
-				// Not supported
-				User::Leave(KErrGsmSMSDataCodingSchemeNotSupported);
-				break;
-				}
-			}
-		}
-	} // CSmsAlphabetConverter::ConstructL
-
-
-//
-// Returns whether the character set converter is invoked.  Provided to allow
-// clients to provided efficient converted length calculation where no
-// conversion is required.
-//
-void CSmsAlphabetConverter::ConversionPropertiesL(TSmsAlphabetConversionProperties& aConversionProperties) const
-	{
-	LOGGSMU1("CSmsAlphabetConverter::ConversionPropertiesL()");
-
-
-	// Set defaults
-	aConversionProperties.iWidthConversion=ESmsAlphabetWidthConversionFixed;
-	aConversionProperties.iUDElementsPerNativeCharacter=1;
-	// Modify if different
-	if (iIsBinary)
-		return;
-	switch (iSmsAlphabet)
-		{
-		case TSmsDataCodingScheme::ESmsAlphabet7Bit:
-		case TSmsDataCodingScheme::ESmsAlphabet8Bit:
-			{
-			aConversionProperties.iWidthConversion=ESmsAlphabetWidthConversionVariable;
-			break;
-			}
-		case TSmsDataCodingScheme::ESmsAlphabetUCS2:
-			{
-			aConversionProperties.iUDElementsPerNativeCharacter=sizeof(TText);
-			break;
-			}
-		default:
-			{
-			User::Leave(KErrGsmSMSDataCodingSchemeNotSupported);
-			}
-		}
-	} // CSmsAlphabetConverter::ConversionPropertiesL
-
-
-/**
- *  Converts from the native character set to unpacked user data elements of the
- *  desired character set.
- *  
- *  The function stores the converted data internally.
- *  
- *  @param aNativeCharacters The native character set data (Unicode only)
- *  @return Converted characters
- *  @capability None
- */
-EXPORT_C TPtrC8 CSmsAlphabetConverter::ConvertFromNativeL(const TDesC& aNativeCharacters)
-	{
-	LOGGSMU1("CSmsAlphabetConverter::ConvertFromNativeL()");
-
-	TInt  numberOfUnconvertibleCharacters, numberOfDowngradedCharacters;
-
-	return ConvertFromNativeL(aNativeCharacters, ESmsEncodingNone,
-			                  numberOfUnconvertibleCharacters,
-			                  numberOfDowngradedCharacters);
-	} // CSmsAlphabetConverter::ConvertFromNativeL
-
-
-/**
- *  Converts from the native character set to unpacked user data elements of the
- *  desired character set.
- *  
- *  The function stores the converted data internally.
- *  
- *  @param aNativeCharacters                 The native character set data (Unicode only)
- *  @param aNumberOfUnconvertibleCharacters  Number of characters unconverted
- *  @param aNumberOfDowngradedCharacters     Number of characters downgraded
- *  @param aEncoding                         Alternative 7bit encoding to used (if needed)
- * 
- *  @return Converted characters
- * 
- *  @capability None
- */
-EXPORT_C TPtrC8 CSmsAlphabetConverter::ConvertFromNativeL(const TDesC& aNativeCharacters,
-                                                          TSmsEncoding aEncoding,
-                                                          TInt& aNumberOfUnconvertibleCharacters,
-			                                              TInt& aNumberOfDowngradedCharacters)
-	{
-	LOGGSMU2("CSmsAlphabetConverter::ConvertFromNativeL(): aEncoding=%d", aEncoding);
-	
-	aNumberOfUnconvertibleCharacters = 0;
-	aNumberOfDowngradedCharacters    = 0;
-
-	// Check for some shortcuts
-	if (iIsBinary ||  iSmsAlphabet == TSmsDataCodingScheme::ESmsAlphabet8Bit)
-		{
-		// Binary data stored as padded unicode
-		TPtr8 outputPtr=CheckAllocBufferL(&iConvertedUDElements,aNativeCharacters.Length(),0);
-		outputPtr.Copy(aNativeCharacters);
-		iUnconvertedNativeCharactersPtr.Zero();
-		return outputPtr;
-		}
-	else if (iSmsAlphabet==TSmsDataCodingScheme::ESmsAlphabetUCS2)
-		{
-		TInt nativeCharactersLength = aNativeCharacters.Length();
-		// 16-bit copy with possible endianess correction
-		TInt elementCount=nativeCharactersLength*2;
-		TPtr8 outputPtr(CheckAllocBufferL(&iConvertedUDElements,elementCount,elementCount));
-	    for (TInt i=0;i<nativeCharactersLength;i++)
-		    {
-		    outputPtr[2*i]=(TUint8)(aNativeCharacters[i]>>8);
-		    outputPtr[2*i+1]=(TUint8)aNativeCharacters[i];
-		    }
-		iUnconvertedNativeCharactersPtr.Zero();
-		return outputPtr;
-		}
-	else // No shortcuts, do proper conversion
-		{
-		PrepareForConversionFromNativeL(aEncoding);
-		
-		// Create input buffer
-		TInt newInputLength=iUnconvertedNativeCharactersPtr.Length()+aNativeCharacters.Length();
-		iUnconvertedNativeCharactersPtr.Set(CheckAllocBufferL(&iUnconvertedNativeCharacters,newInputLength,iUnconvertedNativeCharactersPtr.Length()));
-		iUnconvertedNativeCharactersPtr.Append(aNativeCharacters);
-
-		// Ensure buffer is at least the length of the input buffer
-		TPtr8 outputPtr=CheckAllocBufferL(&iConvertedUDElements,iUnconvertedNativeCharactersPtr.Length(),0);
-
-		TInt retryCount=0;
-		TInt unconvertedCount=iUnconvertedNativeCharactersPtr.Length();
-		while (unconvertedCount)
-			{
-			TInt  tempNumberOfUnconvertibleCharacters = 0;
-			TInt  tempNumberOfDowngradedCharacters    = 0;
-			
-			// Get a pointer to unfilled area of output buffer
-			TPtr8 fillPtr((TUint8*)outputPtr.Ptr()+outputPtr.Length(),0,outputPtr.MaxLength()-outputPtr.Length());
-			// Try the conversion & get number of unconverted characters
-			TInt newUnconvertedCount=iCharacterSetConverter.ConvertFromUnicode(fillPtr,iUnconvertedNativeCharactersPtr);
-			if (newUnconvertedCount<0)
-				break;
-
-			// Compare what is converted with the original, to get downgrade count
-			TPtr  tempBufPtr((TUint16*)iUnconvertedNativeCharactersPtr.Ptr(), 0, fillPtr.Length());
-			TInt  offset      = aNativeCharacters.Length() - unconvertedCount;
-			TInt  state       = CCnvCharacterSetConverter::KStateDefault;
-			TInt  notRestored = iCharacterSetConverter.ConvertToUnicode(tempBufPtr, fillPtr, state);
-			
-			if (notRestored > 0)
-				{
-				tempNumberOfUnconvertibleCharacters += notRestored;
-				}
-			
-			for (TInt pos = 0;  pos < tempBufPtr.Length();  pos++)
-				{
-				if (tempBufPtr[pos] != aNativeCharacters[offset + pos])
-					{
-					if (tempBufPtr[pos] != KReplacementCharacter)
-						{
-						tempNumberOfDowngradedCharacters++;
-						}
-					else
-						{
-						tempNumberOfUnconvertibleCharacters++;
-						}
-					}
-				}
-
-			//
-			// If characters were downgraded or unconverted then replace them
-			// with downgrades from the PREQ2090 converter.
-			//
-			if (tempNumberOfUnconvertibleCharacters > 0  &&
-				aEncoding != ESmsEncodingNone)
-				{
-				HBufC8*  downgradesBuf = HBufC8::NewLC(iUnconvertedNativeCharactersPtr.Length());
-				HBufC*  nativeBuf = HBufC::NewLC(iUnconvertedNativeCharactersPtr.Length());
-				TPtr8  downgradesPtr = downgradesBuf->Des();
-				TPtr  nativePtr = nativeBuf->Des();
-
-				PrepareForConversionFromNativeL(ESmsEncodingNone);
-
-				// Attempt to convert the text
-	 			TInt ret = iCharacterSetConverter.ConvertFromUnicode(downgradesPtr, iUnconvertedNativeCharactersPtr);
-		 		if (ret >= 0)
-		 			{
-					// Compare what is converted with the original...
-					state       = CCnvCharacterSetConverter::KStateDefault;
-					notRestored = iCharacterSetConverter.ConvertToUnicode(nativePtr, downgradesPtr, state);
-						
-					if (notRestored >= 0)
-						{
-						// Merge in the downgrades
-						TInt  pos;
-						
-						for (pos = 0;  pos < tempBufPtr.Length();  pos++)
-							{
-							if (tempBufPtr[pos] != aNativeCharacters[offset + pos])
-								{
-								if (tempBufPtr[pos] != KReplacementCharacter)
-									{
-									tempBufPtr[pos] = nativePtr[pos];
-									}
-								}
-							}
-
-						// Reconvert...
-						PrepareForConversionFromNativeL(aEncoding);
-
-						newUnconvertedCount=iCharacterSetConverter.ConvertFromUnicode(fillPtr,iUnconvertedNativeCharactersPtr);
-						if (newUnconvertedCount<0)
-							break;
-
-						// Recount the changed characters...
-						tempNumberOfUnconvertibleCharacters = 0;
-						tempNumberOfDowngradedCharacters    = 0;
-
-						for (pos = 0;  pos < tempBufPtr.Length();  pos++)
-							{
-							if (tempBufPtr[pos] != aNativeCharacters[offset + pos])
-								{
-								if (tempBufPtr[pos] != KReplacementCharacter)
-									{
-									tempNumberOfDowngradedCharacters++;
-									}
-								else
-									{
-									tempNumberOfUnconvertibleCharacters++;
-									}
-								}
-							}
-		 				}
-					}
-				
-				CleanupStack::PopAndDestroy(2, downgradesBuf);
-				}
-
-			//
-			// Store these downgraded/unconvertible character counts...
-			//
-			aNumberOfDowngradedCharacters    += tempNumberOfDowngradedCharacters;
-			aNumberOfUnconvertibleCharacters += tempNumberOfUnconvertibleCharacters;
-			
-			// Update original buffer length, check retry count and realloc if req'd
-			outputPtr.SetLength(outputPtr.Length()+fillPtr.Length());
-			if (newUnconvertedCount==unconvertedCount)
-				{
-				if (++retryCount>KMaxSmsAlphabetConversionRetries)
-					{
-					__ASSERT_DEBUG(EFalse,Panic(KGsmuPanicConversionRetriedOut));
-					break;
-					}
-				}
-			else
-				{
-				iUnconvertedNativeCharactersPtr.Delete(0,unconvertedCount-newUnconvertedCount);
-				retryCount=0;
-				}
-			unconvertedCount=newUnconvertedCount;
-			// Check for realloc
-			if (unconvertedCount)
-				outputPtr.Set(CheckAllocBufferL(&iConvertedUDElements,iConvertedUDElements->Length()+Max(unconvertedCount,KMinSmsAlphabetConversionAllocIncrement),outputPtr.Length()));
-			}
-
-		return outputPtr;
-		}
-	} // CSmsAlphabetConverter::ConvertFromNativeL
-
-
-/**
- *  Converts the user data elements of the specified character set to the native
- *  character set.
- *  
- *  @param aUDElements The converted character set data
- * 
- *  @return Native character set data (Unicode only)
- * 
- *  @capability None
- */
-EXPORT_C TPtrC CSmsAlphabetConverter::ConvertToNativeL(const TDesC8& aUDElements)
-	{
-	LOGGSMU1("CSmsAlphabetConverter::ConvertToNativeL()");
-
-	return ConvertToNativeL(aUDElements, ESmsEncodingNone);
-	} // CSmsAlphabetConverter::ConvertToNativeL
-
-
-/**
- *  Converts the user data elements of the specified character set to the native
- *  character set.
- *  
- *  @param aUDElements The converted character set data
- *  @param aEncoding   Alternative 7bit encoding to used (if needed)
- * 
- *  @return Native character set data (Unicode only)
- * 
- *  @capability None
- */
-EXPORT_C TPtrC CSmsAlphabetConverter::ConvertToNativeL(const TDesC8& aUDElements,
-													   TSmsEncoding aEncoding)
-	{
-	LOGGSMU2("CSmsAlphabetConverter::ConvertToNativeL(): aEncoding=%d", aEncoding);
-
-	// Check for some shortcuts
-	if (iIsBinary ||  iSmsAlphabet == TSmsDataCodingScheme::ESmsAlphabet8Bit)
-		{
-		// Binary data stored as padded unicode
-		TPtr16 outputPtr=CheckAllocBufferL(&iConvertedNativeCharacters,aUDElements.Length(),0);
-		outputPtr.Copy(aUDElements);
-		iUnconvertedUDElementsPtr.Zero();
-		return outputPtr;
-		}
-	else if (iSmsAlphabet==TSmsDataCodingScheme::ESmsAlphabetUCS2)
-		{
-		// 16-bit copy with possible endianess correction
-		TInt charCount=aUDElements.Length()/2;
-		TPtr16 outputPtr=CheckAllocBufferL(&iConvertedNativeCharacters,charCount,charCount);
-	    for (TInt i=0; i<charCount; i++)
-		    {
-		    outputPtr[i]=(TText)(aUDElements[2*i]<<8);
-		    outputPtr[i]=(TText)(outputPtr[i]+(aUDElements[2*i+1]));
-		    }
-		iUnconvertedUDElementsPtr.Zero();
-		return outputPtr;
-		}
-	else
-		{
-		PrepareForConversionToNativeL(aEncoding);
-
-		// Create input buffer with unconverted characters prepended
-		TInt newInputLength=iUnconvertedUDElementsPtr.Length()+aUDElements.Length();
-		iUnconvertedUDElementsPtr.Set(CheckAllocBufferL(&iUnconvertedUDElements,newInputLength,iUnconvertedUDElementsPtr.Length()));
-		iUnconvertedUDElementsPtr.Append(aUDElements);
-
-		// Ensure buffer is at least the length of the input buffer
-		TPtr outputPtr=CheckAllocBufferL(&iConvertedNativeCharacters,iUnconvertedUDElementsPtr.Length(),0);
-
-		TInt retryCount=0;
-		TInt unconvertedCount=iUnconvertedUDElementsPtr.Length();
-		TInt state=CCnvCharacterSetConverter::KStateDefault;
-		while (unconvertedCount)
-			{
-			// Get a pointer to unfilled area of output buffer
-			TPtr16 fillPtr((TUint16*)outputPtr.Ptr()+outputPtr.Length(),0,outputPtr.MaxLength()-outputPtr.Length());
-			// Try the conversion & get number of unconverted characters
-			TInt newUnconvertedCount=iCharacterSetConverter.ConvertToUnicode(fillPtr,iUnconvertedUDElementsPtr,state);
-			if (newUnconvertedCount<0)
-				break;
-			// Update original buffer length & check retry count
-			outputPtr.SetLength(outputPtr.Length()+fillPtr.Length());
-			if (newUnconvertedCount==unconvertedCount)
-				{
-				if (++retryCount>KMaxSmsAlphabetConversionRetries)
-					{
-					__ASSERT_DEBUG(EFalse,Panic(KGsmuPanicConversionRetriedOut));
-					break;
-					}
-				}
-			else
-				{
-				iUnconvertedUDElementsPtr.Delete(0,unconvertedCount-newUnconvertedCount);
-				retryCount=0;
-				}
-			unconvertedCount=newUnconvertedCount;
-			// Check for realloc
-			if (unconvertedCount)
-				outputPtr.Set(CheckAllocBufferL(&iConvertedNativeCharacters,iConvertedNativeCharacters->Length()+Max(unconvertedCount,KMinSmsAlphabetConversionAllocIncrement),outputPtr.Length()));
-			}
-		return outputPtr;
-		}
-	} // CSmsAlphabetConverter::ConvertToNativeL
-
-
-/**
- *  Tests if the character is supported by the current character set.
- *  This function can be used with 7bit and 8bit alphabets.
- * 
- *  @param aChar  Character to investigate.
- * 
- *  @return  ETrue if the character is supported.
- * 
- *  @note Since the function is based on the old behaviour (pre-PREQ2090)
- *        it does not accept a downgraded character or alternative encoding
- *        as being supported.
- */
-TBool CSmsAlphabetConverter::IsSupportedL(TChar aChar)
-	{
-	LOGGSMU2("[1] CSmsAlphabetConverter::IsSupportedL(aChar=0x%04x)", (TUint) aChar);
-
-	TBool isDowngrade, isRequiresAlternativeEncoding;
-
-    TBool  supported = IsSupportedL(aChar, ESmsEncodingNone,
-            isDowngrade, isRequiresAlternativeEncoding);
-	
-	LOGGSMU2("CSmsAlphabetConverter::IsSupportedL(): supported=%d.", supported);
-
-	return supported;
-	} // CSmsAlphabetConverter::IsSupportedL
-
-
-/**
- *  Tests if the descriptor text is supported by the current character set.
- *  This function can be used with 7bit and 8bit alphabets.
- * 
- *  @param aDes                                 Text string to check.
- *  @param aNumberOfUnconvertibleCharacters     Exit param for the number of
- *                                              characters unconvertible.
- *  @param aIndexOfFirstUnconvertibleCharacter  Exit param for the first
- *                                              unconverted character.
- * 
- *  @return  ETrue if the character is supported.
- */
-TBool CSmsAlphabetConverter::IsSupportedL(const TDesC& aDes, TInt& aNumberOfUnconvertibleCharacters,
-                                          TInt& aIndexOfFirstUnconvertibleCharacter)
-	{
-	LOGGSMU2("[2] CSmsAlphabetConverter::IsSupportedL(aDes=\"%S\")", &aDes);
-
-	TInt desLength = aDes.Length();
-	//
-	// Initialise the exit params...
-	//
-	aNumberOfUnconvertibleCharacters    = 0;
-	aIndexOfFirstUnconvertibleCharacter = desLength;
-
-    //
-    // Create buffers for the input converted to 7Bit and a buffer for it once
-    // converted back again...
-    //
-    HBufC8* encodedBuf       = HBufC8::NewLC(desLength*2); // worse case
-    HBufC*  backToUnicodeAfterStdBuf = HBufC::NewLC(desLength);
-    TPtr8  encoded(encodedBuf->Des());
-    TPtr  backToUnicodeAfterStd(backToUnicodeAfterStdBuf->Des());
-
-    //
-    // Convert the input string to standard 7bit (with downgrades if needed)...
-    // 
-    PrepareForConversionFromNativeL(ESmsEncodingNone);
-
-    TInt  notConverted = iCharacterSetConverter.ConvertFromUnicode(encoded, aDes);
-
-    if (notConverted > 0)
-        {
-        aNumberOfUnconvertibleCharacters += notConverted;
-        }
-    else if (notConverted < 0)
-        {
-        aNumberOfUnconvertibleCharacters = desLength;
-        }
-    
-    //
-    // Convert it back again to the native format...
-    //
-    TInt  state       = CCnvCharacterSetConverter::KStateDefault;
-    TInt  notRestored = iCharacterSetConverter.ConvertToUnicode(backToUnicodeAfterStd, encoded, state);
-
-    if (notRestored > 0)
-        {
-        aNumberOfUnconvertibleCharacters += notRestored;
-        }
-    else if (notRestored < 0)
-        {
-        aNumberOfUnconvertibleCharacters = desLength;
-        }
-
-    //
-    // Work out if the string is acceptable as it is (e.g. no unconvertible
-    // and no downgrades). We only need do this if the previous conversions were
-    // complete with no issues.
-    //
-    for (TInt pos = desLength-1;  pos >= 0;  --pos)
-        {
-        if (backToUnicodeAfterStd[pos] != aDes[pos])
-            {
-            aNumberOfUnconvertibleCharacters++;
-            aIndexOfFirstUnconvertibleCharacter = pos;
-            }
-        }
-    
-    CleanupStack::PopAndDestroy(backToUnicodeAfterStdBuf);
-    CleanupStack::PopAndDestroy(encodedBuf);
-	
-	//
-	// Useful logging...
-	//
-	TBool  supported = (aNumberOfUnconvertibleCharacters == 0);
-
-	LOGGSMU2("CSmsAlphabetConverter::IsSupportedL(): aNumberOfUnconvertibleCharacters=%d.", aNumberOfUnconvertibleCharacters);
-	LOGGSMU2("CSmsAlphabetConverter::IsSupportedL(): aIndexOfFirstUnconvertibleCharacter=%d.", aIndexOfFirstUnconvertibleCharacter);
-	LOGGSMU2("CSmsAlphabetConverter::IsSupportedL(): supported=%d.", supported);
-
-	return supported;
-	} // CSmsAlphabetConverter::IsSupportedL
-
-
-/**
- *  Tests if the character is supported by the current character set.
- *  This function can be used with 7bit and 8bit alphabets.
- * 
- *  @param aChar                         Character to investigate.
- *  @param aEncoding                     Alternative 7bit encoding (if used).
- *  @param aIsDowngrade                  Exit param set to ETrue if the
- *                                       character has to be downgraded.
- *  @param aRequiresAlternativeEncoding  Exit param set to ETrue if the
- *                                       alternative encoding has to be
- *                                       used to encode it.
- * 
- *  @return  ETrue if the character is supported.
- */
-TBool CSmsAlphabetConverter::IsSupportedL(TChar aChar, TSmsEncoding aEncoding,
-		                                  TBool& aIsDowngrade,
-                                          TBool& aRequiresAlternativeEncoding)
-	{
-	LOGGSMU2("[3] CSmsAlphabetConverter::IsSupportedL(aChar=0x%04x)", (TUint) aChar);
-
-	//
-	// Convert the character...
-	//
-	TInt  numberOfUnconvertibleCharacters, numberOfDowngradedCharacters, 
-            numberRequiringAlternativeEncoding, indexOfFirstUnconvertibleCharacter;
-	TBuf<4>   toEncode;
-
-	toEncode.SetLength(1);
-	toEncode[0]=(TText)aChar;
-
-	TBool supported = IsSupportedL(toEncode, aEncoding, 
-	        numberOfUnconvertibleCharacters,
-	        numberOfDowngradedCharacters,
-	        numberRequiringAlternativeEncoding,
-	        indexOfFirstUnconvertibleCharacter);
-
-	//
-	// Calculate the exit params...
-	//
-	aIsDowngrade                 = (numberOfDowngradedCharacters > 0);
-	aRequiresAlternativeEncoding = (numberRequiringAlternativeEncoding > 0);
-	    
-	//
-	// Useful logging...
-	//
-	LOGGSMU2("CSmsAlphabetConverter::IsSupportedL(): aIsDowngrade=%d.", aIsDowngrade);
-	LOGGSMU2("CSmsAlphabetConverter::IsSupportedL(): aRequiresAlternativeEncoding=%d.", aRequiresAlternativeEncoding);
-	LOGGSMU2("CSmsAlphabetConverter::IsSupportedL(): supported=%d.", supported);
-
-	return supported;
-	} // CSmsAlphabetConverter::IsSupportedL
-
-
-/**
- *  Tests if the descriptor text is supported by the current character set.
- *  This function can be used with 7bit and 8bit alphabets.
- * 
- *  @param aDes                                 Text string to check.
- *  @param aEncoding                            Alternative 7bit encoding (if used).
- *  @param aNumberOfUnconvertibleCharacters     Exit param for the number of
- *                                              characters unconvertible.
- *  @param aNumberOfDowngradedCharacters        Exit param for the number of
- *                                              downgraded characters.
- *  @param aNumberRequiringAlternativeEncoding  Exit param for the number of
- *                                              characters requiring use of
- *                                              the alternative encoder.
- *  @param aIndexOfFirstUnconvertibleCharacter  Exit param for the first
- *                                              unconverted character.
- * 
- *  @return  ETrue if the character is supported.
- */
-TBool CSmsAlphabetConverter::IsSupportedL(const TDesC& aDes, TSmsEncoding aEncoding,
-										  TInt& aNumberOfUnconvertibleCharacters,
-                                          TInt& aNumberOfDowngradedCharacters,
-                                          TInt& aNumberRequiringAlternativeEncoding,
-                                          TInt& aIndexOfFirstUnconvertibleCharacter)
-	{
-	LOGGSMU2("[4] CSmsAlphabetConverter::IsSupportedL(aDes=\"%S\")", &aDes);
-
-	TInt desLength = aDes.Length();
-	//
-	// Initialise the exit params...
-	//
-	aNumberOfUnconvertibleCharacters    = 0;
-	aNumberOfDowngradedCharacters       = 0;
-	aNumberRequiringAlternativeEncoding = 0;
-	aIndexOfFirstUnconvertibleCharacter = desLength;
-	
-	//
-	// Create buffers for the input converted to 7Bit and a buffer for it once
-	// converted back again...
-	//
-    HBufC8* encodedBuf       = HBufC8::NewLC(desLength*2); // worse case
-    HBufC*  backToUnicodeAfterStdBuf = HBufC::NewLC(desLength);
-    TPtr8  encoded(encodedBuf->Des());
-    TPtr  backToUnicodeAfterStd(backToUnicodeAfterStdBuf->Des());
-
-    //
-    // Convert the input string to standard 7bit (with downgrades if needed)...
-    // 
-    PrepareForConversionFromNativeL(ESmsEncodingNone);
-
-    TInt  notConverted = iCharacterSetConverter.ConvertFromUnicode(encoded, aDes);
-
-    if (notConverted > 0)
-        {
-        aNumberOfUnconvertibleCharacters += notConverted;
-        }
-    else if (notConverted < 0)
-        {
-        aNumberOfUnconvertibleCharacters = desLength;
-        }
-    
-    //
-    // Convert it back again to the native format...
-    //
-    TInt  state       = CCnvCharacterSetConverter::KStateDefault;
-    TInt  notRestored = iCharacterSetConverter.ConvertToUnicode(backToUnicodeAfterStd, encoded, state);
-
-    if (notRestored > 0)
-        {
-        aNumberOfUnconvertibleCharacters += notRestored;
-        }
-    else if (notRestored < 0)
-        {
-        aNumberOfUnconvertibleCharacters = desLength;
-        }
-
-    //
-    // Work out if the string is acceptable as it is (e.g. no unconvertible
-    // and no downgrades).
-    //
-    for (TInt pos = desLength-1;  pos >= 0;  --pos)
-        {
-        if (backToUnicodeAfterStd[pos] != aDes[pos])
-            {
-            if (backToUnicodeAfterStd[pos] != KReplacementCharacter)
-                {
-                aNumberOfDowngradedCharacters++;
-                }
-            else
-                {
-                aNumberOfUnconvertibleCharacters++;
-                aIndexOfFirstUnconvertibleCharacter = pos;
-                }
-            }
-        }
-
-    TInt  totalCharFaultsSoFar = aNumberOfUnconvertibleCharacters + 
-                                    aNumberOfDowngradedCharacters;
-    
-    //
-    // If the total unconvertible plus downgrades is zero, then there is nothing
-    // more to do as the string can be converted to 7bit with no issues and no
-    // other encoder is needed.
-    //
-    // Otherwise we have to look at the alternative encoder...
-    //
-    if (totalCharFaultsSoFar == 0)
-        {
-        //
-        // We are done (the return counts are already zero and therefore
-        // correct at this point too!).
-        //
-        }
-    else if (iSmsAlphabet != TSmsDataCodingScheme::ESmsAlphabet7Bit  ||
-             aEncoding == ESmsEncodingNone)
-        {
-        //
-        // The string was not perfectly converted, but there is no alternative
-        // encoder to try.  We are done.
-        //
-        }
-    else
-        {
-        //
-        // Initialise the params...
-        //
-        TInt  tmpDowngradedCharacters        = 0;
-        TInt  tmpUnconvertibleCharacters     = 0;
-        TInt  tmpIndexOfFirstUnconvertibleCharacter = desLength;
-		
-        //
-        // Convert the input string to the alternative encoding...
-        //
-        PrepareForConversionFromNativeL(aEncoding);
-
-        notConverted = iCharacterSetConverter.ConvertFromUnicode(encoded, aDes);
-        if (notConverted > 0)
-            {
-            tmpUnconvertibleCharacters = notConverted;
-            }
-        else if (notConverted < 0)
-            {
-            tmpUnconvertibleCharacters = desLength;
-            }
-
-        //
-        // Convert it back again to the native format...
-        //
-        HBufC*  backToUnicodeAfterAltBuf = HBufC::NewLC(desLength);
-        TPtr  backToUnicodeAfterAlt(backToUnicodeAfterAltBuf->Des());
-        TInt  state       = CCnvCharacterSetConverter::KStateDefault;
-        TInt  notRestored = iCharacterSetConverter.ConvertToUnicode(backToUnicodeAfterAlt, encoded, state);
-
-        if (notRestored > 0)
-            {
-            tmpUnconvertibleCharacters += notRestored;
-            }
-        else if (notRestored < 0)
-            {
-            tmpUnconvertibleCharacters = desLength;
-            }
-
-        //
-        // Now work out which characters are downgrades, require alternative encoding
-        // or are unsupported.
-        //
-        for (TInt pos = desLength-1;  pos >= 0;  --pos)
-            {
-            if (backToUnicodeAfterStd[pos] != aDes[pos])
-                {
-                // Not supported by standard encoder...
-                if (backToUnicodeAfterAlt[pos] == aDes[pos])
-                    {
-                    // Supported by alternative encoder...
-                    aNumberRequiringAlternativeEncoding++;
-                    }
-                else if (backToUnicodeAfterStd[pos] != KReplacementCharacter)
-                    {
-                    // Downgraded by standard encoder...
-                    tmpDowngradedCharacters++;
-                    }
-                else if (backToUnicodeAfterAlt[pos] != KReplacementCharacter)
-                    {
-                    // Downgraded by alternative encoder...
-                    tmpDowngradedCharacters++;
-                    aNumberRequiringAlternativeEncoding++;
-                    }
-                else
-                    {
-                    // Unconvertible...
-                    tmpUnconvertibleCharacters++;
-                    tmpIndexOfFirstUnconvertibleCharacter = pos;
-                    }
-                }
-            }
-
-        // Is this better?  
-        if ( totalCharFaultsSoFar >= (tmpUnconvertibleCharacters + tmpDowngradedCharacters) )
-            {
-            // Best conversion is the alternative conversion
-            aNumberOfUnconvertibleCharacters     = tmpUnconvertibleCharacters;
-            aNumberOfDowngradedCharacters        = tmpDowngradedCharacters;
-            aIndexOfFirstUnconvertibleCharacter  = tmpIndexOfFirstUnconvertibleCharacter;
-            }
-        else
-            {
-            // Best conversion is the standard conversion
-            aNumberRequiringAlternativeEncoding = 0;
-            }
-        
-        CleanupStack::PopAndDestroy(backToUnicodeAfterAltBuf);
-        }
-    
-    CleanupStack::PopAndDestroy(backToUnicodeAfterStdBuf);
-    CleanupStack::PopAndDestroy(encodedBuf);
-
-	//
-	// Useful logging...
-	//
-	TBool  supported = (aNumberOfUnconvertibleCharacters == 0);
-
-	LOGGSMU2("CSmsAlphabetConverter::IsSupportedL(): aNumberOfUnconvertibleCharacters=%d.", aNumberOfUnconvertibleCharacters);
-	LOGGSMU2("CSmsAlphabetConverter::IsSupportedL(): aNumberOfDowngradedCharacters=%d.", aNumberOfDowngradedCharacters);
-	LOGGSMU2("CSmsAlphabetConverter::IsSupportedL(): aNumberRequiringAlternativeEncoding=%d.", aNumberRequiringAlternativeEncoding);
-	LOGGSMU2("CSmsAlphabetConverter::IsSupportedL(): aIndexOfFirstUnconvertibleCharacter=%d.", aIndexOfFirstUnconvertibleCharacter);
-	LOGGSMU2("CSmsAlphabetConverter::IsSupportedL(): supported=%d.", supported);
-
-	return supported;
-	} // CSmsAlphabetConverter::IsSupportedL
-
-
-/**
- *  Given a piece of text and an alternative encoding, this function works out
- *  which encoding is best to use and returns the ID of that converter.
- * 
- *  @param aNativeCharacters      Text to use as a sample.
- *  @param aEncoding              Suggested alternative 7bit encoding method.
- * 
- *  @return Encoding that should be used.
- */
-TSmsEncoding CSmsAlphabetConverter::FindBestAlternativeEncodingL(const TDesC& aNativeCharacters,
-									                     		 TSmsEncoding aSuggestedEncoding)
-	{
-	LOGGSMU2("CSmsAlphabetConverter::FindBestAlternativeEncodingL(): aSuggestedEncoding=%d",
-			 aSuggestedEncoding);
-
-	TSmsEncoding  encodingToUse = ESmsEncodingNone;
-
-	//
-	// If this is not 7bit or the alternative encoding is not set then do
-	// nothing...
-	//
-	if (aSuggestedEncoding != ESmsEncodingNone  &&
-		iSmsAlphabet == TSmsDataCodingScheme::ESmsAlphabet7Bit)
-		{
-		TInt  numberOfUnconvertibleCharacters, numberOfDowngradedCharacters;
-		TInt  numberRequiringAlternativeEncoding, indexOfFirstUnconvertibleCharacter;
-		
-		//
-		// First try the default encoding (but in this case treat downgrades
-		// as unconverted, since later encoders might do better)...
-		//
-		IsSupportedL(aNativeCharacters, ESmsEncodingNone,
-					 numberOfUnconvertibleCharacters,
-                     numberOfDowngradedCharacters,
-                     numberRequiringAlternativeEncoding,
-                     indexOfFirstUnconvertibleCharacter);
-
-		TInt leastUnconvertibleCharacters = numberOfUnconvertibleCharacters + numberOfDowngradedCharacters;
-
-		//
-		// Create a list of alternative encodings to try...
-		//
-		TSmsEncoding  encodingList[8];
-		TInt          encodingCount = 0;
-		
-		if (aSuggestedEncoding == ESmsEncodingTurkishLockingAndSingleShift)
-			{
-			encodingList[encodingCount++] = ESmsEncodingTurkishSingleShift;
-			encodingList[encodingCount++] = ESmsEncodingTurkishLockingShift;
-			}
-		else if (aSuggestedEncoding == ESmsEncodingPortugueseLockingAndSingleShift)
-			{
-			encodingList[encodingCount++] = ESmsEncodingPortugueseSingleShift;
-			encodingList[encodingCount++] = ESmsEncodingPortugueseLockingShift;
-			}
-
-		encodingList[encodingCount++] = aSuggestedEncoding;
-		encodingList[encodingCount++] = ESmsEncodingNone;
-
-		//
-		// Now try the all the alternatives...
-		//
-		for (TInt  encoder = 0;  encoder < encodingCount;  encoder++)
-			{
-			IsSupportedL(aNativeCharacters, encodingList[encoder],
-						 numberOfUnconvertibleCharacters,
-	                     numberOfDowngradedCharacters,
-	                     numberRequiringAlternativeEncoding,
-	                     indexOfFirstUnconvertibleCharacter);
-			if (numberOfUnconvertibleCharacters + numberOfDowngradedCharacters < leastUnconvertibleCharacters)
-				{
-				encodingToUse = encodingList[encoder];
-				leastUnconvertibleCharacters = numberOfUnconvertibleCharacters + numberOfDowngradedCharacters;
-				}
-			}
-		}
-
-	LOGGSMU2("CSmsAlphabetConverter::FindBestAlternativeEncodingL(): encodingToUse=%d", encodingToUse);
-
-	return encodingToUse;
-	} // CSmsAlphabetConverter::FindBestAlternativeEncoding
-
-
-/**
- *  Confirms that the requested encoding method is present (e.g. the converter
- *  plug-in can be loaded).
- * 
- *  @param aEncoding  Alternative 7bit encoding method.
- * 
- *  @leave KErrNotSupported if the encoder is not available.
- */
-void CSmsAlphabetConverter::ConfirmAlternativeEncoderL(TSmsEncoding aEncoding) const
-	{
-	//
-	// Check the ID for the encoder exists...
-	//
-	if (aEncoding != ESmsEncodingNone)
-		{
-		TUint  encoderID;
-		
-		GetAlternativeEncoderIDL(aEncoding, encoderID);
-		
-		//
-		// Confirm it can be loaded...
-		//
-		if (iCharacterSetConverter.PrepareToConvertToOrFromL(encoderID, iFs) != CCnvCharacterSetConverter::EAvailable)
-			{
-			User::Leave(KErrNotSupported);
-			}
-		}
-	} // CSmsAlphabetConverter::ConfirmAlternativeEncoderL
-
-
-/**
- *  Prepares the converted for conversion from native charset.
- *  Character set specific preparation is performed here.
- * 
- *  @param aEncoding  Alternative 7bit encoding to use if required.
- */
-void CSmsAlphabetConverter::PrepareForConversionFromNativeL(TSmsEncoding aEncoding)
-	{
-	LOGGSMU2("CSmsAlphabetConverter::PrepareForConversionFromNativeL(): aEncoding=%d",
-			 aEncoding);
-
-	__ASSERT_DEBUG(iIsBinary==EFalse,Panic(KGsmuPanicUnsupportedAlphabet));
-	switch (iSmsAlphabet)
-		{
-		case TSmsDataCodingScheme::ESmsAlphabet7Bit:
-			{
-			//
-			// If an alternative encoding has been specified then try and
-			// load that converter...
-			//
-			if (aEncoding != ESmsEncodingNone)
-				{
-				TUint  alternativeEncoderID;
-				
-				GetAlternativeEncoderIDL(aEncoding, alternativeEncoderID);
-				if (alternativeEncoderID != 0)
-					{
-					CCnvCharacterSetConverter::TAvailability  availability;
-		
-					LOGGSMU2("CSmsAlphabetConverter::PrepareForConversionFromNativeL(): Converter 0x%08x",
-							 alternativeEncoderID);
-					
-					availability = iCharacterSetConverter.PrepareToConvertToOrFromL(alternativeEncoderID, iFs);
-					if (availability == CCnvCharacterSetConverter::EAvailable)
-						{
-			 			// Force unicode line termination characters to simple line feed
-			 			iCharacterSetConverter.SetDowngradeForExoticLineTerminatingCharacters(
-				 				CCnvCharacterSetConverter::EDowngradeExoticLineTerminatingCharactersToJustLineFeed);
-					
-						// Job done, return
-			 			return;
-						}
-					
-					// Plug-in could not be loaded, so drop through and load the default!
-					}
-				}
-			
-			//
-			// Check for the PREQ2090 7bit converter with Eastern European
-			// downgrade support first, otherwise if the plug-in is not found
-			// use the standard internal converter.
-			//
-			CCnvCharacterSetConverter::TAvailability  availability;
-			
-			availability = iCharacterSetConverter.PrepareToConvertToOrFromL(KCharacterSetIdentifierExtendedSms7Bit, iFs);
-			if (availability == CCnvCharacterSetConverter::ENotAvailable)
-				{
-				availability = iCharacterSetConverter.PrepareToConvertToOrFromL(KCharacterSetIdentifierSms7Bit, iFs);
-				if (availability == CCnvCharacterSetConverter::ENotAvailable)
-					{
-					User::Leave(KErrNotFound);
-					}
-				}
-
- 			// Force unicode line termination characters to simple line feed
- 			iCharacterSetConverter.SetDowngradeForExoticLineTerminatingCharacters(
- 				CCnvCharacterSetConverter::EDowngradeExoticLineTerminatingCharactersToJustLineFeed);
-			break;
-			}
-		case TSmsDataCodingScheme::ESmsAlphabet8Bit:
-			{
-			CCnvCharacterSetConverter::TAvailability availability=iCharacterSetConverter.PrepareToConvertToOrFromL(KCharacterSetIdentifierCodePage1252,iFs);
-			if (availability==CCnvCharacterSetConverter::ENotAvailable)
-				{
-				User::Leave(KErrNotFound);
-				}
-
- 			// Force unicode line termination characters to simple line feed
- 			iCharacterSetConverter.SetDowngradeForExoticLineTerminatingCharacters(
- 				CCnvCharacterSetConverter::EDowngradeExoticLineTerminatingCharactersToJustLineFeed);
-			break;
-			}
-		case TSmsDataCodingScheme::ESmsAlphabetUCS2:
-		default:
-			{
-            User::Leave(KErrNotSupported);
-			}
-		}
-	} // CSmsAlphabetConverter::PrepareForConversionFromNativeL
-
-
-/**
- *  Prepares the converted for conversion to unicode.  Character set
- *  specific preparation is performed here.
- * 
- *  @param aEncoding  Alternative 7bit encoding to use if required.
- */
-void CSmsAlphabetConverter::PrepareForConversionToNativeL(TSmsEncoding aEncoding)
-	{
-	LOGGSMU2("CSmsAlphabetConverter::PrepareForConversionToNativeL(): aEncoding=%d",
-			 aEncoding);
-
-	switch (iSmsAlphabet)
-		{
-		case TSmsDataCodingScheme::ESmsAlphabet7Bit:
-			{
-			//
-			// If an alternative encoding has been specified then try and
-			// load that converter...
-			//
-			if (aEncoding != ESmsEncodingNone)
-				{
-				TUint  alternativeEncoderID;
-				
-				GetAlternativeEncoderIDL(aEncoding, alternativeEncoderID);
-				if (alternativeEncoderID != 0)
-					{
-					CCnvCharacterSetConverter::TAvailability  availability;
-		
-					LOGGSMU2("CSmsAlphabetConverter::PrepareForConversionFromNativeL(): Converter 0x%08x",
-							 alternativeEncoderID);
-					
-					availability = iCharacterSetConverter.PrepareToConvertToOrFromL(alternativeEncoderID, iFs);
-					if (availability == CCnvCharacterSetConverter::EAvailable)
-						{
-						// Job done, return
-			 			return;
-						}
-					
-					// Plug-in could not be loaded, so drop through and load the default!
-					}
-				}
-			
-			//
-			// Always use the internal converter, as it is quicker to prepare
-			// and the PREQ2090 7bit converter with Eastern European downgrade
-			// offers no benefit when converting to native.
-			//
-			CCnvCharacterSetConverter::TAvailability availability=iCharacterSetConverter.PrepareToConvertToOrFromL(KCharacterSetIdentifierSms7Bit,iFs);
-			if (availability==CCnvCharacterSetConverter::ENotAvailable)
-				{
-				User::Leave(KErrNotFound);
-				}
-			break;
-			}
-		case TSmsDataCodingScheme::ESmsAlphabet8Bit:
-			{
-			CCnvCharacterSetConverter::TAvailability availability=iCharacterSetConverter.PrepareToConvertToOrFromL(KCharacterSetIdentifierCodePage1252,iFs);
-			if (availability==CCnvCharacterSetConverter::ENotAvailable)
-				{
-				User::Leave(KErrNotFound);
-				}
-			break;
-			}
-		case TSmsDataCodingScheme::ESmsAlphabetUCS2:
-		default:
-			{
-			User::Leave(KErrNotSupported);
-			}
-		}
-	} // CSmsAlphabetConverter::PrepareForConversionToNativeL
-
-
-/**
- *  This function returns the alternative encoding converters that are used
- *  incase the default GSM encoding cannot encode the message completely
- *  without data loss.
- * 
- *  @param aEncoding   Encoding to obtain the converter for.
- *  @param aEncoderID  Returned converter UID if present.
- * 
- *  @leave KErrArgument if the encoding enum is invalid or
- */
-void CSmsAlphabetConverter::GetAlternativeEncoderIDL(TSmsEncoding aEncoding, TUint& aEncoderID) const
-	{
-	LOGGSMU2("CSmsAlphabetConverter::GetAlternativeEncoderIDL(%d)", aEncoding);
-
-	aEncoderID = 0;
-	
-	//
-	// Decide on appropriate encoders.
-	//
-	switch (aEncoding)
-		{
-		case ESmsEncodingNone:
-			{
-			// Nothing to set.
-			}
-			break;
-		
-		case ESmsEncodingTurkishSingleShift:
-			{
-			aEncoderID = KCharacterSetIdentifierTurkishSingleSms7Bit;
-			}
-			break;
-		
-		case ESmsEncodingTurkishLockingShift:
-			{
-			aEncoderID = KCharacterSetIdentifierTurkishLockingSms7Bit;
-			}
-			break;
-		
-		case ESmsEncodingTurkishLockingAndSingleShift:
-			{
-			aEncoderID = KCharacterSetIdentifierTurkishLockingAndSingleSms7Bit;
-			}
-			break;
-		
-		case ESmsEncodingSpanishSingleShift:
-			{
-			aEncoderID = KCharacterSetIdentifierSpanishSingleSms7Bit;
-			}
-			break;
-		
-		case ESmsEncodingPortugueseSingleShift:
-			{
-			aEncoderID = KCharacterSetIdentifierPortugueseSingleSms7Bit;
-			}
-			break;
-		
-		case ESmsEncodingPortugueseLockingShift:
-			{
-			aEncoderID = KCharacterSetIdentifierPortugueseLockingSms7Bit;
-			}
-			break;
-		
-		case ESmsEncodingPortugueseLockingAndSingleShift:
-			{
-			aEncoderID = KCharacterSetIdentifierPortugueseLockingAndSingleSms7Bit;
-			}
-			break;
-
-		default:
-			{
-			//
-			// Invalid encoder method!
-			//
-			User::Leave(KErrArgument);
-			}
-		};
-	} // CSmsAlphabetConverter::GetAlternativeEncoderIDL
-
-
-//
-// Ensures the allocated 16 bit buffer is at least of the specified length
-//
-TPtr16 CSmsAlphabetConverter::CheckAllocBufferL(HBufC16** aBuffer,TInt aMaxLength,TInt aUsedLength)
-	{
-	LOGGSMU1("CSmsAlphabetConverter::CheckAllocBufferL()");
-
-	if (*aBuffer!=NULL)
-		{
-		if ((*aBuffer)->Length()<aMaxLength)
-			{
-			*aBuffer=(*aBuffer)->ReAllocL(aMaxLength);
-			(*aBuffer)->Des().SetLength(aMaxLength);
-			}
-		}
-	else
-		{
-		*aBuffer=HBufC16::NewMaxL(aMaxLength);
-		}
-	return TPtr16((TUint16*)(*aBuffer)->Des().Ptr(),aUsedLength,(*aBuffer)->Length());
-	} // CSmsAlphabetConverter::CheckAllocBufferL
-
-
-//
-// Ensures the allocated 8 bit buffer is at least of the specified length
-//
-TPtr8 CSmsAlphabetConverter::CheckAllocBufferL(HBufC8** aBuffer,TInt aMaxLength,TInt aUsedLength)
-	{
-	LOGGSMU1("CSmsAlphabetConverter::CheckAllocBufferL()");
-
-	if (*aBuffer!=NULL)
-		{
-		if ((*aBuffer)->Length()<aMaxLength)
-			{
-			*aBuffer=(*aBuffer)->ReAllocL(aMaxLength);
-			(*aBuffer)->Des().SetLength(aMaxLength);
-			}
-		}
-	else
-		{
-		*aBuffer=HBufC8::NewMaxL(aMaxLength);
-		}
-	return TPtr8((TUint8*)(*aBuffer)->Des().Ptr(),aUsedLength,(*aBuffer)->Length());
-	} // CSmsAlphabetConverter::CheckAllocBufferL
-
-
-/**
- *  @internalComponent
- *  
- *  Determines whether the address format matches the specified type.
- *  
- *  @param aType Specifies an indicator type, as defined in the Common PCN Handset Specification
- *  @return returns ETrue if address is of specified type, EFalse otherwise 
- */
-EXPORT_C TBool TGsmSmsTelNumber::IsInstanceOf(TTypeOfIndicator aType)
-    {
-    LOGGSMU1("TGsmSmsTelNumber::IsInstanceOf()");
-
-    TBool rc = EFalse;
-
-    (void) aType;
-
-    if((aType == EVoiceMessageWaitingIndicator)
-     && ((iTypeOfAddress & TGsmSmsTypeOfAddress::EGsmSmsTONMask)==EGsmSmsTONAlphaNumeric)
-     && (iTelNumber.Length()==ECPHSSizeOfAddressField)
-     && ((iTelNumber[ECPHSAddressIndicatorType] & ECPSHIndicatorTypeBitMask) == ECPSHVoiceMailId)
-     && ((iTelNumber[ECPHSAddressIndicatorId] & ECPSHIndicatorIdBitMask) == ECPSHIndicatorId ))
-      rc = ETrue;
-
-    return rc;
-    } // TGsmSmsTelNumber::IsInstanceOf
-
-
-//
-// CSmsAddress
-//
-
-CSmsAddress* CSmsAddress::NewL(CCnvCharacterSetConverter& aCharacterSetConverter,RFs& aFs)
-	{
-	LOGGSMU1("CSmsAddress::NewL()");
-
-	CSmsAddress* address=new(ELeave) CSmsAddress(aCharacterSetConverter,aFs);
-	CleanupStack::PushL(address);
-	TPtrC ptr;
-	address->SetAddressL(ptr);
-	CleanupStack::Pop();
-	return address;
-	} // CSmsAddress::NewL
-
-
-CSmsAddress::~CSmsAddress()
-    {
-    delete iBuffer;
-    } // CSmsAddress::NewL
-
-
-/**
- *  Duplicates this CSmsAddress object.
- * 
- *  @return  Pointer to the newly created CSmsAddress object.
- */
-CSmsAddress* CSmsAddress::DuplicateL() const
-	{
-	LOGGSMU1("CSmsAddress::DuplicateL()");
-
-	CSmsAddress*  address = CSmsAddress::NewL(iCharacterSetConverter, iFs);
-	CleanupStack::PushL(address);
-
-	address->SetRawAddressL(iTypeOfAddress, *iBuffer);
-	
-	CleanupStack::Pop();
-
-	return address;
-	} // CSmsAddress::DuplicateL
-
-
-TPtrC CSmsAddress::Address() const
-	{
-	LOGGSMU1("CSmsAddress::Address()");
-
-	TPtrC ptr;
-	if (iBuffer)
-		ptr.Set(iBuffer->Des());
-	return ptr;
-	} // CSmsAddress::Address
-
-
-void CSmsAddress::SetRawAddressL(TGsmSmsTypeOfAddress aTypeOfAddress, TPtrC aBufferPtr)
-    {
-    LOGGSMU1("CSmsAddress::SetRawAddressL()");
-
-    iTypeOfAddress = aTypeOfAddress;
-
-    NewBufferL(aBufferPtr.Length());
-
-	*iBuffer=aBufferPtr;
-    } // CSmsAddress::SetRawAddressL
-
-
-TGsmSmsTypeOfAddress& CSmsAddress::TypeOfAddress()
-    {
-    LOGGSMU1("CSmsAddress::TypeOfAddress()");
-
-    return iTypeOfAddress;
-    } // CSmsAddress::TypeOfAddress
-
-
-void CSmsAddress::SetAddressL(const TDesC& aAddress)
-	{
-	LOGGSMU1("CSmsAddress::SetAddressL()");
-
-	TInt length=aAddress.Length();
-	NewBufferL(length);
-	iBuffer->Des().Copy(aAddress);
-
-	const TGsmSmsTypeOfNumber typeofnumber=length && (iBuffer->Des()[0]=='+')? EGsmSmsTONInternationalNumber: EGsmSmsTONUnknown;
-	iTypeOfAddress.SetTON(typeofnumber);
-	} // CSmsAddress::SetAddressL
-
-
-void CSmsAddress::ParsedAddress(TGsmSmsTelNumber& aParsedAddress) const
-	{
-	aParsedAddress.iTypeOfAddress = iTypeOfAddress;
-
-	TInt maxparsedlength=aParsedAddress.iTelNumber.MaxLength();
-
-	if (iTypeOfAddress.TON()==EGsmSmsTONAlphaNumeric)
-		{
-		TInt parsedlength=Address().Length();
-		if (parsedlength>maxparsedlength)
-			parsedlength=maxparsedlength;
-		aParsedAddress.iTelNumber.Copy(Address().Mid(0,parsedlength));
-		}
-	else
-		{
-		aParsedAddress.iTelNumber.SetLength(maxparsedlength);
-
-		TInt length=iBuffer->Des().Length();
-		TInt parsedlength=0;
-		for (TInt i=0; (i<length) && (parsedlength<maxparsedlength); i++)
-			{
-			TText ch=iBuffer->Des()[i];
-            switch(ch)
-                {
-                case '*':
-                case '#':
-                case 'a':
-                case 'b':
-                case 'c':
-                    aParsedAddress.iTelNumber[parsedlength]=(TUint8) ch;
-                    parsedlength++;
-                    break;                    
-                default:
-                    if ((ch>='0') && (ch<='9'))
-                        {
-                        aParsedAddress.iTelNumber[parsedlength]=(TUint8) ch;
-                        parsedlength++;
-                        }
-                    break;
-                }			
-			}
-
-		aParsedAddress.iTelNumber.SetLength(parsedlength);
-		}
-	}
-
-
-void CSmsAddress::SetParsedAddressL(const TGsmSmsTelNumber& aParsedAddress)
-	{
-	LOGGSMU1("CSmsAddress::SetParsedAddressL()");
-
-	iTypeOfAddress=aParsedAddress.iTypeOfAddress;
-	DoSetParsedAddressL(aParsedAddress.iTelNumber);
-	} // CSmsAddress::SetParsedAddressL
-
-
-TUint8 CSmsAddress::SizeL()
-    {
-    LOGGSMU1("CSmsAddress::SizeL()");
-
-    TUint8 size = 0;
-
-    TBuf8<KSmsAddressMaxAddressLength> testBuffer;
-    testBuffer.SetLength(KSmsAddressMaxAddressLength);
-    TUint8* startPtr = &testBuffer[0];
-    TUint8* endPtr = NULL;
-
-    TRAPD(err,endPtr = EncodeL(startPtr));
-
-    if (err != KErrNone)
-        {
-        User::Leave(KErrArgument);
-        }
-    else
-        {
-        // handle architectures whose address space increments or whose address space decrements.
-        (endPtr > startPtr) ? (size = endPtr - startPtr) : (size = startPtr - endPtr);
-        }
-
-	return size;
-    } // CSmsAddress::SizeL
-
-
-TUint8* CSmsAddress::EncodeL(TUint8* aPtr) const
-	{
-	TGsmSmsTelNumber parsedaddress;
-	ParsedAddress(parsedaddress);
-
-	switch (iTypeOfAddress.TON())
-		{
-		case EGsmSmsTONAlphaNumeric:
-			{
-			// Mark buffer for length encoding after conversion
-			TUint8* lengthPtr=aPtr++;
-			// Encode type
-			aPtr=iTypeOfAddress.EncodeL(aPtr);
-			// 7-bit conversion
-			TPtrC address=Address();
-			TInt convertedNumUDUnits=0;
-			TPtr8 packedPtr(aPtr,0,KSmsAddressMaxAddressValueLength);
-			TSmsAlphabetPacker packer(TSmsDataCodingScheme::ESmsAlphabet7Bit,EFalse,0);
-			aPtr+=packer.ConvertAndPackL(iCharacterSetConverter,iFs,packedPtr,address,convertedNumUDUnits);
-			// Now encode length
-			TSmsOctet length=(convertedNumUDUnits*7+3)/4;
-			length.EncodeL(lengthPtr);
-			break;
-			}
-		case EGsmSmsTONInternationalNumber:
-		default:
-			{
-			TSmsOctet length=parsedaddress.iTelNumber.Length();
-			if (length > KSmsAddressMaxAddressValueLength * 2)
-			// each address value occupies one nibble.
-                {
-                User::Leave(KErrArgument);
-                }
-			aPtr=length.EncodeL(aPtr);
-			aPtr=iTypeOfAddress.EncodeL(aPtr);
-			TSmsOctet octet;
-			for (TInt i=0; i<length; i++)
-				{
-                if ((i%2)==0)  //  even
-                    {
-                    switch(parsedaddress.iTelNumber[i])
-                        {
-                        case '*':
-                            {
-                            octet=10; // 1010 as a binary, according to 23.040 …
-                            }
-                            break;
-
-                        case '#':
-                            {
-                            octet=11; // 1011 as a binary, according to 23.040…
-                            }
-                            break; 
-
-                        case 'a':
-                            {
-                            octet=12; // 1100 as a binary, according to 23.040...
-                            }
-                            break;
-
-                        case 'b':
-                            {
-                            octet=13; // 1101 as a binary, according to 23.040…
-                            }
-                            break;
-
-                        case 'c':
-                            {
-                            octet=14; // 1110 as a binary, according to 23.040…
-                            }
-                            break;
-
-                        default:
-                            octet=(parsedaddress.iTelNumber[i])-'0';
-                            break;
-                        }
-                    } 
-                else
-                    {
-                    TInt tempOctet = 0;
-       
-                    switch(parsedaddress.iTelNumber[i])
-                        {
-                        case '*':
-                            {
-                            tempOctet=10; // 1010 as a binary, according to 23.040…
-                            }
-                            break;
-
-                        case '#':
-                            {
-                            tempOctet=11; // 1011 as a binary, according to 23.040…
-                            }
-                            break;
-
-                        case 'a':
-                            {
-                            tempOctet=12; // 1100 as a binary, according to 23.040…
-                            }
-                            break;
-
-                        case 'b':
-                            {
-                            tempOctet=13; // 1101 as a binary, according to 23.040…
-                            }
-                            break;
-
-                        case 'c':
-                            {
-                            tempOctet=14; // 1110 as a binary, according to 23.040…
-                            }
-                            break;
-
-                        default:
-                            tempOctet=(parsedaddress.iTelNumber[i])-'0';
-                            break;
-                        }
-                    octet=octet|tempOctet<<4;
-                    aPtr=octet.EncodeL(aPtr);				
-				    }
-                
-			    } // end for loop
-
-			if (length%2)   // odd number of semioctets
-				{
-				octet=octet|0xF0;
-				aPtr=octet.EncodeL(aPtr);
-				}
-						
-		    } // end default case
-	    }
-	return aPtr;
-	}
-
-
-void CSmsAddress::DecodeL(TGsmuLex8& aPdu)
-	{
-	TSmsOctet length;  //represents the number of valid semi-octets
-	length.DecodeL(aPdu);
-	iTypeOfAddress.DecodeL(aPdu);
-
-	switch (iTypeOfAddress.TON())
-		{
-		case EGsmSmsTONAlphaNumeric:
-			{
-			const TUint cphs1 = aPdu.GetL();
-			const TUint cphs2 = aPdu.GetL();
-			aPdu.UnGet();
-			aPdu.UnGet();
-
-			const TPtrC8 remainder(aPdu.Remainder());
-			// we assume that it is a cphs message waiting indicator
-            // we might want to do further tests tobe sure that it is a CPHS message
-			if(    (length==4)
-				&& ((cphs1 & 0x7E) == 0x10) // x001 000x constant value
-				&& ((cphs2 & 0x7E) == 0x00) // x000 000x constant value
-			  )
-				{
-				TGsmSmsTelNumber parsedaddress;
-				parsedaddress.iTelNumber.SetLength(length);
-				//Copy the two bytes of the cphs message waiting address into the parsed address
-				parsedaddress.iTelNumber[0]=(TUint8)length;
-				parsedaddress.iTelNumber[1]= (TUint8)iTypeOfAddress;
-				parsedaddress.iTelNumber[2]= (TUint8)aPdu.GetL();
-				parsedaddress.iTelNumber[3]= (TUint8)aPdu.GetL();
-				DoSetParsedAddressL(parsedaddress.iTelNumber);
-				}
-			else if(length==11 && remainder.Left(6).CompareF(KMOSES) ==KErrNone ) //check for MOSES
-				{
-					DoSetParsedAddressL(KNETWORK);
-					aPdu.IncL(6);
-				}
-			else
-				{
-				// Encoded length is number of semi-octets used to store address using
-				// 7-bit char set - determine number of user data units required
-				const TInt numUDUnits=length*4/7;
-				// Unpack the data - assume max converted length twice the unconverted length
-				// VEP Why this assumption, the length will be doubled at the client because of that??
-				// EXT-568BMW
-				// Fix is not to multiply by 2
-				//NewBufferL(2*numUDUnits);
-				NewBufferL(numUDUnits);
-				TPtr unpackedPtr((TText*)iBuffer->Des().Ptr(),0,iBuffer->Length());
-
-				if (remainder.Length() < KSmsAddressMaxAddressValueLength)
-					User::Leave(KErrGsmuDecoding);
-
-				TPtrC8 packedPtr(remainder.Ptr(), KSmsAddressMaxAddressValueLength);
-				TSmsAlphabetPacker unpacker(TSmsDataCodingScheme::ESmsAlphabet7Bit,EFalse,0);
-				unpacker.UnpackAndConvertL(iCharacterSetConverter,iFs,packedPtr,unpackedPtr,numUDUnits);
-				aPdu.IncL(length / 2);
-				if ((length % 2) != 0)
-					aPdu.IncL();
-				}
-			break;
-			}
-		case EGsmSmsTONInternationalNumber:
-		default:
-			{
-			TGsmSmsTelNumber parsedaddress;
-			if (length>parsedaddress.iTelNumber.MaxLength())
-				User::Leave(KErrGsmuDecoding);
-			parsedaddress.iTelNumber.SetLength(length);
-			TSmsOctet octet;
-			for (TInt i=0; i<length; i++)
-				{
-				if ((i%2)==0)  //  even
-					{
-                    TUint8 tempOctet = 0;
-                    octet.DecodeL(aPdu);
-                    tempOctet = (TUint8)octet&0x0F; // four topmost bits set to zero
-                    
-                    switch(tempOctet)
-                        {
-                        case 10: // 1010
-                            {
-                            parsedaddress.iTelNumber[i] = '*';
-                            }
-                            break;
-
-                        case 11: // 1011
-                            {
-                            parsedaddress.iTelNumber[i] = '#';
-                            }
-                            break; 
-
-                        case 12: // 1100
-                            {
-                            parsedaddress.iTelNumber[i] = 'a';
-                            }
-                            break;
-
-                        case 13: //1101
-                            {
-                            parsedaddress.iTelNumber[i] = 'b'; 
-                            }
-                            break;
-
-                        case 14: //1110
-                            {
-                            parsedaddress.iTelNumber[i] = 'c';
-                            }
-                            break;
-
-                        case 15: 
-                            // Skip if 1111 is received 
-                            break;
-
-                        default:
-                            parsedaddress.iTelNumber[i]=(TUint8) (tempOctet+'0');
-                            break;
-                        }
-					}
-				else
-                    {
-                    TUint8 tempOctet = 0;
-                    octet&0xF0; // four least significant bits…
-                    tempOctet = (TUint8)octet>>4;
-
-                    switch(tempOctet)
-                        {
-                        case 10: // 1010
-                            {
-                            parsedaddress.iTelNumber[i] = '*';
-                            }
-                            break;
-
-                        case 11: // 1011
-                            {
-                            parsedaddress.iTelNumber[i] = '#';
-                            }
-                            break;
-
-                        case 12: // 1100
-                            {
-                            parsedaddress.iTelNumber[i] = 'a';
-                            }
-                            break;
-
-                        case 13: // 1101
-                            {
-                            parsedaddress.iTelNumber[i] = 'b';
-                            }
-                            break;
-
-                        case 14: // 1110
-                            {
-                            parsedaddress.iTelNumber[i] = 'c';
-                            }
-                            break;
-
-                        case 15: 
-                            // Skip if 1111 is received 
-                            break;
-
-                        default:
-                            parsedaddress.iTelNumber[i]=(TUint8) (tempOctet+'0'); 
-                            // unwanted bits zeroed in the beginning
-       
-                            break;
-                        }
-                    }
-				}
-			DoSetParsedAddressL(parsedaddress.iTelNumber);
-			}
-		}
-	}
-
-void CSmsAddress::InternalizeL(RReadStream& aStream)
-	{
-	aStream >> iTypeOfAddress;
-	HBufC* buffer=HBufC::NewL(aStream,256);
-	delete iBuffer;
-	iBuffer=buffer;
-	} // CSmsAddress::InternalizeL
-
-
-void CSmsAddress::ExternalizeL(RWriteStream& aStream) const
-	{
-	aStream << iTypeOfAddress;
-	aStream << *iBuffer;
-	} // CSmsAddress::ExternalizeL
-
-
-CSmsAddress::CSmsAddress(CCnvCharacterSetConverter& aCharacterSetConverter,RFs& aFs):
-	iCharacterSetConverter(aCharacterSetConverter),
-	iFs(aFs),
-	iTypeOfAddress(EGsmSmsTONUnknown, EGsmSmsNPIISDNTelephoneNumberingPlan)
-	{
-	} // CSmsAddress::CSmsAddress
-
-
-void CSmsAddress::NewBufferL(TInt aLength)
-	{
-	LOGGSMU1("CSmsAddress::NewBufferL()");
-
-    HBufC* buffer=HBufC::NewL(aLength);
-    delete iBuffer;
-    iBuffer=buffer;
-    iBuffer->Des().SetLength(aLength);
-    iBuffer->Des().FillZ();
-	}
-
-
-void CSmsAddress::DoSetParsedAddressL(const TDesC& aAddress)
-	{
-	LOGGSMU2("CSmsAddress::DoSetParsedAddressL() the length of the Address [Length = %d", aAddress.Length());
-
-	TInt length=aAddress.Length();
-	if ((iTypeOfAddress.TON()==EGsmSmsTONInternationalNumber) &&
-	    (length && (aAddress[0]!='+')))
-		{
-		NewBufferL(length+1);
-		iBuffer->Des()[0]='+';
-		TPtr ptr((TText*) (iBuffer->Des().Ptr()+1),length,length);
-		ptr.Copy(aAddress);
-		}
-	else
-		{
-		NewBufferL(length);
-		iBuffer->Des().Copy(aAddress);
-		}
-	} // CSmsAddress::DoSetParsedAddressL
-
-
-TSmsServiceCenterTimeStamp::TSmsServiceCenterTimeStamp()
-	{
-	iTimeZoneNumQuarterHours = 0;
-	} // TSmsServiceCenterTimeStamp::TSmsServiceCenterTimeStamp
-
-
-void TSmsServiceCenterTimeStamp::SetTimeOffset(TInt aNumQuarterHours)
-	{
-	__ASSERT_DEBUG((aNumQuarterHours>=-KSmsMaxTimeZoneNumQuarterHours) && (aNumQuarterHours<=KSmsMaxTimeZoneNumQuarterHours),Panic(KGsmuPanicNumQuarterHoursOutOfRange));
-	iTimeZoneNumQuarterHours=aNumQuarterHours;
-	} // TSmsServiceCenterTimeStamp::SetTimeOffset
-
-
-TUint8* TSmsServiceCenterTimeStamp::EncodeL(TUint8* aPtr) const
-    {
-    LOGGSMU1("TSmsServiceCenterTimeStamp::EncodeL()");
-
-    TInt numquarterhours=iTimeZoneNumQuarterHours;
-
-    TInt timeZoneOffsetInSeconds = numquarterhours * CSmsMessage::E15MinutesRepresentedInSeconds;
-    TTimeIntervalSeconds offsetFromUTCToLocal(timeZoneOffsetInSeconds);
-
-    TTime time = iTime;
-    time += offsetFromUTCToLocal;
-
-    TDateTime datetime=time.DateTime();
-
-    TSmsOctet octet;
-    octet.FillSemiOctets(datetime.Year()%100);
-    aPtr=octet.EncodeL(aPtr);
-    octet.FillSemiOctets(datetime.Month()+1);
-    aPtr=octet.EncodeL(aPtr);
-    octet.FillSemiOctets(datetime.Day()+1);
-    aPtr=octet.EncodeL(aPtr);
-    octet.FillSemiOctets(datetime.Hour());
-    aPtr=octet.EncodeL(aPtr);
-    octet.FillSemiOctets(datetime.Minute());
-    aPtr=octet.EncodeL(aPtr);
-    octet.FillSemiOctets(datetime.Second());
-    aPtr=octet.EncodeL(aPtr);
-
-    TInt signbit=ESmsTimeZonePositive;
-    if (numquarterhours<0)
-        {
-        numquarterhours=-numquarterhours;
-        signbit=ESmsTimeZoneNegative;
-        }
-
-    TSmsOctet timezone;
-    timezone.FillSemiOctets(numquarterhours);
-    timezone=timezone|signbit;
-    return timezone.EncodeL(aPtr);
-    } // TSmsServiceCenterTimeStamp::EncodeL
-
-
-void TSmsServiceCenterTimeStamp::DecodeL(TGsmuLex8& aPdu, TInt& aTimeError)
-	{
-	LOGGSMU1("TSmsServiceCenterTimeStamp::DecodeL()");
-
-	TSmsOctet octet;
-	octet.DecodeL(aPdu);
-	TInt year=octet.SemiOctetsToNum();
-	if (year>95)
-		year+=1900;
-	else
-		year+=2000;
-	octet.DecodeL(aPdu);
-	TInt month=octet.SemiOctetsToNum();
-	octet.DecodeL(aPdu);
-
-	TInt day=octet.SemiOctetsToNum();
-	octet.DecodeL(aPdu);
-	TInt hour=octet.SemiOctetsToNum();
-	octet.DecodeL(aPdu);
-	TInt minute=octet.SemiOctetsToNum();
-	octet.DecodeL(aPdu);
-	TInt second=octet.SemiOctetsToNum();
-
-    TDateTime datetime;
-    aTimeError = datetime.Set(year,(TMonth) (month-1),day-1,hour,minute,second,0);
-
-    TSmsOctet timezone;
-    timezone.DecodeL(aPdu);
-
-    TInt signBit = (timezone&ESmsTimeZoneSignBitMask) ?  ESmsTimeZoneNegative : ESmsTimeZonePositive;
-    timezone=timezone &(~ESmsTimeZoneSignBitMask); // clear sign bit
-
-    TInt offsetToUTCInSeconds = 0;
-    if (timezone.SemiOctetsToNum() <= KSmsMaxTimeZoneNumQuarterHours)
-        {
-        offsetToUTCInSeconds = ((TInt) timezone.SemiOctetsToNum()) * CSmsMessage::E15MinutesRepresentedInSeconds;
-        if (signBit == ESmsTimeZoneNegative)    
-            {
-            offsetToUTCInSeconds = -offsetToUTCInSeconds;
-            }
-
-        TTimeIntervalSeconds offsetToUTC(offsetToUTCInSeconds) ;      
-
-        if (aTimeError == KErrNone)
-            {
-            TTime time = datetime;    	
-            time -= offsetToUTC;
-            iTime = time;
-    	
-            iTimeZoneNumQuarterHours=(signBit == ESmsTimeZonePositive) ? timezone.SemiOctetsToNum(): -timezone.SemiOctetsToNum();
-            }
-            
-        }
-    else // Time zone out of range, set to 0 per 23.040 4.4.0 Section 9.2.3.11
-        {
-    	if (aTimeError == KErrNone)
-            {    		
-            iTime = datetime;    	
-    	    iTimeZoneNumQuarterHours=0;
-    	    }            
-        }
-	} // TSmsServiceCenterTimeStamp::DecodeL
-
-
-void TSmsServiceCenterTimeStamp::InternalizeL(RReadStream& aStream)
-	{
-	TInt64 time;
-	aStream >> time;
-	iTime=time;
-	iTimeZoneNumQuarterHours=aStream.ReadInt32L();
-	} // TSmsServiceCenterTimeStamp::InternalizeL
-
-
-void TSmsServiceCenterTimeStamp::ExternalizeL(RWriteStream& aStream) const
-	{
-	aStream << iTime.Int64();
-	aStream.WriteInt32L(iTimeZoneNumQuarterHours);
-	} // TSmsServiceCenterTimeStamp::ExternalizeL
-
-
-TSmsValidityPeriod::TSmsValidityPeriod(TSmsFirstOctet& aFirstOctet):
-	iFirstOctet(aFirstOctet),
-	iTimeIntervalMinutes(EOneDayUnitInMinutes)
-	{
-	} // TSmsValidityPeriod::TSmsValidityPeriod
-
-
-TTime TSmsValidityPeriod::Time() const
-	{
-	LOGGSMU1("TSmsValidityPeriod::Time()");
-
-	TTime time;
-	time.UniversalTime();
-	time+=iTimeIntervalMinutes;
-	return time;
-	} // TSmsValidityPeriod::Time
-
-
-TUint8* TSmsValidityPeriod::EncodeL(TUint8* aPtr) const
-	{
-	LOGGSMU1("TSmsValidityPeriod::EncodeL()");
-
-	TInt validityperiodformat=ValidityPeriodFormat();
-	switch (validityperiodformat)
-		{
-		case (TSmsFirstOctet::ESmsVPFNone):
-			break;
-		case (TSmsFirstOctet::ESmsVPFInteger):
-			{
-			TInt timeintervalminutes=iTimeIntervalMinutes.Int();
-			__ASSERT_DEBUG((timeintervalminutes>=EFiveMinuteUnitInMinutes) && (timeintervalminutes<=63*EOneWeekUnitLimitInMinutes),Panic(KGsmuPanicValidityPeriodOutOfRange));
-			TSmsOctet octet;
-			if (timeintervalminutes<=EFiveMinuteUnitLimitInMinutes)
-                octet=((timeintervalminutes/EFiveMinuteUnitInMinutes)-1);
-			else if (timeintervalminutes<=EHalfHourUnitLimitInMinutes)
-                octet=(((timeintervalminutes-(EHalfHourUnitLimitInMinutes/2))/EHalfHourUnitInMinutes)+EFiveMinuteUnitLimit);
-
-			else if (timeintervalminutes<=EOneDayUnitLimitInMinutes)
-                octet=((timeintervalminutes/EOneDayUnitInMinutes)+166);
-			else
-                octet=((timeintervalminutes/EOneWeekUnitInMinutes)+192);
-
-			aPtr=octet.EncodeL(aPtr);
-			break;
-			}
-		case (TSmsFirstOctet::ESmsVPFSemiOctet):
-			{
-			TSmsServiceCenterTimeStamp timestamp;
-			timestamp.SetTime(Time());
-
-	 		TTimeIntervalSeconds timeIntervalInSeconds(User::UTCOffset());
-			timestamp.SetTimeOffset(timeIntervalInSeconds.Int() / CSmsMessage::E15MinutesRepresentedInSeconds);
-
-			aPtr=timestamp.EncodeL(aPtr);
-			break;
-			}
-		default:
-            __ASSERT_DEBUG(EFalse,Panic(KGsmuPanicUnsupportedValidityPeriodFormat));
-			User::Leave(KErrGsmSMSTPVPFNotSupported);
-            break;
-		};
-	return aPtr;
-	} // TSmsValidityPeriod::EncodeL
-	
-TUint8* TSmsValidityPeriod::EncodeL(TUint8* aPtr, const TEncodeParams* aEncodeParams) const
-	{
-	LOGGSMU1("TSmsValidityPeriod::EncodeL()");
-
-	TInt validityperiodformat=ValidityPeriodFormat();
-	switch (validityperiodformat)
-		{
-		case (TSmsFirstOctet::ESmsVPFNone):
-			break;
-		case (TSmsFirstOctet::ESmsVPFInteger):
-			{
-			TInt timeintervalminutes=iTimeIntervalMinutes.Int();
-			__ASSERT_DEBUG((timeintervalminutes>=EFiveMinuteUnitInMinutes) && (timeintervalminutes<=63*EOneWeekUnitLimitInMinutes),Panic(KGsmuPanicValidityPeriodOutOfRange));
-			TSmsOctet octet;
-			if (timeintervalminutes<=EFiveMinuteUnitLimitInMinutes)
-                octet=((timeintervalminutes/EFiveMinuteUnitInMinutes)-1);
-			else if (timeintervalminutes<=EHalfHourUnitLimitInMinutes)
-                octet=(((timeintervalminutes-(EHalfHourUnitLimitInMinutes/2))/EHalfHourUnitInMinutes)+EFiveMinuteUnitLimit);
-
-			else if (timeintervalminutes<=EOneDayUnitLimitInMinutes)
-                octet=((timeintervalminutes/EOneDayUnitInMinutes)+166);
-			else
-                octet=((timeintervalminutes/EOneWeekUnitInMinutes)+192);
-
-			aPtr=octet.EncodeL(aPtr);
-			break;
-			}
-		case (TSmsFirstOctet::ESmsVPFSemiOctet):
-			{			
-			//The reason TSmsValidityPeriod::EncodeL(TUint8* aPtr, const TEncodeParams* aEncodeParams) was
-			//created was to allow the CSmsMessage's time stamp to be used when generating the validity time.
-			//The CSmsMessage's time stamp is typically created when the message is constructed by the SMS Stack client.
-			//This means the validity time is based from the point the SMS Stack client actually sends the message, rather
-			//than the SMS Stack encodes it
-						
-			TSmsServiceCenterTimeStamp timestamp;
-			timestamp.SetTime( *aEncodeParams->iTimeStamp + iTimeIntervalMinutes ); 									    		    		    		    		    
-
-	 		TTimeIntervalSeconds timeIntervalInSeconds( *aEncodeParams->iTimeIntervalInSeconds );
-			timestamp.SetTimeOffset(timeIntervalInSeconds.Int() / CSmsMessage::E15MinutesRepresentedInSeconds);
-
-			aPtr=timestamp.EncodeL(aPtr);
-			break;
-			}
-		default:
-            __ASSERT_DEBUG(EFalse,Panic(KGsmuPanicUnsupportedValidityPeriodFormat));
-			User::Leave(KErrGsmSMSTPVPFNotSupported);
-            break;
-		};
-	return aPtr;
-	} // TSmsValidityPeriod::EncodeL	
-
-void TSmsValidityPeriod::DecodeL(TGsmuLex8& aPdu)
-	{
-	LOGGSMU1("TSmsValidityPeriod::DecodeL()");
-
-	TInt validityperiodformat=ValidityPeriodFormat();
-	switch (validityperiodformat)
-		{
-		case (TSmsFirstOctet::ESmsVPFNone):
-			break;
-		case (TSmsFirstOctet::ESmsVPFInteger):
-			{
-			TSmsOctet octet;
-			octet.DecodeL(aPdu);
-            if (octet<=EFiveMinuteUnitLimit)
-                iTimeIntervalMinutes=(octet+1)*EFiveMinuteUnitInMinutes;
-			else if (octet<=EHalfHourUnitLimit)
-                iTimeIntervalMinutes=((EOneDayUnitInMinutes/2)+((octet-EFiveMinuteUnitLimit)*EHalfHourUnitInMinutes));
-			else if (octet<=EOneDayUnitLimit)
-                iTimeIntervalMinutes=(octet-166)*EOneDayUnitInMinutes;
-			else
-                iTimeIntervalMinutes=(octet-192)*EOneWeekUnitInMinutes;
-			break;
-			}
-		case (TSmsFirstOctet::ESmsVPFSemiOctet):
-			{
-			TSmsServiceCenterTimeStamp timestamp;
-			TInt timeError;
-			timestamp.DecodeL(aPdu, timeError);
-			User::LeaveIfError(timeError);
-			TTime time;
-			time.UniversalTime();
-			timestamp.Time().MinutesFrom(time,iTimeIntervalMinutes);
-			break;
-			}
-		default:
-            __ASSERT_DEBUG(EFalse,Panic(KGsmuPanicUnsupportedValidityPeriodFormat));
-			User::Leave(KErrGsmSMSTPVPFNotSupported);
-            break;
-		};
-	} // TSmsValidityPeriod::DecodeL
-
-
-void TSmsValidityPeriod::InternalizeL(RReadStream& aStream)
-	{
-	TInt timeintervalinminutes=aStream.ReadInt32L();
-	iTimeIntervalMinutes=timeintervalinminutes;
-	} // TSmsValidityPeriod::InternalizeL
-
-
-void TSmsValidityPeriod::ExternalizeL(RWriteStream& aStream) const
-	{
-	aStream.WriteInt32L(iTimeIntervalMinutes.Int());
-	} // TSmsValidityPeriod::ExternalizeL
-
-
-CSmsInformationElement* CSmsInformationElement::NewL(TSmsInformationElementIdentifier aIdentifier,const TDesC8& aData)
-	{
-	LOGGSMU1("CSmsInformationElement::NewL()");
-
-	CSmsInformationElement* informationelement=new(ELeave) CSmsInformationElement(aIdentifier);
-	CleanupStack::PushL(informationelement);
-	informationelement->ConstructL(aData);
-	CleanupStack::Pop();
-	return informationelement;
-	} // CSmsInformationElement::NewL
-
-
-CSmsInformationElement* CSmsInformationElement::NewL()
-	{
-	LOGGSMU1("CSmsInformationElement::NewL()");
-
-	CSmsInformationElement* informationelement=new(ELeave) CSmsInformationElement(ESmsIEIConcatenatedShortMessages8BitReference);
-	CleanupStack::PushL(informationelement);
-	TPtrC8 data;
-	informationelement->ConstructL(data);
-	CleanupStack::Pop();
-	return informationelement;
-	} // CSmsInformationElement::NewL
-
-
-/**
- *  Destructor.
- */
-CSmsInformationElement::~CSmsInformationElement()
-	{
-	delete iData;
-	} // CSmsInformationElement::NewL
-
-
-/**
- *  Gets the Information Element data.
- *  
- *  @return Information Element data
- *  @capability None
- */
-EXPORT_C TPtr8 CSmsInformationElement::Data()
-	{
-	LOGGSMU1("CSmsInformationElement::Data()");
-
-	return iData->Des();
-	} // CSmsInformationElement::Data
-
-
-/**
- *  Gets the (const) Information Element data.
- *  
- *  @return Information Element data
- *  @capability None
- */
-EXPORT_C const TDesC8& CSmsInformationElement::Data() const
-	{
-	LOGGSMU1("CSmsInformationElement::Data()");
-
-	return *iData;
-	} // CSmsInformationElement::Data
-
-
-/**
- *  Gets the Information Element Identifier.
- *  
- *  @return Information Element Identifier
- *  @capability None
- */
-EXPORT_C CSmsInformationElement::TSmsInformationElementIdentifier CSmsInformationElement::Identifier() const
-	{
-	return TSmsId(TInt(iIdentifier));
-	} // CSmsInformationElement::TSmsInformationElementIdentifier
-
-
-TUint8* CSmsInformationElement::EncodeL(TUint8* aPtr) const
-	{
-	LOGGSMU1("CSmsInformationElement::EncodeL()");
-
-	TSmsOctet id=iIdentifier;
-	aPtr=id.EncodeL(aPtr);
-	TSmsOctet informationelementlength=iData->Des().Length();
-	aPtr=informationelementlength.EncodeL(aPtr);
-	Mem::Copy(aPtr,iData->Des().Ptr(),informationelementlength);
-	aPtr+=TInt(informationelementlength);
-	return aPtr;
-	} // CSmsInformationElement::EncodeL
-
-
-void CSmsInformationElement::DecodeL(TGsmuLex8& aPdu)
-	{
-	LOGGSMU1("CSmsInformationElement::DecodeL()");
-
-	TSmsOctet id;
-	id.DecodeL(aPdu);
-	iIdentifier=static_cast<TSmsInformationElementIdentifier>((TInt)id);
-
-	TSmsOctet informationelementlength;
-	informationelementlength.DecodeL(aPdu);
-
- 	switch(iIdentifier)
- 	{
- 	case (ESmsIEIConcatenatedShortMessages8BitReference):
- 		if(informationelementlength !=3)
- 			User::Leave(KErrGsmSMSTpduNotSupported);
- 		break;
- 	case (ESmsIEISpecialSMSMessageIndication):
- 		if(informationelementlength !=2)
- 			User::Leave(KErrGsmSMSTpduNotSupported);
- 		break;
- 	case (ESmsIEIApplicationPortAddressing8Bit):
- 		if(informationelementlength !=2)
- 			User::Leave(KErrGsmSMSTpduNotSupported);
- 		break;
- 	case (ESmsIEIApplicationPortAddressing16Bit):
- 		if(informationelementlength !=4)
- 			User::Leave(KErrGsmSMSTpduNotSupported);
- 		break;
- 	case (ESmsIEISMSCControlParameters):
- 		if(informationelementlength !=1)
- 			User::Leave(KErrGsmSMSTpduNotSupported);
- 		break;
- 	case (ESmsIEIUDHSourceIndicator):
- 		if(informationelementlength !=1)
- 			User::Leave(KErrGsmSMSTpduNotSupported);
- 		break;
- 	case (ESmsIEIConcatenatedShortMessages16BitReference):
- 		if(informationelementlength !=4)
- 			User::Leave(KErrGsmSMSTpduNotSupported);
- 		break;
- 	case (ESmsIEIRFC822EmailHeader):
- 		if(informationelementlength !=1)
- 			User::Leave(KErrGsmSMSTpduNotSupported);
- 		break;
-  	case (ESmsHyperLinkFormat):
- 		if(informationelementlength !=4)
- 			User::Leave(KErrGsmSMSTpduNotSupported);
- 		break;
-  	case (ESmsNationalLanguageSingleShift):
- 		if(informationelementlength != 1)
- 			User::Leave(KErrGsmSMSTpduNotSupported);
- 		break;
-  	case (ESmsNationalLanguageLockingShift):
- 		if(informationelementlength != 1)
- 			User::Leave(KErrGsmSMSTpduNotSupported);
- 		break;
- 	case (ESmsIEISIMToolkitSecurityHeaders1):
- 	case (ESmsIEISIMToolkitSecurityHeaders2):
- 	case (ESmsIEISIMToolkitSecurityHeaders3):
- 	case (ESmsIEISIMToolkitSecurityHeaders4):
- 	case (ESmsIEISIMToolkitSecurityHeaders5):
- 	case (ESmsIEISIMToolkitSecurityHeaders6):
- 	case (ESmsIEISIMToolkitSecurityHeaders7):
- 	case (ESmsIEISIMToolkitSecurityHeaders8):
- 	case (ESmsIEISIMToolkitSecurityHeaders9):
- 	case (ESmsIEISIMToolkitSecurityHeaders10):
- 	case (ESmsIEISIMToolkitSecurityHeaders11):
- 	case (ESmsIEISIMToolkitSecurityHeaders12):
- 	case (ESmsIEISIMToolkitSecurityHeaders13):
- 	case (ESmsIEISIMToolkitSecurityHeaders14):
- 	case (ESmsIEISIMToolkitSecurityHeaders15):
- 	case (ESmsIEISIMToolkitSecurityHeaders16):
- 	if(informationelementlength !=0)
- 			User::Leave(KErrGsmSMSTpduNotSupported);
- 		break;
- 	default:
- 		break;
- 	}
-
-	const TPtrC8 data(aPdu.NextAndIncL(informationelementlength));
-	NewDataL(informationelementlength);
-	TPtr8 ptr(iData->Des());
-	ptr.Copy(data);
-	} // CSmsInformationElement::DecodeL
-
-
-void CSmsInformationElement::InternalizeL(RReadStream& aStream)
-	{
-	TSmsOctet id;
-	aStream >> id;
-	iIdentifier=static_cast<TSmsInformationElementIdentifier>((TInt)id);
-	delete iData;
-	iData=NULL;
-	iData=HBufC8::NewL(aStream,CSmsUserData::KSmsMaxUserDataSize);
-	} // CSmsInformationElement::InternalizeL
-
-
-void CSmsInformationElement::ExternalizeL(RWriteStream& aStream) const
-	{
-	TSmsOctet id;
-	id=(TInt)iIdentifier;
-	aStream << id;
-	aStream << *iData;
-	} // CSmsInformationElement::ExternalizeL
-
-
-void CSmsInformationElement::ConstructL(const TDesC8& aData)
-	{
-	LOGGSMU1("CSmsInformationElement::ConstructL()");
-
-	NewDataL(aData.Length());
-	iData->Des().Copy(aData);
-	} // CSmsInformationElement::ConstructL
-
-
-void CSmsInformationElement::NewDataL(TInt aLength)
-	{
-	LOGGSMU1("CSmsInformationElement::NewDataL()");
-
-	HBufC8* data=HBufC8::NewL(aLength);
-	delete iData;
-	iData=data;
-	iData->Des().SetLength(aLength);
-	} // CSmsInformationElement::NewDataL
-
-
-TUint CSmsInformationElement::Length()const
-	{
-	LOGGSMU1("CSmsInformationElement::Length()");
-
-	return 2+iData->Length();  // 2 stands for IEID and IEDL
-	} // CSmsInformationElement::Length
-
-
-/**
- *  @internalComponent
- *  
- *  This method maps an information element to an index into an array of categories.
- *  
- *  @param aId
- *  The information Element Identifier.
- *  @param aIndex
- *  The index into the array of categories
- *  @return
- *  True if the information element can be mapped.
- *  False otherwise.
- */
-TBool TSmsInformationElementCategories::TranslateCategoryToIndex(TInformationElementId aId, TInt& aIndex)
-    {
-    LOGGSMU1("CSmsMessage::TranslateCategoryToIndex");
-
-    TBool rc = ETrue;
-
-    if (aId < CSmsInformationElement::ESmsIEMaximum)
-        {
-        switch (aId)
-            {
-            case CSmsInformationElement::ESmsIEIConcatenatedShortMessages8BitReference:
-            case CSmsInformationElement::ESmsIEIConcatenatedShortMessages16BitReference:
-            case CSmsInformationElement::ESmsIEISMSCControlParameters:
-            case CSmsInformationElement::ESmsIEIRFC822EmailHeader:
-                {
-                aIndex = EIndexCtrlMandatoryInEveryPDUButWithValueSpecificToPDU;
-                break;
-                }
-            case CSmsInformationElement::ESmsIEISpecialSMSMessageIndication:
-                {
-                aIndex = EIndexCtrlMandatoryInEveryPDUMultipleInstancesPerPDU;
-                break;
-                }
-            case CSmsInformationElement::ESmsHyperLinkFormat:
-                {
-                aIndex = EIndexCtrlMultipleInstancesAllowed;
-                break;
-                }
-            case CSmsInformationElement::ESmsNationalLanguageSingleShift:
-            case CSmsInformationElement::ESmsNationalLanguageLockingShift:
-                {
-                aIndex = EIndexCtrlOptionalInEveryPDUWithValueSpecificToPDU;
-                break;
-                }
-            case CSmsInformationElement::ESmsReplyAddressFormat:
-                {
-                aIndex = EIndexCtrlMandatoryIn1stPDUOnly;
-                break;
-                }
-            case CSmsInformationElement::ESmsEnhanceVoiceMailInformation:
-                {
-                aIndex = EIndexCtrlSingleInstanceOnly;
-                break;
-                }
-            case CSmsInformationElement::ESmsEnhancedTextFormatting:
-            case CSmsInformationElement::ESmsEnhancedPredefinedSound:
-            case CSmsInformationElement::ESmsEnhancedUserDefinedSound:
-            case CSmsInformationElement::ESmsEnhancedPredefinedAnimation:
-            case CSmsInformationElement::ESmsEnhancedLargeAnimation:
-            case CSmsInformationElement::ESmsEnhancedSmallAnimation:
-            case CSmsInformationElement::ESmsEnhancedLargePicture:
-            case CSmsInformationElement::ESmsEnhancedSmallPicture:
-            case CSmsInformationElement::ESmsEnhancedVariablePicture:
-            case CSmsInformationElement::ESmsEnhancedUserPromptIndicator:
-            case CSmsInformationElement::ESmsEnhancedExtendedObject:
-            case CSmsInformationElement::ESmsEnhancedReusedExtendedObject:
-            case CSmsInformationElement::ESmsEnhancedCompressionControl:
-            case CSmsInformationElement::ESmsEnhancedODI:
-            case CSmsInformationElement::ESmsEnhancedStandardWVG:
-            case CSmsInformationElement::ESmsEnhancedCharacterSizeWVG:
-            case CSmsInformationElement::ESmsEnhancedextendedObjectDataRequest:
-                {
-                aIndex = EIndexEmsInformationElement;
-                break;
-                }
-            case CSmsInformationElement::ESmsIEIReserved:
-            case CSmsInformationElement::ESmsIEIValueNotUsed:
-                {
-                rc = EFalse;
-                break;
-                }
-            default:
-                {
-                aIndex = EIndexCtrlMandatoryInEveryPDUAndWithIdenticalValues;
-                break;
-                }
-            }
-        }
-    else
-        {
-        rc = EFalse;
-        LOGGSMU3("CSmsMessage::TranslateCategoryToIndex id = %d, found = %d", aId, rc);
-        }
-    return rc;
-    } // TSmsInformationElementCategories::TranslateCategoryToIndex
-
-
-/**
- *  @internalComponent
- *  
- *  This method gets an information element identifier's category.
- *  
- *  @param aId
- *  The information Element Identifier.
- *  @param aCategory
- *  The category of information element.
- *  @return
- *  ETrue if successful, EFalse if an information identifier is unknown or cannot
- *  be mapped.
- */
-TBool TSmsInformationElementCategories::GetCategoryDefinition(TInformationElementId aId, TInformationElementCategory& aCategory)
-    {
-    LOGGSMU1("TSmsInformationElementCategories::GetCategoryDefinition");
-    TInt index;
-
-    if (TranslateCategoryToIndex(aId,index))
-        {
-        aCategory = categories[index];
-        }
-    else
-        {
-        LOGGSMU2("TSmsInformationElementCategories::GetCategoryDefinition, Failure, aId = %d", aId);
-        return EFalse;
-        }
-
-    return ETrue;
-    } // TSmsInformationElementCategories::GetCategoryDefinition
-
-
-const TSmsInformationElementCategories::TInformationElementCategory TSmsInformationElementCategories::categories[TSmsInformationElementCategories::ENumberOfIndices] =
-    {
-    TSmsInformationElementCategories::EEmsInformationElement,                           // EDefaultEMSIndex
-    TSmsInformationElementCategories::ECtrlMandatoryInEveryPDUAndWithIdenticalValues,   // EDefaultControlIndex
-    TSmsInformationElementCategories::ECtrlMandatoryInEveryPDUMultipleInstancesPerPDU,  // EIndexForSpecialSMSMessageIndication, Concatenated Short Messages
-    TSmsInformationElementCategories::ECtrlMandatoryInEveryPDUButWithValueSpecificToPDU,// EIndexForIRFC822EmailHeader, Application Port Addresses
-    TSmsInformationElementCategories::ECtrlMandatoryIn1stPDUOnly,                       // EIndexReplyAddressFormat
-    TSmsInformationElementCategories::ECtrlSingleInstanceOnly,                          // EIndexEnhanceVoiceMailInformation
-    TSmsInformationElementCategories::ECtrlMultipleInstancesAllowed                     // EIndexForHyperLinkFormat
-    };
-
-
-CSmsUserData* CSmsUserData::NewL(CCnvCharacterSetConverter& aCharacterSetConverter,RFs& aFs,TSmsFirstOctet& aFirstOctet,const TSmsDataCodingScheme& aDataCodingScheme)
-	{
-	LOGGSMU1("CSmsUserData::NewL()");
-
-	CSmsUserData* userdata=new(ELeave) CSmsUserData(aCharacterSetConverter,aFs,aFirstOctet,aDataCodingScheme);
-	CleanupStack::PushL(userdata);
-	userdata->ConstructL();
-	CleanupStack::Pop();
-	return userdata;
-	} // CSmsUserData::NewL
-
-
-/**
- *  Destructor.
- */
-CSmsUserData::~CSmsUserData()
-    {
-    iInformationElementArray.ResetAndDestroy();
-    delete iBody;
-    } // CSmsUserData::NewL
-
-
-/**
- *  Gets an information element by index.
- *  
- *  @param aIndex Index of the information element within the User Data
- *  @return Information element
- *  @capability None
- */
-EXPORT_C  CSmsInformationElement& CSmsUserData::InformationElement(TInt aIndex) const
-	{
-	LOGGSMU1("CSmsUserData::InformationElement()");
-
-	return *iInformationElementArray[aIndex];
-	} // CSmsUserData::InformationElement
-
-
-CSmsInformationElement*& CSmsUserData::InformationElementPtr(TInt aIndex)
-    {
-    LOGGSMU1("CSmsUserData::InformationElementPtr()");
-
-    return iInformationElementArray[aIndex];
-    } // CSmsUserData::InformationElementPtr
-
-
-/**
- *  Gets the index of an information element.
- *  
- *  @param aIdentifier An information element Identifier to search for
- *  @param aIndex The index within the User Data of the information element (if
- *  found). If more than 1 instance of this information element exists, then
- *  the 1st instance will be returned.
- *  
- *  Use InformationELementIndexL to get all elements.
- *  @return True if aIdentifier is found in the User Data
- *  @capability None
- */
-EXPORT_C TBool CSmsUserData::InformationElementIndex(CSmsInformationElement::TSmsInformationElementIdentifier aIdentifier,TInt& aIndex) const
-	{
-	LOGGSMU1("CSmsUserData::InformationElementIndex()");
-
-	TBool found=EFalse;
-	TInt count=NumInformationElements();
-	for (TInt i=0; (!found) && (i<count); i++)
-		if (InformationElement(i).Identifier()==aIdentifier)
-			{
-			found=ETrue;
-			aIndex=i;
-			}
-	return found;
-	} // CSmsUserData::InformationElementIndex
-
-
-/**
- *  Gets the last index of an information element.
- *  
- *  @param aIdentifier An information element Identifier to search for
- *  @param aIndex The index within the User Data of the information element (if
- *  found). If more than 1 instance of this information element exists, then
- *  the last instance will be returned.
- *  
- *  Use InformationELementIndexL to get all elements.
- *  @return True if aIdentifier is found in the User Data
- *  @capability None
- */
-EXPORT_C TBool CSmsUserData::InformationElementLastIndex(CSmsInformationElement::TSmsInformationElementIdentifier aIdentifier,TInt& aIndex) const
-	{
-	LOGGSMU1("CSmsUserData::InformationElementLastIndex()");
-
-	TBool found=EFalse;
-	TInt count=NumInformationElements();
-	for (TInt i=count-1; (!found) && (i>=0); i--)
-		if (InformationElement(i).Identifier()==aIdentifier)
-			{
-			found=ETrue;
-			aIndex=i;
-			}
-	return found;
-	} // CSmsUserData::InformationElementLastIndex
-
-
-/**
- *  @internalComponent
- *  
- *  Locates every information element of type aIdentifier and
- *  stores its location index in the output array aIndices.
- *  
- *  @param aIdentifer
- *  The information element Identifier to search for
- *  @param aIndices
- *  A collection containing the location index for each information element of this type.
- */
-void CSmsUserData::InformationElementIndicesL(CSmsInformationElement::TSmsInformationElementIdentifier aIdentifier, CArrayFixFlat<TInt>& aIndices) const
-    {
-    LOGGSMU1("CSmsUserData::InformationElementIndicesL()");
-
-    aIndices.Reset();
-    
-	TInt count=NumInformationElements();
-	for (TInt i=0; i<count; i++)
-	    {
-    	if (InformationElement(i).Identifier()==aIdentifier)
-            {
-            aIndices.AppendL(i);
-            }
-        }
-    } // CSmsUserData::InformationElementIndicesL
-
-
-/**
- *  Note that whilst a pointer to the aIe is passed as an
- *  input argument, the information element is still owned
- *  by the calling function, regardless of the return code.
- *  @param aInformationElement An EMS Information Element
- */
-TBool CSmsUserData::EmsInformationElementWillFitL(CEmsInformationElement* aIe,CSmsEMSBufferSegmenter& aSeg,TUint& aCharsAddedToCurrentPDU)
-	{
-	LOGGSMU1("CSmsUserData::EmsInformationElementWillFitL()");
-
-	// Before using an EmsInformationElement polymorphically as an SmsIE,
-	// we need to make sure that the IE has been encoded
-	aIe->EncodeInformationElementL();
-	iInformationElementArray.AppendL(aIe);
-
-	TInt sizeLeft=MaxPackedUDUnitsInBodyRemaining();
-	iInformationElementArray.Delete(iInformationElementArray.Count()-1);
-	if(sizeLeft==0 && iBody && (iBody->Length() > 0) && (*iBody)[iBody->Length()-1] == KSms7BitAlphabetEscapeChar)
-	{
-		--aCharsAddedToCurrentPDU;
-		--aSeg.iElementsExtracted;
-		TPtr8 ptr(iBody->Des());
-		ptr.Delete(iBody->Length()-1,1);
-		--sizeLeft;
-	}
-	return sizeLeft>=0;
-	} // CSmsUserData::EmsInformationElementWillFitL
-
-
-/**
- *  Tests whether the control information element will fit in the current PDU.
- *  
- *  Note that whilst a pointer to the aIe is passed as an
- *  input argument, the information element is still owned
- *  by the calling function, regardless of the return code.
- *  
- *  @param aInformationElement A pointer to an information Element
- *  @capability None
- */
-TBool CSmsUserData::ControlInformationElementWillFitL(CSmsInformationElement* aIe)
-    {
-    LOGGSMU1("CSmsUserData::ControlInformationElementWillFitL()");
-
-    if (aIe == NULL)
-        {
-        User::Leave(KErrGeneral);
-        }
-
-    TSmsInformationElementCategories::TInformationElementCategory category;
-
-    if (TSmsInformationElementCategories::GetCategoryDefinition(aIe->Identifier(), category) == EFalse  ||
-    	category == TSmsInformationElementCategories::EEmsInformationElement)
-        {
-        User::Leave(KErrArgument);
-        }
-
-    iInformationElementArray.AppendL(aIe);
-
-    TInt sizeLeft=MaxPackedUDUnitsInBodyRemaining();
-    iInformationElementArray.Delete(iInformationElementArray.Count()-1);
-
-    // Not considering whether escape characters exist in the buffer
-    // as control information elements do not add text to the buffer.
-
-    return sizeLeft>=0;
-    } // CSmsUserData::ControlInformationElementWillFitL
-
-
-/**
- *  Adds an information element.
- *  This method can be used to create information elements in the range:
- *  00 - 09 - i.e. Control Information Elements
- *  It can be used to create information elements in the following ranges
- *  (on the assumption that the information element is intended to be encoded into
- *  every PDU):
- *  24 - 25 - i.e. National Language Encodings
- *  70 - 7F - i.e. SIM Tool Kit Security Headers
- *  80 - 9F - i.e  SMS to SME specific use
- *  C0 - CF - i.e. SC specific use
- *  
- *  Information elements in the following ranges should not be
- *  added using this interface. Instead they should be added using
- *  the following identified interfaces:
- *  0A-1F - Use the interfaces provided to support EMS Elements
- *  20 - Use the interfaces provided for Email in CSmsMessage
- *  21 - Use the interface provided by CSmsHyperLinkOperations
- *  22 - Use the interface provided by CSmsReplyAddressOperations
- *  23 - Use the interface provided by CSmsEnhancedVoiceMailOperations
- *  
- *  This interface should not be used for information element in the following
- *  ranges, these are reserved for future use in TS23.040 V6.5.0 and their
- *  characteristics and repeatability have not yet been defined.
- *  26-6F
- *  A0-BF
- *  E0-FF
- *  
- *  @param aIdentifier An information element Identifier for aData
- *  @param aData The information element to add to the User Data
- *  @leave
- *  KErrNotSupported if the information element is not supported via this interface.
- *  @capability None
- */
-EXPORT_C void CSmsUserData::AddInformationElementL(TSmsId aIdentifier,const TDesC8& aData)
-    {
-    LOGGSMU1("CSmsUserData::AddInformationElementL");
-
-    if  ((aIdentifier >= 0x21) && (aIdentifier <= 0x23) ||
-         (aIdentifier >= 0x26) && (aIdentifier <= 0x6F) ||
-         (aIdentifier >= 0xA0) && (aIdentifier <= 0xBF) ||
-         (aIdentifier >= 0xE0) && (aIdentifier <= 0xFF))
-        {
-        User::Leave(KErrNotSupported);
-        }
-    UpdateInformationElementArrayL(aIdentifier, aData);
-
-    } // CSmsUserData::AddInformationElementL
-
-
-/**
- *  @internalComponent
- *  
- *  Either adds an information element to
- *  iInformationElementArray.
- *  
- *  @param aIdentifier An information element Identifier for aData
- *  @param aData The information element to add to the User Data
- */
-void CSmsUserData::UpdateInformationElementArrayL(TSmsId aIdentifier,const TDesC8& aData)
-    {
-    LOGGSMU1("CSmsUserData::UpdateInformationElementsL");
-
-    TInt count=NumInformationElements();
-    if(!CEmsFactory::Supported(aIdentifier))
-        {
-        for (TInt i=0; i<count; i++)
-            {
- 	        if (InformationElement(i).Identifier()==aIdentifier)
-                {
-                TSmsInformationElementCategories::TInformationElementCategory category;
-                
-                if (TSmsInformationElementCategories::GetCategoryDefinition(aIdentifier, category) == EFalse)
-                	{
-                	User::Leave(KErrArgument);
-                	}
-
-                switch (category)
-                    {
-                    case TSmsInformationElementCategories::ECtrlMandatoryInEveryPDUMultipleInstancesPerPDU:
-                        {
-                        if (InformationElement(i).Identifier() == CSmsInformationElement::ESmsIEISpecialSMSMessageIndication)
-                            {
-                            LOGGSMU3("CSmsUserData::AddInformationElementL1 category = %d, identifier = %d",category,aIdentifier);
-
-                            //if Msg type is the same, swap with the most recent value
-                            if ((InformationElement(i).Data()[0] & ((TUint8) EGsmSmsSpecialMessageIndicationTypeMask)) ==
-                                (aData[0] & ((TUint8) EGsmSmsSpecialMessageIndicationTypeMask)))
-                                {
-                                User::Leave(KErrAlreadyExists);
-                                }
-                            }
-                        else
-                            {
-                            LOGGSMU4("CSmsUserData::AddInformationElementL3 category = %d, identifier = %d, data = %S",category,aIdentifier, &aData);
-                            User::Leave(KErrArgument);
-                            }
-                        break;
-                        }
-                    case TSmsInformationElementCategories::ECtrlMandatoryInEveryPDUAndWithIdenticalValues:
-                    case TSmsInformationElementCategories::ECtrlMandatoryIn1stPDUOnly:
-                    case TSmsInformationElementCategories::ECtrlSingleInstanceOnly:
-                        {
-                        LOGGSMU3("CSmsUserData::AddInformationElementL4 category = %d, identifier = %d",category,aIdentifier);
-                        User::Leave(KErrAlreadyExists);
-                        break;
-                        }
-                    case TSmsInformationElementCategories::ECtrlMultipleInstancesAllowed:
-                        {
-                        LOGGSMU3("CSmsUserData::AddInformationElementL5 category = %d, identifier = %d",category,aIdentifier);
-                        break;
-                        }
-                    case TSmsInformationElementCategories::ECtrlMandatoryInEveryPDUButWithValueSpecificToPDU:
-                        {
-                        LOGGSMU3("CSmsUserData::AddInformationElementL6 category = %d, identifier = %d",category,aIdentifier);
-                        User::Leave(KErrAlreadyExists);
-                        // currently the email header is updated in:
-                        // void CSmsMessage::DecodeBufferL(CArrayPtr<CSmsPDU>& aSmsPDUArray,CSmsBufferBase& aBuffer)
-                        break;
-                        }
-                    default:
-                        {
-                        LOGGSMU3("CSmsUserData::AddInformationElementL8 category = %d, identifier = %d",category,aIdentifier);
-                        User::Leave(KErrNotSupported);
-                        break;
-                        }
-                    }
-                }
-            }
-        }
-
-    	CSmsInformationElement* informationElement=CSmsInformationElement::NewL(aIdentifier,aData);
-    	CleanupStack::PushL(informationElement);
-    	iInformationElementArray.AppendL(informationElement);
-    	CleanupStack::Pop();
-    	SetHeaderPresent(ETrue);
-    } // CSmsUserData::UpdateInformationElementArrayL
-
-
-void CSmsUserData::AddEmsInformationElementL(CEmsInformationElement* aIe)
-	{
-	LOGGSMU1("CSmsUserData::AddEmsInformationElementL()");
-
-	// Before using an EmsInformationElement polymorphically as an SmsIE,
-	// we need to make sure that the IE has been encoded
-	aIe->EncodeInformationElementL();
-	iInformationElementArray.AppendL(aIe);
-	SetHeaderPresent(ETrue);
-	} // CSmsUserData::AddEmsInformationElementL
-
-
-/**
- *  Removes an information element at the specified index.
- *  
- *  @param aIndex Information element index
- *  @capability None
- */
-EXPORT_C void CSmsUserData::RemoveInformationElement(TInt aIndex)
-	{
-	LOGGSMU1("CSmsUserData::RemoveInformationElement()");
-	// Since iInformationElementArray[aIndex] pointer is removed from iInformationElementArray, there is no double free issue.
-	// coverity[double_free]
-	delete iInformationElementArray[aIndex];
-	iInformationElementArray[aIndex] = NULL;
-	iInformationElementArray.Delete(aIndex);
-
-	if (NumInformationElements()==0)
-		{
-		SetHeaderPresent(EFalse);
-		}
-	} // CSmsUserData::RemoveInformationElement
-
-
-TInt CSmsUserData::MaxPackedUDUnitsInBodyRemaining() const
-	{
-	LOGGSMU1("CSmsUserData::MaxPackedUDUnitsInBodyRemaining()");
-
-	TInt totalHeaderLengthInUDLUnits=TotalHeaderLengthInUDLUnits();
-	TInt maxPackedUDUnitsInBody=0;
-	if (iDataCodingScheme.TextCompressed()||(iDataCodingScheme.Alphabet()!=TSmsDataCodingScheme::ESmsAlphabet7Bit))
-		{
-		maxPackedUDUnitsInBody=KSmsMaxUserDataSize-totalHeaderLengthInUDLUnits;
-		if (iDataCodingScheme.Alphabet()==TSmsDataCodingScheme::ESmsAlphabetUCS2)
-			{
-			// Cannot split unicode character across PDU boundary
-			maxPackedUDUnitsInBody&=~1;
-			}
-		}
-	else // 7-bit
-		{
-		maxPackedUDUnitsInBody=(8*KSmsMaxUserDataSize)/7-totalHeaderLengthInUDLUnits;
-		}
-
-	if (iBody)
-		return maxPackedUDUnitsInBody-=iBody->Length();
-	return maxPackedUDUnitsInBody;
-	} // CSmsUserData::MaxPackedUDUnitsInBodyRemaining
-
-
-TInt CSmsUserData::MaxPackedUDUnitsInBodyRemaining(TUint aIELen) const
-	{
-	LOGGSMU1("CSmsUserData::MaxPackedUDUnitsInBodyRemaining()");
-
-	TInt totalHeaderLengthInUDLUnits=TotalHeaderLengthInUDLUnits(aIELen);
-	TInt maxPackedUDUnitsInBody=0;
-	if (iDataCodingScheme.TextCompressed()||(iDataCodingScheme.Alphabet()!=TSmsDataCodingScheme::ESmsAlphabet7Bit))
-		{
-		maxPackedUDUnitsInBody=KSmsMaxUserDataSize-totalHeaderLengthInUDLUnits;
-		if (iDataCodingScheme.Alphabet()==TSmsDataCodingScheme::ESmsAlphabetUCS2)
-			{
-			// Cannot split unicode character across PDU boundary
-			maxPackedUDUnitsInBody&=~1;
-			}
-		}
-	else // 7-bit
-		{
-		maxPackedUDUnitsInBody=(8*KSmsMaxUserDataSize)/7-totalHeaderLengthInUDLUnits;
-		}
-
-	if (iBody)
-		return maxPackedUDUnitsInBody-=iBody->Length();
-	return maxPackedUDUnitsInBody;
-	} // CSmsUserData::MaxPackedUDUnitsInBodyRemaining
-
-
-/**
- *  @capability None
- */
-EXPORT_C TInt CSmsUserData::MaxBodyLengthInChars() const
-	{
-	LOGGSMU1("CSmsUserData::MaxBodyLengthInChars()");
-
-	TInt totalheaderlengthinudlunits=TotalHeaderLengthInUDLUnits();
-	TInt maxbodylengthinchars=0;
-	if (iDataCodingScheme.TextCompressed())
-		{
-		maxbodylengthinchars=KSmsMaxUserDataSize-totalheaderlengthinudlunits;
-		}
-	else
-		{
-		switch (iDataCodingScheme.Alphabet())
-			{
-			case (TSmsDataCodingScheme::ESmsAlphabet7Bit):
-				{
-				maxbodylengthinchars=(8*KSmsMaxUserDataSize)/7-totalheaderlengthinudlunits;
-				break;
-				}
-			case (TSmsDataCodingScheme::ESmsAlphabet8Bit):
-				{
-				maxbodylengthinchars=KSmsMaxUserDataSize-totalheaderlengthinudlunits;
-				break;
-				}
-			case (TSmsDataCodingScheme::ESmsAlphabetUCS2):
-				{
-				maxbodylengthinchars=(KSmsMaxUserDataSize-totalheaderlengthinudlunits)/2;
-				break;
-				}
-			default:
-			    LOGGSMU1("CSmsUserData::MaxBodyLengthInChars() WARNING! default case has been reached");
-                break;
- 			}
-		}
-	return maxbodylengthinchars;
-	} // CSmsUserData::MaxBodyLengthInChars
-
-
-/**
- *  Gets the unpacked User Data Elements.
- *  
- *  @return Unpacked User Data Elements
- *  @capability None
- */
-EXPORT_C TPtrC8 CSmsUserData::Body() const
-	{
-	LOGGSMU1("CSmsUserData::Body()");
-
-	return iBody->Des();
-	} // CSmsUserData::Body
-
-
-/**
- *  Sets the User Data (unpacked).
- *  
- *  @param aBody Unpacked User Data Elements
- *  @capability None
- */
-EXPORT_C void CSmsUserData::SetBodyL(const TDesC8& aBody)
-	{
-	LOGGSMU1("CSmsUserData::SetBodyL()");
-
-	//Some tests fail with this line in, despite it being a valid condition!
-	//__ASSERT_DEBUG(aBody.Length() <= MaxBodyLengthInChars(), User::Leave(KErrTooBig));
-
-	NewBodyL(aBody.Length());
-	iBody->Des().Copy(aBody);
-	} // CSmsUserData::SetBodyL
-
-
-void CSmsUserData::AppendBodyL(const TDesC8& aBody)
-	{
-	LOGGSMU1("CSmsUserData::AppendBodyL()");
-
-	if (iBody)
-		{
-		//Some tests fail with this line in, despite it being a valid condition!
-		//__ASSERT_DEBUG(aBody.Length() + iBody->Length() <= MaxBodyLengthInChars(), User::Leave(KErrTooBig));
-
-		iBody = iBody->ReAllocL(aBody.Length()+iBody->Length());
-		iBody->Des().Append(aBody);
-		}
-	else
-		{
-		SetBodyL(aBody);
-		}
-	} // CSmsUserData::AppendBodyL
-
-
-/**
- *  Tests if the character is supported by the current character set.
- *  This function can be used with 7bit and 8bit alphabets.
- * 
- *  @param aChar  Character to investigate.
- * 
- *  @return  ETrue if the character is supported.
- * 
- *  @note Since the function is based on the old behaviour (pre-PREQ2090)
- *        it does not accept a downgraded character or alternative encoding
- *        as being supported.
- *
- *  @capability None
- */
-EXPORT_C TBool CSmsUserData::IsSupportedL(TChar aChar)
-	{
-	LOGGSMU1("CSmsUserData::IsSupportedL()");
-
-	CSmsAlphabetConverter* converter=CSmsAlphabetConverter::NewLC(iCharacterSetConverter,iFs,iDataCodingScheme.Alphabet(),IsBinaryData());
-	TBool result=converter->IsSupportedL(aChar);
-	CleanupStack::PopAndDestroy();
-
-	return result;
-	} // CSmsUserData::IsSupportedL
-
-
-/**
- *  Tests if the descriptor text is supported by the current character set.
- *  This function can be used with 7bit and 8bit alphabets.
- * 
- *  @param aDes                                 Text string to check.
- *  @param aNumberOfUnconvertibleCharacters     Exit param for the number of
- *                                              characters unconvertible.
- *  @param aIndexOfFirstUnconvertibleCharacter  Exit param for the first
- *                                              unconverted character.
- * 
- *  @return  ETrue if the character is supported.
- *
- *  @capability None
- */
-EXPORT_C TBool CSmsUserData::IsSupportedL(const TDesC& aDes, TInt& aNumberOfUnconvertibleCharacters,
-                                          TInt& aIndexOfFirstUnconvertibleCharacter) const
-	{
-	LOGGSMU1("[1] CSmsUserData::IsSupportedL()");
-
-	CSmsAlphabetConverter* converter=CSmsAlphabetConverter::NewLC(iCharacterSetConverter,iFs,iDataCodingScheme.Alphabet(),IsBinaryData());
-	TBool result=converter->IsSupportedL(aDes, aNumberOfUnconvertibleCharacters,
-			                             aIndexOfFirstUnconvertibleCharacter);
-	CleanupStack::PopAndDestroy();
-
-	return result;
-	} // CSmsUserData::IsSupportedL
-
-
-/**
- *  Tests if the descriptor text is supported by the current character set.
- *  This function can be used with 7bit and 8bit alphabets.
- * 
- *  @param aDes                                 Text string to check.
- *  @param aEncoding                            Alternative encoding method.
- *  @param aNumberOfUnconvertibleCharacters     Exit param for the number of
- *                                              characters unconvertible.
- *  @param aNumberOfDowngradedCharacters        Exit param for the number of
- *                                              downgraded characters.
- *  @param aNumberRequiringAlternativeEncoding  Exit param for the number of
- *                                              characters requiring use of
- *                                              the alternative encoder.
- *  @param aIndexOfFirstUnconvertibleCharacter  Exit param for the first
- *                                              unconverted character.
- * 
- *  @return  ETrue if the character is supported.
- *
- *  @capability None
- */
-EXPORT_C TBool CSmsUserData::IsSupportedL(const TDesC& aDes, TSmsEncoding aEncoding,
-										  TInt& aNumberOfUnconvertibleCharacters,
-                                          TInt& aNumberOfDowngradedCharacters,
-                                          TInt& aNumberRequiringAlternativeEncoding,
-                                          TInt& aIndexOfFirstUnconvertibleCharacter) const
-	{
-	LOGGSMU1("[2] CSmsUserData::IsSupportedL()");
-
-	CSmsAlphabetConverter* converter=CSmsAlphabetConverter::NewLC(iCharacterSetConverter,iFs,iDataCodingScheme.Alphabet(),IsBinaryData());
-	TBool result=converter->IsSupportedL(aDes, aEncoding,
-			                             aNumberOfUnconvertibleCharacters,
-			                             aNumberOfDowngradedCharacters,
-			                             aNumberRequiringAlternativeEncoding,
-			                             aIndexOfFirstUnconvertibleCharacter);
-	CleanupStack::PopAndDestroy();
-
-	return result;
-	} // CSmsUserData::IsSupportedL
-
-
-TUint8* CSmsUserData::EncodeL(TUint8* aPtr) const
-	{
-	LOGGSMU1("CSmsUserData::EncodeL()");
-
-	__ASSERT_DEBUG(0<=MaxPackedUDUnitsInBodyRemaining(),Panic(KGsmuPanicUserDataBodyTooLong));
-	// Encode the user data length
-	TInt totalHeaderLengthInUDLUnits=TotalHeaderLengthInUDLUnits();
-	TSmsOctet userDataLength=totalHeaderLengthInUDLUnits+TSmsOctet(BodyLengthInUDLUnits());
-	aPtr=userDataLength.EncodeL(aPtr);
-	// Encode any user data header
-	if (HeaderPresent())
-		{
-		TSmsOctet headerLength=HeaderLength();
-		aPtr=headerLength.EncodeL(aPtr);
-		TInt numInformationElements=NumInformationElements();
-		for (TInt i=0; i<numInformationElements; i++)
-			aPtr=iInformationElementArray[i]->EncodeL(aPtr);
-		}
-	// Pack the user data body
-	TInt startBit=0;
-	if (iDataCodingScheme.Alphabet()==TSmsDataCodingScheme::ESmsAlphabet7Bit)
-		startBit=(totalHeaderLengthInUDLUnits*7)%8;
-	TSmsAlphabetPacker packer(iDataCodingScheme.Alphabet(),IsBinaryData(),startBit);
-	TPtr8 ptr((TUint8*)aPtr,0,packer.PackedOctetsRequiredL(Body().Length()));
-	aPtr+=packer.PackL(ptr,Body());
-	return aPtr;
-	} // CSmsUserData::EncodeL
-
-
-void CSmsUserData::DecodeL(TGsmuLex8& aPdu)
-	{
-	DecodeL(aPdu, EFalse);
-	}
-
-void CSmsUserData::DecodeL(TGsmuLex8& aPdu, TBool aAcceptTruncation)
-	{	
-	LOGGSMU1("CSmsUserData::DecodeL()");
-
-	// Reset current data
-	iInformationElementArray.ResetAndDestroy();
-	// Decode the user data
-	TSmsOctet userDataLength;
-	userDataLength.DecodeL(aPdu);
-	TSmsOctet headerLength;
-	// Decode any user data header
-	TBool headerPresent=HeaderPresent();
-	/*
-	if (headerPresent || IsHeaderPresent(aPtr,dataLength))
-	*/
-	if (headerPresent)
-		{
-		headerLength.DecodeL(aPdu);
-		if ((1+headerLength)>KSmsMaxUserDataSize)
-			User::Leave(KErrGsmSMSTpduNotSupported);
-		while (HeaderLength()<headerLength)
-			{
-			CSmsInformationElement* informationelement=CSmsInformationElement::NewL();
-			CleanupStack::PushL(informationelement);
-			informationelement->DecodeL(aPdu);
-			iInformationElementArray.AppendL(informationelement);
-			CleanupStack::Pop(informationelement);
-			}
-		if (HeaderLength()!=headerLength)
-			User::Leave(KErrGsmSMSTpduNotSupported);
-		}
-	// Decode the body - make sure we have enough buffer
-	TInt headerLengthInUDLUnits=TotalHeaderLengthInUDLUnits();
-	TInt bodyLengthInUDLUnits=userDataLength-headerLengthInUDLUnits;
-
-	if(bodyLengthInUDLUnits <=0)
-	{
-		NewBodyL(0);
-		return;
-	}
-
-	NewBodyL(bodyLengthInUDLUnits);
-
-	// Unpack the body
-	TInt startBit=0;
-	if (iDataCodingScheme.Alphabet()==TSmsDataCodingScheme::ESmsAlphabet7Bit)
-		startBit=(headerLengthInUDLUnits*7)%8;
-	TSmsAlphabetPacker unpacker(iDataCodingScheme.Alphabet(),IsBinaryData(),startBit);
-	TInt bodyLengthInOctets=unpacker.PackedOctetsRequiredL(bodyLengthInUDLUnits);
-	TPtr8 destPtr((TUint8*)iBody->Des().Ptr(),0,bodyLengthInUDLUnits);
-
-	const TPtrC8 sourcePtr(aPdu.NextWithNoIncL(bodyLengthInOctets,aAcceptTruncation));
-	if ( aAcceptTruncation && sourcePtr.Length() < bodyLengthInOctets)
-		{
-		// field was truncated in an acceptable situation (User Data in Status Report PDU)
-		bodyLengthInUDLUnits = unpacker.NumUDUnitsL(sourcePtr.Length());
-		}
-	unpacker.UnpackL(sourcePtr,destPtr,bodyLengthInUDLUnits);
-
-	//@note No need to call aPdu.IncL() because CSmsUserData is always at the end of a PDU
-	} // CSmsUserData::DecodeL
-
-
-void CSmsUserData::InternalizeL(RReadStream& aStream)
-	{
-	iInformationElementArray.ResetAndDestroy();
-	TInt numiformationelements=aStream.ReadInt32L();
-	// The "header present" flag must mirror whether information elements are present, and
-	// the parental iFirstOctet should already be set by its InternalizeL()
-	__ASSERT_DEBUG(((!HeaderPresent() && numiformationelements == 0) || (HeaderPresent() && numiformationelements > 0)), Panic(KGsmuPanicInformationElementIndexOutOfRange));
-	for (TInt i=0; i<numiformationelements; i++)
-		{
-		CSmsInformationElement* informationelement=CSmsInformationElement::NewL();
-		CleanupStack::PushL(informationelement);
-		aStream >> *informationelement;
-		iInformationElementArray.AppendL(informationelement);
-		CleanupStack::Pop();
-		}
-	delete iBody;
-	iBody=NULL;
-	iBody=HBufC8::NewL(aStream,KSmsMaxUserDataLengthInChars);
-	} // CSmsUserData::InternalizeL
-
-
-void CSmsUserData::ExternalizeL(RWriteStream& aStream) const
-	{
-	TInt numiformationelements=iInformationElementArray.Count();
-	aStream.WriteInt32L(numiformationelements);
-	for (TInt i=0; i<numiformationelements; i++)
-		aStream << *iInformationElementArray[i];
-	aStream << *iBody;
-	} // CSmsUserData::ExternalizeL
-
-
-CSmsUserData::CSmsUserData(CCnvCharacterSetConverter& aCharacterSetConverter,RFs& aFs,TSmsFirstOctet& aFirstOctet,const TSmsDataCodingScheme& aDataCodingScheme):
-    iCharacterSetConverter(aCharacterSetConverter),
-    iFs(aFs),
-    iFirstOctet(aFirstOctet),
-    iDataCodingScheme(aDataCodingScheme),
-    iInformationElementArray(8)
-    {
-    } // CSmsUserData::CSmsUserData
-
-
-void CSmsUserData::ConstructL()
-	{
-	LOGGSMU1("CSmsUserData::ConstructL()");
-
-	NewBodyL(0);
-	} // CSmsUserData::ConstructL
-
-
-/**
- *  Duplicates this CSmsUserData object.
- * 
- *  @return  Pointer to the newly created CSmsUserData object.
- */
-CSmsUserData* CSmsUserData::DuplicateL(TSmsFirstOctet& aFirstOctet,
-									   const TSmsDataCodingScheme& aDataCodingScheme) const
-	{
-	LOGGSMU1("CSmsUserData::DuplicateL()");
-
-	CSmsUserData*  userdata = CSmsUserData::NewL(iCharacterSetConverter, iFs,
-	                                             aFirstOctet, aDataCodingScheme);
-	CleanupStack::PushL(userdata);
-
-	userdata->SetBodyL(Body());
-
-	for (TInt ie = 0;  ie < iInformationElementArray.Count();  ie++)
-		{
-		CSmsInformationElement*  oldIE = iInformationElementArray[ie];
-
-		if (CEmsFactory::Supported(oldIE->Identifier()))
-			{
-			CEmsInformationElement*  newIE = static_cast<CEmsInformationElement*>(oldIE)->DuplicateL();
-			
-			CleanupStack::PushL(newIE);
-			userdata->AddEmsInformationElementL(newIE);
-			CleanupStack::Pop(newIE);
-			}
-		else
-			{
-			userdata->UpdateInformationElementArrayL(oldIE->Identifier(), oldIE->Data());
-			}
-		}
-
-	CleanupStack::Pop();
-
-	return userdata;
-	} // CSmsUserData::DuplicateL
-
-
-TInt CSmsUserData::HeaderLength() const
-	{
-	LOGGSMU1("CSmsUserData::HeaderLength()");
-
-	TInt numinformationelements=NumInformationElements();
-	TInt headerlength=0;
-	for (TInt i=0; i<numinformationelements; i++)
-		headerlength+=iInformationElementArray[i]->Length();
-	return headerlength;
-	} // CSmsUserData::HeaderLength
-
-
-TInt CSmsUserData::TotalHeaderLengthInUDLUnits() const
-	{
-	LOGGSMU1("CSmsUserData::TotalHeaderLengthInUDLUnits()");
-
-	TInt totalheaderlengthinudlunits=0;
-	if (iInformationElementArray.Count()>0)
-		{
-		TInt totalheaderlength=1+HeaderLength();
-		if (iDataCodingScheme.TextCompressed())
-			{
-			totalheaderlengthinudlunits=totalheaderlength;
-			}
-		else
-			{
-			switch(iDataCodingScheme.Alphabet())
-				{
-				case (TSmsDataCodingScheme::ESmsAlphabet7Bit):
-					{
-					totalheaderlengthinudlunits=((8*totalheaderlength)+6)/7; //  Rounds up
-					break;
-					}
-				case (TSmsDataCodingScheme::ESmsAlphabet8Bit):
-				case (TSmsDataCodingScheme::ESmsAlphabetUCS2):
-					{
-					totalheaderlengthinudlunits=totalheaderlength;
-					break;
-					}
-				default:
-				    LOGGSMU1("CSmsUserData::TotalHeaderLengthInUDLUnits() WARNING default case has been reached");
-                    break;
-				}
-			}
-		}
-	return totalheaderlengthinudlunits;
-	} // CSmsUserData::TotalHeaderLengthInUDLUnits
-
-
-TInt CSmsUserData::TotalHeaderLengthInUDLUnits(TInt aIElen) const
-	{
-	LOGGSMU1("CSmsUserData::TotalHeaderLengthInUDLUnits()");
-
-		TInt totalheaderlengthinudlunits=0;
-		TInt totalheaderlength=aIElen;
-
-		if (iInformationElementArray.Count()>0)
-			totalheaderlength+=HeaderLength();
-
-		if(totalheaderlength)totalheaderlength+=1; //UDHL
-
-		if (iDataCodingScheme.TextCompressed())
-			{
-			totalheaderlengthinudlunits=totalheaderlength;
-			}
-		else
-			{
-			switch(iDataCodingScheme.Alphabet())
-				{
-				case (TSmsDataCodingScheme::ESmsAlphabet7Bit):
-					{
-					totalheaderlengthinudlunits=((8*totalheaderlength)+6)/7; //  Rounds up
-					break;
-					}
-				case (TSmsDataCodingScheme::ESmsAlphabet8Bit):
-				case (TSmsDataCodingScheme::ESmsAlphabetUCS2):
-					{
-					totalheaderlengthinudlunits=totalheaderlength;
-					break;
-					}
-				default:
-                    break;
-				}
-			}
-		return totalheaderlengthinudlunits;
-	} // CSmsUserData::TotalHeaderLengthInUDLUnits
-
-
-TInt CSmsUserData::BodyLengthInUDLUnits() const
-	{
-	LOGGSMU1("CSmsUserData::BodyLengthInUDLUnits()");
-
-	return iBody->Des().Length();
-	} // CSmsUserData::BodyLengthInUDLUnits
-
-
-void CSmsUserData::NewBodyL(TInt aLength)
-	{
-	LOGGSMU1("CSmsUserData::NewBodyL()");
-
-
-		HBufC8* body=HBufC8::NewL(aLength);
-		delete iBody;
-		iBody=body;
-		iBody->Des().SetLength(aLength);
-
-	} // CSmsUserData::NewBodyL
-
-
-TBool CSmsUserData::HeaderPresent() const
-	{
-	LOGGSMU1("CSmsUserData::HeaderPresent()");
-
-	return (iFirstOctet&TSmsFirstOctet::ESmsUDHIMask)==TSmsFirstOctet::ESmsUDHIHeaderPresent;
-	} // CSmsUserData::HeaderPresent
-
-
-void CSmsUserData::SetHeaderPresent(TBool aHeaderPresent)
-	{
-	LOGGSMU1("CSmsUserData::SetHeaderPresent()");
-
-	iFirstOctet=aHeaderPresent? (iFirstOctet&(~TSmsFirstOctet::ESmsUDHIMask))|TSmsFirstOctet::ESmsUDHIHeaderPresent: (iFirstOctet&(~TSmsFirstOctet::ESmsUDHIMask))|TSmsFirstOctet::ESmsUDHIHeaderNotPresent;
-	} // CSmsUserData::SetHeaderPresent
-
-
-TBool CSmsUserData::IsBinaryData() const
-	{
-	LOGGSMU1("CSmsUserData::IsBinaryData()");
-
-	TInt index=0;
-	return (iDataCodingScheme.TextCompressed()) ||
-			((iDataCodingScheme.Alphabet()==TSmsDataCodingScheme::ESmsAlphabet8Bit) &&
-			(InformationElementIndex(CSmsInformationElement::ESmsIEIApplicationPortAddressing8Bit,index) ||
-	        InformationElementIndex(CSmsInformationElement::ESmsIEIApplicationPortAddressing16Bit,index)));
-	} // CSmsUserData::IsBinaryData
-
-
-/**
- *  Converts type of number and numbering plan identification information
- *  from the type of address parameter to the NMobilePhone::TMobileTON
- *  and NMobilePhone::TMobileNPI format.
- *  
- *  @return aTon The number type
- *  @return aNpi The numbering plan
- *  
- *  @capability None
- */
-EXPORT_C void TGsmSmsTypeOfAddress::ConvertToETelMM(NMobilePhone::TMobileTON& aTon,NMobilePhone::TMobileNPI& aNpi) const
-    {
-    LOGGSMU1("TGsmSmsTypeOfAddress::ConvertToETelMM()");
-
-    switch (TON())
-    {
-		case EGsmSmsTONInternationalNumber:
-            {
-            aTon = (NMobilePhone::EInternationalNumber);
-            break;
-            }
-        case EGsmSmsTONNationalNumber:
-            {
-            aTon = (NMobilePhone::ENationalNumber);
-            break;
-            }
-        case EGsmSmsTONNetworkSpecificNumber:
-            {
-            aTon = (NMobilePhone::ENetworkSpecificNumber);
-            break;
-            }
-        case EGsmSmsTONSubscriberNumber:
-            {
-            aTon = (NMobilePhone::ESubscriberNumber);
-            break;
-            }
-        case EGsmSmsTONAlphaNumeric:
-            {
-            aTon = (NMobilePhone::EAlphanumericNumber);
-            break;
-            }
-        case EGsmSmsTONAbbreviatedNumber:
-            {
-            aTon = (NMobilePhone::EAbbreviatedNumber);
-            break;
-            }
-
-        default:
-            {
-            aTon = (NMobilePhone::EUnknownNumber);
-            break;
-            }
-		}
-
-    switch (NPI())
-		{
-        case EGsmSmsNPIISDNTelephoneNumberingPlan:
-            {
-            aNpi = (NMobilePhone::EIsdnNumberPlan);
-            break;
-            }
-        case EGsmSmsNPIDataNumberingPlan:
-            {
-            aNpi = (NMobilePhone::EDataNumberPlan);
-            break;
-            }
-        case EGsmSmsNPITelexNumberingPlan:
-            {
-            aNpi = (NMobilePhone::ETelexNumberPlan);
-            break;
-            }
-        case EGsmSmsNPINationalNumberingPlan:
-            {
-            aNpi = (NMobilePhone::ENationalNumberPlan);
-            break;
-            }
-        case EGsmSmsNPIPrivateNumberingPlan:
-            {
-            aNpi = (NMobilePhone::EPrivateNumberPlan);
-            break;
-            }
-        case EGsmSmsNPIERMESNumberingPlan:
-            {
-            aNpi = (NMobilePhone::EERMESNumberPlan);
-            break;
-            }
-
-        default:
-            {
-            aNpi = (NMobilePhone::EUnknownNumberingPlan);
-            break;
-            }
-		}
-	} // NMobilePhone::TMobileNPI
-
-
-/**
- *  Converts type of number and numbering plan identification information
- *  from the NMobilePhone::TMobileTON and NMobilePhone::TMobileNPI format
- *  to the type of address parameter.
- *  
- *  @param aTon The number type
- *  @param aNpi The numbering plan
- *  
- *  @capability None
- */
-EXPORT_C void TGsmSmsTypeOfAddress::SetFromETelMM(NMobilePhone::TMobileTON aTon,NMobilePhone::TMobileNPI aNpi)
-    {
-    LOGGSMU1("TGsmSmsTypeOfAddress::SetFromETelMM()");
-
-    switch (aTon)
-    {
-		case NMobilePhone::EInternationalNumber:
-            {
-            SetTON( EGsmSmsTONInternationalNumber );
-            break;
-            }
-        case NMobilePhone::ENationalNumber:
-            {
-            SetTON( EGsmSmsTONNationalNumber );
-            break;
-            }
-        case NMobilePhone::ENetworkSpecificNumber:
-            {
-            SetTON( EGsmSmsTONNetworkSpecificNumber );
-            break;
-            }
-        case NMobilePhone::ESubscriberNumber:
-            {
-            SetTON( EGsmSmsTONSubscriberNumber );
-            break;
-            }
-        case NMobilePhone::EAlphanumericNumber:
-            {
-            SetTON( EGsmSmsTONAlphaNumeric );
-            break;
-            }
-        case NMobilePhone::EAbbreviatedNumber:
-            {
-            SetTON( EGsmSmsTONAbbreviatedNumber );
-            break;
-            }
-
-        default:
-            {
-            SetTON( EGsmSmsTONUnknown );
-            break;
-            }
-		}
-
-    switch (aNpi)
-		{
-        case NMobilePhone::EIsdnNumberPlan:
-            {
-            SetNPI( EGsmSmsNPIISDNTelephoneNumberingPlan );
-            break;
-            }
-        case NMobilePhone::EDataNumberPlan:
-            {
-            SetNPI( EGsmSmsNPIDataNumberingPlan );
-            break;
-            }
-        case NMobilePhone::ETelexNumberPlan:
-            {
-            SetNPI( EGsmSmsNPITelexNumberingPlan );
-            break;
-            }
-        case NMobilePhone::ENationalNumberPlan:
-            {
-            SetNPI( EGsmSmsNPINationalNumberingPlan );
-            break;
-            }
-        case NMobilePhone::EPrivateNumberPlan:
-            {
-            SetNPI( EGsmSmsNPIPrivateNumberingPlan );
-            break;
-            }
-        case NMobilePhone::EERMESNumberPlan:
-            {
-            SetNPI( EGsmSmsNPIERMESNumberingPlan );
-            break;
-            }
-
-        default:
-            {
-            SetNPI( EGsmSmsNPIUnknown );
-            break;
-            }
-		}
-	} // NMobilePhone::TMobileTON
-
-
-/**
- *  @publishedAll
- *  
- *  Indicates whether this message is a Voice Mail Notification
- *  or a Voice Mail Deletion Confirmation.
- *  
- *  @return
- *  TVoiceMailInfoType, indicating whether this message is a Voice Mail
- *  Notification or a Voice Mail Deletion Confirmation.
- *  
- *  @capability None
- */
-EXPORT_C TVoiceMailInfoType CEnhancedVoiceMailBoxInformation::Type() const
-	{
-	LOGGSMU1("CEnhancedVoiceMailBoxInformation::Type()");
-
-	return iType;
-	} // CEnhancedVoiceMailBoxInformation::Type
-
-
-/**
- *  @publishedAll
- *  
- *  Sets the subscriber profile per 23.040 v6.5 Section 9.2.3.24.13.1.
- *  
- *  @param aProfile
- *  The required subscriber profile
- *  
- *  @capability None
- */
-EXPORT_C void CEnhancedVoiceMailBoxInformation::SetProfile(TSmsMessageProfileType aProfile)
-	{
-	LOGGSMU1("CEnhancedVoiceMailBoxInformation::SetProfile()");
-
-	iProfile = aProfile;
-	} // CEnhancedVoiceMailBoxInformation::SetProfile
-
-
-/**
- *  @publishedAll
- *  
- *  Gets the subscriber profile per 23.040 v6.5 Section 9.2.3.24.13.1.
- *  
- *  @param aProfile
- *  The current subscriber profile
- *  
- *  @capability None
- */
-EXPORT_C TSmsMessageProfileType CEnhancedVoiceMailBoxInformation::Profile() const
-	{
-	LOGGSMU1("CEnhancedVoiceMailBoxInformation::Profile()");
-
-	return iProfile;
-	} // CEnhancedVoiceMailBoxInformation::Profile
-
-
-/**
- *  @publishedAll
- *  
- *  Configures the storage directive
- *  
- *  @param aIsStored
- *  Set to True if the SM is to be stored in the ME or USIM,
- *  False is the SM is to be discarded.
- *  
- *  @capability None
- */
-EXPORT_C void CEnhancedVoiceMailBoxInformation::SetStorage(TBool aIsStored)
-	{
-	LOGGSMU1("CEnhancedVoiceMailBoxInformation::SetStorage()");
-
-	iStorage = aIsStored;
-	} // CEnhancedVoiceMailBoxInformation::SetStorage
-
-
-/**
- *  @publishedAll
- *  
- *  Indicates whether the SM is to be stored or discarded
- *  
- *  @return
- *  True if the SM is to be stored in the ME or USIM,
- *  False is the SM is to be discarded.
- *  
- *  @capability None
- */
-EXPORT_C TBool CEnhancedVoiceMailBoxInformation::Store() const
-	{
-	LOGGSMU1("CEnhancedVoiceMailBoxInformation::Store()");
-
-	return iStorage;
-	} // CEnhancedVoiceMailBoxInformation::Store
-
-
-/**
- *  @publishedAll
- *  
- *  Used to set or reset the voice mail status to almost full.
- *  
- *  @param aIsStored
- *  Set to True the voice mail system is almost full.
- *  Set to False otherwise.
- *  
- *  @capability None
- */
-EXPORT_C void CEnhancedVoiceMailBoxInformation::SetAlmostMaximumCapacity(TBool aIsAlmostFull)
-	{
-	LOGGSMU1("CEnhancedVoiceMailBoxInformation::SetAlmostMaximumCapacity()");
-
-	iAlmostFull = aIsAlmostFull;
-	} // CEnhancedVoiceMailBoxInformation::SetAlmostMaximumCapacity
-
-
-/**
- *  @publishedAll
- *  
- *  Indicates whether the voice mail system is almost at full capacity.
- *  
- *  @return
- *  True, if the voice mail system is almost full.
- *  False otherwise.
- *  
- *  @capability None
- */
-EXPORT_C TBool CEnhancedVoiceMailBoxInformation::AlmostMaximumCapacity() const
-	{
-	LOGGSMU1("CEnhancedVoiceMailBoxInformation::AlmostMaximumCapacity()");
-
-	return iAlmostFull;
-	} // CEnhancedVoiceMailBoxInformation::AlmostMaximumCapacity
-
-
-/**
- *  @publishedAll
- *  
- *  Used to set or reset the voice mail status to full.
- *  
- *  @param aIsStored
- *  Set to True the voice mail system is full.
- *  Set to False otherwise.
- *  
- *  @capability None
- */
-EXPORT_C void CEnhancedVoiceMailBoxInformation::SetMaximumCapacity(TBool aIsFull)
-	{
-	LOGGSMU1("CEnhancedVoiceMailBoxInformation::SetMaximumCapacity()");
-
-	iFull = aIsFull;
-	} // CEnhancedVoiceMailBoxInformation::SetMaximumCapacity
-
-
-/**
- *  @publishedAll
- *  
- *  Indicates whether the voice mail status is full.
- *  
- *  @return
- *  True if the voice mail system is almost full.
- *  False otherwise.
- *  
- *  @capability None
- */
-EXPORT_C TBool CEnhancedVoiceMailBoxInformation::MaximumCapacity() const
-	{
-	LOGGSMU1("CEnhancedVoiceMailBoxInformation::MaximumCapacity()");
-
-	return iFull;
-	} // CEnhancedVoiceMailBoxInformation::MaximumCapacity
-
-
-/**
- *  @publishedAll
- *  
- *  Indicates whether the message contains extension bytes
- *  
- *  @return
- *  True if the message contains extension bytes.
- *  False otherwise.
- *  
- *  @capability None
- */
-EXPORT_C TBool CEnhancedVoiceMailBoxInformation::ExtensionIndicator() const
-	{
-	LOGGSMU1("CEnhancedVoiceMailBoxInformation::ExtensionIndicator()");
-
-	return iExtensionIndicator;
-	} // CEnhancedVoiceMailBoxInformation::ExtensionIndicator
-
-
-void CEnhancedVoiceMailBoxInformation::NewBufferL(TInt aLength)
-	{
-	LOGGSMU2("CEnhancedVoiceMailBoxInformation::NewBufferL, length = %d",aLength);
-
-	HBufC* buffer=HBufC::NewL(aLength);
-	delete iAccessAddress;
-	iAccessAddress=buffer;
-	iAccessAddress->Des().SetLength(aLength);
-	iAccessAddress->Des().FillZ();
-	} // CEnhancedVoiceMailBoxInformation::NewBufferL
-
-
-/**
- *  @publishedAll
- *  
- *  Used to set the voice mail box number, overwriting any pre-existing number.
- *  
- *  @param aAddress
- *  The voice mail box address.
- *  
- *  @capability None
- */
-EXPORT_C void  CEnhancedVoiceMailBoxInformation::SetAccessAddressL(const TDesC& aAddress)
-	{
-	LOGGSMU1("CEnhancedVoiceMailBoxInformation::SetAccessAddressL()");
-
-	TInt length=aAddress.Length();
-	NewBufferL(length);
-	iAccessAddress->Des().Copy(aAddress);
-
-	const TGsmSmsTypeOfNumber typeofnumber=length && (iAccessAddress->Des()[0]=='+')? EGsmSmsTONInternationalNumber: EGsmSmsTONUnknown;
-	iTypeOfAddress.SetTON(typeofnumber);
-	} // CEnhancedVoiceMailBoxInformation::SetAccessAddressL
-
-
-/**
- *  @publishedAll
- *  
- *  Retrieves the voice mail box number.
- *  
- *  @return
- *  A pointer to the voice mail box number.
- *  
- *  @capability None
- */
-EXPORT_C TPtrC CEnhancedVoiceMailBoxInformation::AccessAddress() const
-	{
-	LOGGSMU1("CEnhancedVoiceMailBoxInformation::AccessAddress()");
-
-	TPtrC ptr;
-	if (iAccessAddress)
-	    ptr.Set(iAccessAddress->Des());
-	return ptr;
-	} // CEnhancedVoiceMailBoxInformation::AccessAddress
-
-
-/**
- *  @publishedAll
- *  
- *  Used to set the voice mail box number as a parsed address
- *  
- *  @param aParsedAddress
- *  The parsed address to be used as the voice mail box number.
- *  
- *  @capability None
- */
-EXPORT_C void  CEnhancedVoiceMailBoxInformation::SetParsedAccessAddressL(const TGsmSmsTelNumber& aParsedAddress)
-	{
-	LOGGSMU1("CEnhancedVoiceMailBoxInformation::SetParsedAccessAddressL()");
-
-   	iTypeOfAddress=aParsedAddress.iTypeOfAddress;
-	DoSetParsedAddressL(aParsedAddress.iTelNumber);
-	} // CEnhancedVoiceMailBoxInformation::SetParsedAccessAddressL
-
-
-/**
- *  @publishedAll
- *  
- *  Used to get the voice mail box number as a parsed address.
- *  
- *  @param aParsedAddress
- *  An output parameter which is set to the parsed address.
- *  
- *  @capability None
- */
-EXPORT_C void  CEnhancedVoiceMailBoxInformation::ParsedAccessAddress(TGsmSmsTelNumber& aParsedAddress) const
-	{
-	LOGGSMU1("CEnhancedVoiceMailBoxInformation::ParsedAccessAddress()");
-
-	aParsedAddress.iTypeOfAddress = iTypeOfAddress;
-
-	TInt maxparsedlength=aParsedAddress.iTelNumber.MaxLength();
-
-	if (iTypeOfAddress.TON()==EGsmSmsTONAlphaNumeric)
-		{
-		TInt parsedlength=AccessAddress().Length();
-		if (parsedlength>maxparsedlength)
-			parsedlength=maxparsedlength;
-		aParsedAddress.iTelNumber.Copy(AccessAddress().Mid(0,parsedlength));
-		}
-	else
-		{
-		aParsedAddress.iTelNumber.SetLength(maxparsedlength);
-
-		TInt length=iAccessAddress->Des().Length();
-		TInt parsedlength=0;
-		for (TInt i=0; (i<length) && (parsedlength<maxparsedlength); i++)
-			{
-			TText ch=iAccessAddress->Des()[i];
-			if ((ch>='0') && (ch<='9'))
-				{
-				aParsedAddress.iTelNumber[parsedlength]=(TUint8) ch;
-				parsedlength++;
-				}
-			}
-
-		aParsedAddress.iTelNumber.SetLength(parsedlength);
-		}
-	} // CEnhancedVoiceMailBoxInformation::ParsedAccessAddress
-
-
-void CEnhancedVoiceMailBoxInformation::DoSetParsedAddressL(const TDesC& aAddress)
-	{
-	LOGGSMU1("CEnhancedVoiceMailBoxInformation::DoSetParsedAddressL()");
-
-	TInt length=aAddress.Length();
-	if ((iTypeOfAddress.TON()==EGsmSmsTONInternationalNumber) &&
-	    (length && (aAddress[0]!='+')))
-		{
-		NewBufferL(length+1);
-		iAccessAddress->Des()[0]='+';
-		TPtr ptr((TText*) (iAccessAddress->Des().Ptr()+1),length,length);
-		ptr.Copy(aAddress);
-		}
-	else
-		{
-		NewBufferL(length);
-		iAccessAddress->Des().Copy(aAddress);
-		}
-	} // CEnhancedVoiceMailBoxInformation::DoSetParsedAddressL
-
-
-/**
- *  @publishedAll
- *  
- *  Sets the number of voice messages to a value in the range 0 to 255.
- *  
- *  @param aNumber
- *  The number of voice messages.
- *  
- *  @capability None
- */
-EXPORT_C void   CEnhancedVoiceMailBoxInformation::SetNumberOfVoiceMessages(TUint8 aNumber)
-	{
-	LOGGSMU1("CEnhancedVoiceMailBoxInformation::SetNumberOfVoiceMessages()");
-
-	iNumberOfVoiceMessages=aNumber;
-	} // CEnhancedVoiceMailBoxInformation::SetNumberOfVoiceMessages
-
-
-/**
- *  @publishedAll
- *  
- *  Retrieves the number of voice messages that are unread.
- *  
- *  @return
- *  The number of unread voice messages.
- *  
- *  @capability None
- */
-EXPORT_C TUint8 CEnhancedVoiceMailBoxInformation::NumberOfVoiceMessages() const
-	{
-	LOGGSMU1("CEnhancedVoiceMailBoxInformation::NumberOfVoiceMessages()");
-
-	return iNumberOfVoiceMessages;
-	} // CEnhancedVoiceMailBoxInformation::NumberOfVoiceMessages
-
-
-TUint8* CEnhancedVoiceMailBoxInformation::EncodeL(TUint8* aPtr, CCnvCharacterSetConverter& aCharacterSetConverter, RFs& aFs) const
-	{
-	*aPtr =  (((TUint8) iType)       & EMask1Bit )       +
-	        ((((TUint8) iProfile)    & EMask2Bits) << 2) +
-	        ((((TUint8) iStorage)    & EMask1Bit ) << 4) +
-	        ((((TUint8) iAlmostFull) & EMask1Bit ) << 5) +
-	        ((((TUint8) iFull)       & EMask1Bit ) << 6) +
-	         (((TUint8) iExtensionIndicator      ) << 7);
-
-	LOGGSMU2("CEnhancedVoiceMailBoxInformation::EncodeL 1st byte = %d",*aPtr);
-	aPtr++;
-
-	// Create an address object to encode the mail box access address into the
-	// format required by 23.040 v6.5.0 section 9.1.2.5.
-	CSmsAddress* address = CSmsAddress::NewL(aCharacterSetConverter,aFs);
-	CleanupStack::PushL(address);
-	TPtrC accessAddressPtr;
-	if (iAccessAddress)
-	    {
-		accessAddressPtr.Set(iAccessAddress->Des());
-	    }
-	address->SetRawAddressL(iTypeOfAddress,accessAddressPtr);
-	aPtr = address->EncodeL(aPtr);
-	CleanupStack::PopAndDestroy(address);
-
-	*aPtr = (TUint8) iNumberOfVoiceMessages;
-	aPtr++;
-
-	return aPtr;
-	} // CEnhancedVoiceMailBoxInformation::EncodeL
-
-
-void CEnhancedVoiceMailBoxInformation::DecodeL(TGsmuLex8& aVoiceMailInfo, CCnvCharacterSetConverter& aCharacterSetConverter, RFs& aFs)
-	{
-	TUint8 Byte1 = aVoiceMailInfo.GetL();
-
-	iType               = (TVoiceMailInfoType)       (Byte1       & EMask1Bit);
-	iProfile            = (TSmsMessageProfileType ) ((Byte1 >> 2) & EMask2Bits);
-	iStorage            = (TBool)                   ((Byte1 >> 4) & EMask1Bit);
-	iAlmostFull         = (TBool)                   ((Byte1 >> 5) & EMask1Bit);
-	iFull               = (TBool)                   ((Byte1 >> 6) & EMask1Bit);
-	iExtensionIndicator = (TBool)                   ((Byte1 >> 7) & EMask1Bit);
-
-	LOGGSMU2("CEnhancedVoiceMailBoxInformation::DecodeL 1st byte = %d", Byte1);
-
-	// Create an address object to deccode the mail box access address from the
-	// format required by 23.040 v6.5.0 section 9.1.2.5.
-	CSmsAddress* decodedAddress = CSmsAddress::NewL(aCharacterSetConverter,aFs);
-	CleanupStack::PushL(decodedAddress);
-
-	// CSmsAddress::DecodeL is also used to decode source and destination addresses.
-	// CSmsAddress::DecodeL expects internally that alphanumeric addresses will be size
-	// CSmsAddress::KSmsAddressMaxAddressValueLength=10.
-	// Need to add padding bytes to bring the address field up to the maximum size.
-	const TPtrC8 remainder(aVoiceMailInfo.Remainder());
-
-	if (remainder.Length() < CSmsAddress::KSmsAddressMaxAddressLength)
-	    {
-	    TBuf8<CSmsAddress::KSmsAddressMaxAddressLength> data;
-	    data = remainder;
-	    TInt actualLength = data.Length();
-	    data.SetLength(CSmsAddress::KSmsAddressMaxAddressLength);
-
-	    for (TUint8 j = actualLength; j < CSmsAddress::KSmsAddressMaxAddressLength; j++)
-	        {
-	        data[j] = 0;
-	        }
-
-	    TGsmuLex8 encodedAddress(data);
-	    decodedAddress->DecodeL(encodedAddress);
-	    // might want to check that aVoiceMailInfo can be incremented
-	    // by encodedAddress.Offset.
-	    aVoiceMailInfo.Inc(encodedAddress.Offset());
-	    }
-	else
-	    {
-	    decodedAddress->DecodeL(aVoiceMailInfo);
-	    }
-
-	TInt length=(decodedAddress->Address()).Length();
-	NewBufferL(length);
-	iAccessAddress->Des().Copy((decodedAddress->Address().Ptr()),length);
-
-	iTypeOfAddress = decodedAddress->TypeOfAddress();
-
-	CleanupStack::PopAndDestroy(decodedAddress);
-
-	iNumberOfVoiceMessages = aVoiceMailInfo.GetL();
-	LOGGSMU2("CEnhancedVoiceMailBoxInformation::DecodeL iNumberOfVoiceMessages = %d", iNumberOfVoiceMessages);
-	} // CEnhancedVoiceMailBoxInformation::DecodeL
-
-
-CEnhancedVoiceMailBoxInformation::CEnhancedVoiceMailBoxInformation()
-	{
-	LOGGSMU1("CEnhancedVoiceMailBoxInformation::CEnhancedVoiceMailBoxInformation()");
-
-	// Consider changing this over to a Panic.
-	iType               = EGsmSmsVoiceMailNotification;
-	iOctet1Bit1         = EFalse;
-	iProfile            = EGsmSmsProfileId1;
-	iStorage            = EFalse;
-	iAlmostFull         = EFalse;
-	iFull               = EFalse;
-	iExtensionIndicator = EFalse;
-	iTypeOfAddress      = 0;
-	} // CEnhancedVoiceMailBoxInformation::CEnhancedVoiceMailBoxInformation
-
-
-CEnhancedVoiceMailBoxInformation::CEnhancedVoiceMailBoxInformation(TVoiceMailInfoType aTVoiceMailInfoType)
-	{
-	LOGGSMU1("CEnhancedVoiceMailBoxInformation::CEnhancedVoiceMailBoxInformation()");
-
-	iType               = aTVoiceMailInfoType;
-	iOctet1Bit1         = EFalse;
-	iProfile            = EGsmSmsProfileId1;
-	iStorage            = EFalse;
-	iAlmostFull         = EFalse;
-	iFull               = EFalse;
-	iExtensionIndicator = EFalse;
-	iTypeOfAddress      = 0;
-	} // CEnhancedVoiceMailBoxInformation::CEnhancedVoiceMailBoxInformation
-
-
-/**
- *  @internalComponent
- *  
- *  Prevent clients from using the copy constructor by including it in the class definition
- *  but making it protected and not exporting it.
- *  
- *  @capability None
- */
-CEnhancedVoiceMailBoxInformation::CEnhancedVoiceMailBoxInformation(const CEnhancedVoiceMailBoxInformation&)
-    {
-    // Ignore in code coverage - not intended to be used
-    BULLSEYE_OFF    
-    LOGGSMU1("CEnhancedVoiceMailBoxInformation::CEnhancedVoiceMailBoxInformation");
-    Panic(KGsmuPanicMethodBodyNotImplemented);
-    BULLSEYE_RESTORE
-    }
-
-/**
- *  @internalComponent
- *  
- *  Prevent clients from using the equality operator by including it in the class definition
- *  but making it protected and not exporting it.
- *  
- *  @capability None
- */
-TBool CEnhancedVoiceMailBoxInformation::operator==(const CEnhancedVoiceMailBoxInformation&)
-    {
-    // Ignore in code coverage - not intended to be used
-    BULLSEYE_OFF    
-    LOGGSMU1("CEnhancedVoiceMailBoxInformation::operator==");
-    Panic(KGsmuPanicMethodBodyNotImplemented);
-    return EFalse;
-    BULLSEYE_RESTORE
-    }
-
-/**
- *  @internalComponent
- *  
- *  Prevent clients from using the assignment operator by including it in the class definition
- *  but making it protected and not exporting it.
- *  
- *  @capability None
- */
-void CEnhancedVoiceMailBoxInformation::operator=(const CEnhancedVoiceMailBoxInformation&)
-    {
-    // Ignore in code coverage - not intended to be used
-    BULLSEYE_OFF    
-    LOGGSMU1("CEnhancedVoiceMailBoxInformation::operator=");
-    Panic(KGsmuPanicMethodBodyNotImplemented);
-    BULLSEYE_RESTORE
-    }
-
-void CEnhancedVoiceMailBoxInformation::ConstructL()
-	{
-	LOGGSMU1("CEnhancedVoiceMailBoxInformation::ConstructL()");
-
-	NewBufferL(0);
-	} // CEnhancedVoiceMailBoxInformation::ConstructL
-
-
-CEnhancedVoiceMailBoxInformation::~CEnhancedVoiceMailBoxInformation()
-	{
-	LOGGSMU1("CEnhancedVoiceMailBoxInformation::~CEnhancedVoiceMailBoxInformation");
-	delete iAccessAddress;
-	} // CEnhancedVoiceMailBoxInformation::ConstructL
-
-
-CEnhancedVoiceMailBoxInformation* CEnhancedVoiceMailBoxInformation::NewL()
-	{
-	LOGGSMU1("CEnhancedVoiceMailBoxInformation::NewL()");
-
-	CEnhancedVoiceMailBoxInformation* aCEnhancedVoiceMailBoxInformation=new(ELeave) CEnhancedVoiceMailBoxInformation();
-	CleanupStack::PushL(aCEnhancedVoiceMailBoxInformation);
-	aCEnhancedVoiceMailBoxInformation->ConstructL();
-	CleanupStack::Pop(aCEnhancedVoiceMailBoxInformation);
-	return aCEnhancedVoiceMailBoxInformation;
-	} // CEnhancedVoiceMailBoxInformation::NewL
-
-
-/**
- *  @publishedAll
- *  
- *  Sets the message id to a value between 0 and 65535.
- *  
- *  @param aNumber
- *  The message id
- *  
- *  @capability None
- */
-EXPORT_C void CVoiceMailNotification::SetMessageId(TUint16 aMessageId)
-	{
-	LOGGSMU1("CVoiceMailNotification::SetMessageId()");
-
-	iMessageId = aMessageId;
-	} // CVoiceMailNotification::SetMessageId
-
-
-/**
- *  @publishedAll
- *  
- *  Retrieves the message id, a value in the range 0 to 65535.
- *  
- *  @return
- *  The message id,
- *  
- *  @capability None
- */
-EXPORT_C TUint16 CVoiceMailNotification::MessageId() const
-	{
-	LOGGSMU1("CVoiceMailNotification::MessageId()");
-
-	return iMessageId;
-	} // CVoiceMailNotification::MessageId
-
-
-/**
- *  @publishedAll
- *  
- *  Sets the voice mail message length to a value between 0 and 255
- *  
- *  @param aLength
- *  The voice mail message length.
- *  
- *  @capability None
- */
-EXPORT_C void CVoiceMailNotification::SetMessageLength(TUint8 aLength)
-	{
-	LOGGSMU1("CVoiceMailNotification::SetMessageLength()");
-
-	iMessageLength=aLength;
-	} // CVoiceMailNotification::SetMessageLength
-
-
-/**
- *  @publishedAll
- *  
- *  Retrieves the voice mail message length, a value in the range 0 to 255.
- *  
- *  @return
- *  The voice mail message length.
- *  
- *  @capability None
- */
-EXPORT_C TUint8 CVoiceMailNotification::MessageLength() const
-	{
-	LOGGSMU1("CVoiceMailNotification::MessageLength()");
-
-	return iMessageLength;
-	} // CVoiceMailNotification::MessageLength
-
-
-/**
- *  @publishedAll
- *  
- *  Sets the number of days that the voice message will be retained to
- *  a value between 0 and 31. Values in excess of 31 will be capped at
- *  31.
- *  
- *  @param aDays
- *  The number of retention days.
- *  
- *  @capability None
- */
-EXPORT_C void CVoiceMailNotification::SetRetentionDays(TUint8 aDays)
-	{
-	LOGGSMU1("CVoiceMailNotification::SetRetentionDays()");
-
-	if (aDays > 31)
-	    {
-	    iRetentionDays = 31;
-	    }
-	else
-	    {
-	    iRetentionDays = aDays;
-	    }
-	} // CVoiceMailNotification::SetRetentionDays
-
-
-/**
- *  @publishedAll
- *  
- *  Retrieves the number of days the voice message will be retained.
- *  
- *  @return
- *  The number of days the voice message will be retained.
- *  
- *  @capability None
- */
-EXPORT_C TUint8 CVoiceMailNotification::RetentionDays() const
-	{
-	LOGGSMU1("CVoiceMailNotification::RetentionDays()");
-
-	return iRetentionDays;
-	} // CVoiceMailNotification::RetentionDays
-
-
-/**
- *  @publishedAll
- *  
- *  Sets the message priority to urgent
- *  
- *  @param aPriority
- *  Set to True if the priority is urgent,
- *  Otherwise set to False.
- *  
- *  @capability None
- */
-EXPORT_C void CVoiceMailNotification::SetPriorityIndication(TBool aPriority)
-	{
-	LOGGSMU1("CVoiceMailNotification::SetPriorityIndication()");
-
-	iPriorityIndication=aPriority;
-	} // CVoiceMailNotification::SetPriorityIndication
-
-
-/**
- *  @publishedAll
- *  
- *  Retrieves the priority indication.
- *  
- *  @return
- *  True if the priority is urgent,
- *  False otherwise.
- *  
- *  @capability None
- */
-EXPORT_C TBool CVoiceMailNotification::PriorityIndication() const
-	{
-	LOGGSMU1("CVoiceMailNotification::PriorityIndication()");
-
-	return iPriorityIndication;
-	} // CVoiceMailNotification::PriorityIndication
-
-
-/**
- *  @publishedAll
- *  
- *  Indicates whether the voice mail notification contains extension bytes.
- *  
- *  @return
- *  True if the voice mail notification contains extension bytes.
- *  False otherwise.
- *  
- *  @capability None
- */
-EXPORT_C TBool CVoiceMailNotification::MessageExtensionIndication() const
-	{
-	LOGGSMU1("CVoiceMailNotification::MessageExtensionIndication()");
-
-	return iMessageExtensionIndicator;
-	} // CVoiceMailNotification::MessageExtensionIndication
-
-
-void CVoiceMailNotification::NewBufferL(TInt aLength)
-	{
-	LOGGSMU1("CVoiceMailNotification::NewBufferL()");
-
-	HBufC* buffer=HBufC::NewL(aLength);
-	delete iCallingLineIdentity;
-	iCallingLineIdentity=buffer;
-	iCallingLineIdentity->Des().SetLength(aLength);
-	iCallingLineIdentity->Des().FillZ();
-	} // CVoiceMailNotification::NewBufferL
-
-
-/**
- *  @publishedAll
- *  
- *  Used to set the calling line idenity
- *  
- *  @param aLineIdentity
- *  
- *  @capability None
- */
-EXPORT_C void  CVoiceMailNotification::SetCallingLineIdentityL(TDesC& aLineIdentity)
-	{
-	LOGGSMU1("CVoiceMailNotification::SetCallingLineIdentityL()");
-
-	TInt length=aLineIdentity.Length();
-	NewBufferL(length);
-	iCallingLineIdentity->Des().Copy(aLineIdentity);
-
-	const TGsmSmsTypeOfNumber typeofnumber=length && (iCallingLineIdentity->Des()[0]=='+')? EGsmSmsTONInternationalNumber: EGsmSmsTONUnknown;
-	iTypeOfAddress.SetTON(typeofnumber);
-	} // CVoiceMailNotification::SetCallingLineIdentityL
-
-
-/**
- *  @publishedAll
- *  
- *  Retrieves the Calling Line Identity
- *  
- *  @return
- *  A pointer to the Calling Line Identity.
- *  
- *  @capability None
- */
-EXPORT_C TPtrC CVoiceMailNotification::CallingLineIdentity() const
-	{
-	LOGGSMU1("CVoiceMailNotification::CallingLineIdentity()");
-
-	TPtrC ptr;
-	if (iCallingLineIdentity)
-	    ptr.Set(iCallingLineIdentity->Des());
-	return ptr;
-	} // CVoiceMailNotification::CallingLineIdentity
-
-
-/**
- *  @publishedAll
- *  
- *  Set the Calling Line Id as a parsed address.
- *  
- *  @param aParsedAddress
- *  The Calling Line Id as a parsed address.
- *  
- *  @capability None
- */
-EXPORT_C void CVoiceMailNotification::SetParsedCallingLineIdentityL(TGsmSmsTelNumber& aParsedAddress)
-	{
-	LOGGSMU1("CVoiceMailNotification::SetParsedCallingLineIdentityL()");
-
-	iTypeOfAddress=aParsedAddress.iTypeOfAddress;
-	DoSetParsedAddressL(aParsedAddress.iTelNumber);
-	} // CVoiceMailNotification::SetParsedCallingLineIdentityL
-
-
-/**
- *  @publishedAll
- *  
- *  Gets the Calling Line Id as a parsed address.
- *  
- *  @param aParsedAddress
- *  An output parameter which is to be set to the parsed calling line ID.
- *  
- *  @capability None
- */
-EXPORT_C void CVoiceMailNotification::ParsedCallingLineIdentity(TGsmSmsTelNumber& aParsedAddress) const
-	{
-	LOGGSMU1("CVoiceMailNotification::ParsedCallingLineIdentity()");
-
-	aParsedAddress.iTypeOfAddress = iTypeOfAddress;
-
-	TInt maxparsedlength=aParsedAddress.iTelNumber.MaxLength();
-
-	if (iTypeOfAddress.TON()==EGsmSmsTONAlphaNumeric)
-		{
-		TInt parsedlength=CallingLineIdentity().Length();
-		if (parsedlength>maxparsedlength)
-			parsedlength=maxparsedlength;
-		aParsedAddress.iTelNumber.Copy(CallingLineIdentity().Mid(0,parsedlength));
-		}
-	else
-		{
-		aParsedAddress.iTelNumber.SetLength(maxparsedlength);
-
-		TInt length=iCallingLineIdentity->Des().Length();
-		TInt parsedlength=0;
-		for (TInt i=0; (i<length) && (parsedlength<maxparsedlength); i++)
-			{
-			TText ch=iCallingLineIdentity->Des()[i];
-			if ((ch>='0') && (ch<='9'))
-				{
-				aParsedAddress.iTelNumber[parsedlength]=(TUint8) ch;
-				parsedlength++;
-				}
-			}
-
-		aParsedAddress.iTelNumber.SetLength(parsedlength);
-		}
-	} // CVoiceMailNotification::ParsedCallingLineIdentity
-
-
-void CVoiceMailNotification::NewExtensionL(TInt aLength)
-	{
-	LOGGSMU1("CVoiceMailNotification::NewExtensionL()");
-
-	HBufC* buffer=HBufC::NewL(aLength);
-	delete iExtension;
-	iExtension=buffer;
-	iExtension->Des().SetLength(aLength);
-	iExtension->Des().FillZ();
-	} // CVoiceMailNotification::NewExtensionL
-
-
-/*void CVoiceMailNotification::SetExtension(TDesC& aExtension)
-	{
-	LOGGSMU1("CVoiceMailNotification::SetExtension()");
-
-	TInt length=aExtension.Length();
-	NewExtensionL(length);
-	iExtension->Des().Copy(aExtension);
-	} // CVoiceMailNotification::SetExtension
-
-TPtrC CVoiceMailNotification::Extension() const
-	{
-	LOGGSMU1("CVoiceMailNotification::Extension()");
-
-	TPtrC ptr;
-	if (iExtension)
-	    ptr.Set(iExtension->Des());
-	return ptr;
-	}*/
-
-
-/**
- *  @internalComponent
- *  
- *  Determines the size of the encoded Voice Mail Notification.
- *  
- *  @param aCharacterSetConverter  A reference to a character set converter.
- *  @param aFs  A reference to the file server.
- *  @return The size of the encoded Voice Mail Notification
- *  
- *  @capability None
- */
-TUint8 CVoiceMailNotification::SizeL(CCnvCharacterSetConverter& aCharacterSetConverter, RFs& aFs)
-	{
-	LOGGSMU1("CVoiceMailNotification::SizeL()");
-
-	const TUint8 KTotalSizeOfFixedLengthAttributes = 4;
-	TUint8 size = KTotalSizeOfFixedLengthAttributes;
-
-	// need to find the size of the calling line ID.
-	CSmsAddress* address = CSmsAddress::NewL(aCharacterSetConverter,aFs);
-	CleanupStack::PushL(address);
-
-	TPtrC callingLineIdentityPtr;
-	if (iCallingLineIdentity)
-	    {
-		callingLineIdentityPtr.Set(iCallingLineIdentity->Des());
-	    }
-
-	address->SetRawAddressL(iTypeOfAddress,callingLineIdentityPtr);
-
-	size += address->SizeL();
-	CleanupStack::PopAndDestroy(address);
-
-	return size;
-	} // CVoiceMailNotification::SizeL
-
-
-TUint8* CVoiceMailNotification::EncodeL(TUint8* aPtr, CCnvCharacterSetConverter& aCharacterSetConverter, RFs& aFs) const
-	{
-	// When changes are made to this function that affect the
-	// number of bytes that are encoded, this should be reflected in
-	// CVoiceMailNotification::SizeL()
-	LOGGSMU1("CVoiceMailNotification::EncodeL");
-
-
-	*aPtr =   (TUint8)  (iMessageId                         >> 8);  // Message Id MSB
-	aPtr++;
-	*aPtr =   (TUint8)   iMessageId;                                // Message Id LSB
-	aPtr++;
-	*aPtr =   (TUint8)   iMessageLength;
-	aPtr++;
-	*aPtr =   ((TUint8)  (iRetentionDays & EMask5Bits))             +
-	         (((TUint8)   iPriorityIndication)               << 6)  +
-	         (((TUint8)   iMessageExtensionIndicator)        << 7);
-	aPtr++;
-
-	CSmsAddress* address = CSmsAddress::NewL(aCharacterSetConverter,aFs);
-	CleanupStack::PushL(address);
-
-	TPtrC callingLineIdentityPtr;
-	if (iCallingLineIdentity)
-	    {
-		callingLineIdentityPtr.Set(iCallingLineIdentity->Des());
-	    }
-
-	address->SetRawAddressL(iTypeOfAddress,callingLineIdentityPtr);
-
-	aPtr = address->EncodeL(aPtr);
-	CleanupStack::PopAndDestroy(address);
-
-	return aPtr;
-	} // CVoiceMailNotification::EncodeL
-
-
-void CVoiceMailNotification::DecodeL(TGsmuLex8& aVoiceMailInfo, CCnvCharacterSetConverter& aCharacterSetConverter, RFs& aFs)
-	{
-	LOGGSMU1("CVoiceMailNotification::DecodeL");
-
-	iMessageId = (((TUint16) aVoiceMailInfo.GetL()) << 8);
-	iMessageId += ((TUint16) aVoiceMailInfo.GetL());
-
-	iMessageLength=aVoiceMailInfo.GetL();
-
-	TUint8 currentByte = aVoiceMailInfo.GetL();
-
-	iRetentionDays             =   currentByte       & EMask5Bits;
-	iPriorityIndication        = ((currentByte >> 6) & EMask1Bit);
-	iMessageExtensionIndicator = ((currentByte >> 7) & EMask1Bit);
-
-	CSmsAddress* decodedAddress = CSmsAddress::NewL(aCharacterSetConverter,aFs);
-	CleanupStack::PushL(decodedAddress);
-
-	const TPtrC8 remainder(aVoiceMailInfo.Remainder());
-	// The address information element makes an assumption that aVoiceMail must
-	// be of size CSmsAddress::KSmsAddressMaxAddressLength
-	// Provide padding to ensure that this is the case.
-	if (remainder.Length() < CSmsAddress::KSmsAddressMaxAddressLength)
-	    {
-	    TBuf8<CSmsAddress::KSmsAddressMaxAddressLength> data;
-	    data = remainder;
-	    TInt actualLength = data.Length();
-	    data.SetLength(CSmsAddress::KSmsAddressMaxAddressLength);
-
-	    for (TUint8 j = actualLength; j < CSmsAddress::KSmsAddressMaxAddressLength; j++)
-	        {
-	        data[j] = 0;
-	        }
-
-	    TGsmuLex8 encodedAddress(data);
-	    decodedAddress->DecodeL(encodedAddress);
-	    // Should be the last piece of data to be decoded
-	    // The next line is included for completeness.
-	    aVoiceMailInfo.Inc(encodedAddress.Offset());
-	    }
-	else
-	    {
-	    decodedAddress->DecodeL(aVoiceMailInfo);
-	    }
-
-	TInt length=(decodedAddress->Address()).Length();
-	NewBufferL(length);
-	iCallingLineIdentity->Des().Copy((decodedAddress->Address().Ptr()),length);
-
-	iTypeOfAddress = decodedAddress->TypeOfAddress();
-
-	CleanupStack::PopAndDestroy(decodedAddress);
-
-	if (iMessageExtensionIndicator)
-	    {
-	    TUint8 extensionLength = aVoiceMailInfo.GetL();
-	    aVoiceMailInfo.Inc(extensionLength);
-	    }
-	} // CVoiceMailNotification::DecodeL
-
-
-/**
- *  @internalComponent
- *  
- *  Prevent clients from using the copy constructor by including it in the class definition
- *  but making it protected and not exporting it.
- *  
- *  @capability None
- */
-CVoiceMailNotification::CVoiceMailNotification(const CVoiceMailNotification&)
-    {
-    // Ignore in code coverage - not intended to be used
-    BULLSEYE_OFF    
-    LOGGSMU1("CVoiceMailNotification::CVoiceMailNotification");
-    Panic(KGsmuPanicMethodBodyNotImplemented);
-    BULLSEYE_RESTORE
-    }
-
-/**
- *  @internalComponent
- *  
- *  Prevent clients from using the equality operator by including it in the class definition
- *  but making it protected and not exporting it.
- *  
- *  @capability None
- */
-TBool CVoiceMailNotification::operator==(const CVoiceMailNotification&)
-    {
-    // Ignore in code coverage - not intended to be used
-    BULLSEYE_OFF    
-    LOGGSMU1("CVoiceMailNotification::operator==");
-    Panic(KGsmuPanicMethodBodyNotImplemented);
-    return EFalse;
-    BULLSEYE_RESTORE
-    }
-
-/**
- *  @internalComponent
- *  
- *  Prevent clients from using the assignment operator by including it in the class definition
- *  but making it protected and not exporting it.
- *  
- *  @capability None
- */
-void CVoiceMailNotification::operator=(const CVoiceMailNotification&)
-    {
-    // Ignore in code coverage - not intended to be used
-    BULLSEYE_OFF    
-    LOGGSMU1("CVoiceMailNotification::operator=");
-    Panic(KGsmuPanicMethodBodyNotImplemented);
-    BULLSEYE_RESTORE
-    }
-
-CVoiceMailNotification::CVoiceMailNotification()
-	{
-	LOGGSMU1("CVoiceMailNotification::CVoiceMailNotification()");
-
-	iMessageId                 = 0;
-	iMessageLength             = 0;
-	iRetentionDays             = 0;
-	iOctetN8Bit1               = EFalse;
-	iPriorityIndication        = EFalse;
-	iMessageExtensionIndicator = EFalse;
-	iTypeOfAddress             = 0;
-	} // CVoiceMailNotification::CVoiceMailNotification
-
-
-/**
- *  @publishedAll
- *  
- *  Class Destructor
- *  
- *  @capability None
- */
-EXPORT_C CVoiceMailNotification::~CVoiceMailNotification()
-	{
-	LOGGSMU1("CVoiceMailNotification::~CVoiceMailNotification");
-	delete iCallingLineIdentity;
-	delete iExtension;
-	} // CVoiceMailNotification::CVoiceMailNotification
-
-
-void CVoiceMailNotification::ConstructL()
-	{
-	LOGGSMU1("CVoiceMailNotification::ConstructL()");
-
-	NewBufferL(0);
-	NewExtensionL(0);
-	} // CVoiceMailNotification::ConstructL
-
-
-/**
- *  @publishedAll
- *  
- *  Class construction method.
- *  
- *  @capability None
- */
-EXPORT_C CVoiceMailNotification* CVoiceMailNotification::NewL()
-	{
-	LOGGSMU1("CVoiceMailNotification::NewL()");
-
-	CVoiceMailNotification* aCVoiceMailNotification=new(ELeave) CVoiceMailNotification();
-	CleanupStack::PushL(aCVoiceMailNotification);
-	aCVoiceMailNotification->ConstructL();
-	CleanupStack::Pop(aCVoiceMailNotification);
-	return aCVoiceMailNotification;
-	} // CVoiceMailNotification::NewL
-
-
-void CVoiceMailNotification::DoSetParsedAddressL(const TDesC& aAddress)
-	{
-	LOGGSMU1("CVoiceMailNotification::DoSetParsedAddressL()");
-
-	TInt length=aAddress.Length();
-	if ((iTypeOfAddress.TON()==EGsmSmsTONInternationalNumber) &&
-	    (length && (aAddress[0]!='+')))
-		{
-		NewBufferL(length+1);
-		iCallingLineIdentity->Des()[0]='+';
-		TPtr ptr((TText*) (iCallingLineIdentity->Des().Ptr()+1),length,length);
-		ptr.Copy(aAddress);
-		}
-	else
-		{
-		NewBufferL(length);
-		iCallingLineIdentity->Des().Copy(aAddress);
-		}
-	} // CVoiceMailNotification::DoSetParsedAddressL
-
-
-/**
- *  @publishedAll
- *  
- *  Retrieves the number of voice message notifications contained in
- *  this information. The range is 0 to 15.
- *  
- *  @return
- *  The number of voice message notifications in this information element.
- *  
- *  @capability None
- */
-EXPORT_C TUint8 CEnhancedVoiceMailNotification::NumberOfVoiceMails()
-	{
-	LOGGSMU1("CEnhancedVoiceMailNotification::NumberOfVoiceMails()");
-
-	return (TUint8) iNotifications->Count();
-	} // CEnhancedVoiceMailNotification::NumberOfVoiceMails
-
-
-/*void CEnhancedVoiceMailNotification::SetExtension(TDesC& aExtension)
-	{
-	LOGGSMU1("CEnhancedVoiceMailNotification::SetExtension()");
-
-	TInt length=aExtension.Length();
-	NewExtensionL(length);
-	iExtension->Des().Copy(aExtension);
-	} // CEnhancedVoiceMailNotification::SetExtension
-
-TPtrC CEnhancedVoiceMailNotification::Extension() const
-	{
-	LOGGSMU1("CEnhancedVoiceMailNotification::Extension()");
-
-	TPtrC ptr;
-	if (iExtension)
-	    ptr.Set(iExtension->Des());
-	return ptr;
-	}*/
-
-
-/**
- *  @publishedAll
- *  
- *  Provides a reference to the collection that is used to contain the Voice Mail Notifications.
- *  A maximum of 15 voice mail confirmations is supported. If more that 15 voice mails notifications are added
- *  the CEnhancedVoiceMailNotification will not be added to the CSmsMessage by the CSmsEnhancedVoiceMailOperations
- *  class.
- *  
- *  @return
- *  A reference to the collection that is used to contain the Voice Mail Notifications.
- *  
- *  @capability None
- */
-EXPORT_C RPointerArray<CVoiceMailNotification>& CEnhancedVoiceMailNotification::GetVoiceMailNotifications()
-	{
-	LOGGSMU1("CEnhancedVoiceMailNotification::GetVoiceMailNotifications()");
-
-	return *iNotifications;
-	} // CEnhancedVoiceMailNotification::GetVoiceMailNotifications
-
-
-void CEnhancedVoiceMailNotification::NewExtensionL(TInt aLength)
-	{
-	LOGGSMU1("CEnhancedVoiceMailNotification::NewExtensionL()");
-
-	HBufC* buffer=HBufC::NewL(aLength);
-	delete iExtension;
-	iExtension=buffer;
-	iExtension->Des().SetLength(aLength);
-	iExtension->Des().FillZ();
-	} // CEnhancedVoiceMailNotification::NewExtensionL
-
-
-/**
- *  @publishedAll
- *  
- *  Class construction method.
- *  
- *  @capability None
- */
-EXPORT_C  CEnhancedVoiceMailNotification* CEnhancedVoiceMailNotification::NewL()
-	{
-	LOGGSMU1("CEnhancedVoiceMailNotification::NewL()");
-
-	CEnhancedVoiceMailNotification* aCEnhancedVoiceMailNotification=new(ELeave) CEnhancedVoiceMailNotification();
-	CleanupStack::PushL(aCEnhancedVoiceMailNotification);
-	aCEnhancedVoiceMailNotification->CEnhancedVoiceMailBoxInformation::ConstructL();
-	aCEnhancedVoiceMailNotification->ConstructL();
-	CleanupStack::Pop(aCEnhancedVoiceMailNotification);
-	return aCEnhancedVoiceMailNotification;
-	} // CEnhancedVoiceMailNotification::NewL
-
-
-CEnhancedVoiceMailNotification::CEnhancedVoiceMailNotification() : CEnhancedVoiceMailBoxInformation(EGsmSmsVoiceMailNotification)
-	{
-	} // CEnhancedVoiceMailNotification::CEnhancedVoiceMailNotification
-
-
-/**
- *  @internalComponent
- *  
- *  Prevent clients from using the copy constructor by including it in the class definition
- *  but making it protected and not exporting it.
- *  
- *  @capability None
- */
-CEnhancedVoiceMailNotification::CEnhancedVoiceMailNotification(const CEnhancedVoiceMailNotification&)
-    {
-    // Ignore in code coverage - not intended to be used
-    BULLSEYE_OFF    
-    LOGGSMU1("CEnhancedVoiceMailNotification::CEnhancedVoiceMailNotification");
-    Panic(KGsmuPanicMethodBodyNotImplemented);
-    BULLSEYE_RESTORE
-    }
-
-/**
- *  @internalComponent
- *  
- *  Prevent clients from using the equality operator by including it in the class definition
- *  but making it protected and not exporting it.
- *  
- *  @capability None
- */
-TBool CEnhancedVoiceMailNotification::operator==(const CEnhancedVoiceMailNotification&)
-    {
-    // Ignore in code coverage - not intended to be used
-    BULLSEYE_OFF    
-    LOGGSMU1("CEnhancedVoiceMailNotification::operator==");
-    Panic(KGsmuPanicMethodBodyNotImplemented);
-    return EFalse;
-    BULLSEYE_RESTORE
-    }
-
-/**
- *  @internalComponent
- *  
- *  Prevent clients from using the assignment operator by including it in the class definition
- *  but making it protected and not exporting it.
- *  
- *  @capability None
- */
-void CEnhancedVoiceMailNotification::operator=(const CEnhancedVoiceMailNotification&)
-    {
-    // Ignore in code coverage - not intended to be used
-    BULLSEYE_OFF    
-    LOGGSMU1("CEnhancedVoiceMailNotification::operator=");
-    Panic(KGsmuPanicMethodBodyNotImplemented);
-    BULLSEYE_RESTORE
-    }
-
-/**
- *  @publishedAll
- *  
- *  Class destructor.
- *  
- *  @capability None
- */
-EXPORT_C  CEnhancedVoiceMailNotification::~CEnhancedVoiceMailNotification()
-	{
-	LOGGSMU1("CEnhancedVoiceMailNotification::~CEnhancedVoiceMailNotification");
-	delete iExtension;
-	iNotifications->ResetAndDestroy();
-	iNotifications->Close();
-	delete iNotifications;
-	} // CEnhancedVoiceMailNotification::operator
-
-
-void CEnhancedVoiceMailNotification::ConstructL()
-	{
-	LOGGSMU1("CEnhancedVoiceMailNotification::ConstructL()");
-
-	NewExtensionL(0);
-	iNotifications = new (ELeave) RPointerArray<CVoiceMailNotification>(KMaxNumberOfNotifications);
-	} // CEnhancedVoiceMailNotification::ConstructL
-
-
-TUint8* CEnhancedVoiceMailNotification::EncodeL(TUint8* aCurrentPtr, CCnvCharacterSetConverter& aCharacterSetConverter, RFs& aFs) const
-	{
-	LOGGSMU1("CEnhancedVoiceMailNotification::EncodeL");
-
-	TUint8* startPtr   = aCurrentPtr;
-
-	aCurrentPtr = CEnhancedVoiceMailBoxInformation::EncodeL(aCurrentPtr, aCharacterSetConverter, aFs);
-
-	TUint8 count = (TUint8)  iNotifications->Count();
-	if (count > KMaxNumberOfNotifications)
-	    {
-	    User::Leave(KErrArgument);
-	    }
-
-	*aCurrentPtr = (count & KSmsNotificationBitMask);
-	aCurrentPtr++;
-
-	TInt16 spaceAlreadyAllocated = 0; // handle architectures whose address space increments and whose address space decrements.
-	(aCurrentPtr > startPtr) ? (spaceAlreadyAllocated = aCurrentPtr - startPtr) : (spaceAlreadyAllocated = startPtr - aCurrentPtr);
-
-	TInt16 remainingSize = (TInt16)(CEnhancedVoiceMailNotification::KSmsMaxEnhancedVoiceMailSize - spaceAlreadyAllocated);
-	for (TUint i = 0; i < count; i++)
-	    {
-	    remainingSize -= (TInt16)(*iNotifications)[i]->SizeL(aCharacterSetConverter,aFs);
-	    if (remainingSize < 0)
-	        {
-	        User::Leave(KErrArgument);
-	        }
-
-	    aCurrentPtr = (*iNotifications)[i]->EncodeL(aCurrentPtr, aCharacterSetConverter, aFs);
-	    }
-
-	return aCurrentPtr;
-	} // CEnhancedVoiceMailNotification::EncodeL
-
-
-void CEnhancedVoiceMailNotification::DecodeL(TGsmuLex8& aVoiceMailInfo, CCnvCharacterSetConverter& aCharacterSetConverter, RFs& aFs)
-	{
-	LOGGSMU1("CEnhancedVoiceMailNotification::DecodeL");
-
-	CEnhancedVoiceMailBoxInformation::DecodeL(aVoiceMailInfo, aCharacterSetConverter, aFs);
-
-	TUint8 numberOfNotifications = (aVoiceMailInfo.GetL() & KSmsNotificationBitMask);
-
-	if (iExtensionIndicator)
-	    {
-	    TUint8 extensionLength = aVoiceMailInfo.GetL();
-	    aVoiceMailInfo.Inc(extensionLength);
-	    }
-
-	for (TUint8 i = 0; i < numberOfNotifications; i++)
-	    {
-	    CVoiceMailNotification* voiceMailNotification = CVoiceMailNotification::NewL();
-	    CleanupStack::PushL(voiceMailNotification);
-	    voiceMailNotification->DecodeL(aVoiceMailInfo, aCharacterSetConverter, aFs);
-	    iNotifications->AppendL(voiceMailNotification);
-	    CleanupStack::Pop(voiceMailNotification);
-	    }
-	} // CEnhancedVoiceMailNotification::DecodeL
-
-
-/**
- *  @publishedAll
- *  
- *  Sets the message ID of the specific Voice Mail message
- *  whose deletion is being confirmed.
- *  
- *  @param aMessageId
- *  The message ID of the specific voice mail message whose deletion
- *  is being confirmed.
- *  
- *  @capability None
- */
-EXPORT_C void CVoiceMailDeletion::SetMessageId(TUint16 aMessageId)
-	{
-	LOGGSMU1("CVoiceMailDeletion::SetMessageId()");
-
-	iMessageId=aMessageId;
-	} // CVoiceMailDeletion::SetMessageId
-
-
-/**
- *  @publishedAll
- *  
- *  Retrieves the message ID of the Voice Mail message
- *  whose deletion is being confirmed, range 0 to 65535.
- *  
- *  @return
- *  The message ID of the Voice Mail message whose deletion
- *  is being confirmed, range 0 to 65535.
- *  
- *  @capability None
- */
-EXPORT_C TUint16 CVoiceMailDeletion::MessageId() const
-	{
-	LOGGSMU1("CVoiceMailDeletion::MessageId()");
-
-	return iMessageId;
-	} // CVoiceMailDeletion::MessageId
-
-
-/**
- *  @publishedAll
- *  
- *  Indicates whether the voice mail deletion contains extension bytes.
- *  
- *  @return
- *  True if the voice mail deletion contains extension bytes.
- *  False otherwise.
- *  
- *  @capability None
- */
-EXPORT_C TBool CVoiceMailDeletion::MessageExtensionIndication() const
-	{
-	LOGGSMU1("CVoiceMailDeletion::MessageExtensionIndication()");
-
-	return iExtensionIndicator;
-	} // CVoiceMailDeletion::MessageExtensionIndication
-
-
-TUint8 CVoiceMailDeletion::SizeL()
-	{
-	LOGGSMU1("CVoiceMailDeletion::SizeL()");
-
-	const TUint8 KSizeOfVoiceMailDeletion = 3;
-	return KSizeOfVoiceMailDeletion;
-	} // CVoiceMailDeletion::SizeL
-
-
-TUint8* CVoiceMailDeletion::EncodeL(TUint8* aPtr) const
-	{
-	// When changes are made which affect the
-	// number of bytes encoded, this should be
-	// reflected in VoiceMailDeletion::SizeL()
-	LOGGSMU1("CVoiceMailDeletion::EncodeL");
-
-	*aPtr =  (TUint8) (iMessageId >> 8);
-	aPtr++;
-	*aPtr =  (TUint8) iMessageId;
-	aPtr++;
-	*aPtr = ((TUint8) iExtensionIndicator) << 7;
-	aPtr++;
-	return aPtr;
-	} // CVoiceMailDeletion::EncodeL
-
-
-void CVoiceMailDeletion::DecodeL(TGsmuLex8& aVoiceMailInfo)
-	{
-	LOGGSMU1("CVoiceMailDeletion::DecodeL");
-
-	iMessageId = (((TUint16) aVoiceMailInfo.GetL()) << 8) +
-	              ((TUint16) aVoiceMailInfo.GetL());
-	iExtensionIndicator =    (aVoiceMailInfo.GetL() >> 7);
-
-	if (iExtensionIndicator)
-	    {
-	    TUint8 extensionLength = aVoiceMailInfo.GetL();
-	    aVoiceMailInfo.Inc(extensionLength);
-	    }
-	} // CVoiceMailDeletion::DecodeL
-
-
-CVoiceMailDeletion::CVoiceMailDeletion()
-	{
-	iMessageId = 0;
-	iExtensionIndicator = EFalse;
-	} // CVoiceMailDeletion::CVoiceMailDeletion
-
-
-/**
- *  @internalComponent
- *  
- *  Prevent clients from using the copy constructor by including it in the class definition
- *  but making it protected and not exporting it.
- *  
- *  @capability None
- */
-CVoiceMailDeletion::CVoiceMailDeletion(const CVoiceMailDeletion&)
-    {
-    // Ignore in code coverage - not intended to be used
-    BULLSEYE_OFF    
-    LOGGSMU1("CVoiceMailDeletion::CVoiceMailDeletion");
-    Panic(KGsmuPanicMethodBodyNotImplemented);
-    BULLSEYE_RESTORE
-    }
-
-/**
- *  @internalComponent
- *  
- *  Prevent clients from using the equality operator by including it in the class definition
- *  but making it protected and not exporting it.
- *  
- *  @capability None
- */
-TBool CVoiceMailDeletion::operator==(const CVoiceMailDeletion&)
-    {
-    // Ignore in code coverage - not intended to be used
-    BULLSEYE_OFF    
-    LOGGSMU1("CVoiceMailDeletion::operator==");
-    Panic(KGsmuPanicMethodBodyNotImplemented);
-    return EFalse;
-    BULLSEYE_RESTORE
-    }
-
-/**
- *  @internalComponent
- *  
- *  Prevent clients from using the assignment operator by including it in the class definition
- *  but making it protected and not exporting it.
- *  
- *  @capability None
- */
-void CVoiceMailDeletion::operator=(const CVoiceMailDeletion&)
-    {
-    // Ignore in code coverage - not intended to be used
-    BULLSEYE_OFF    
-    LOGGSMU1("CVoiceMailDeletion::operator=");
-    Panic(KGsmuPanicMethodBodyNotImplemented);
-    BULLSEYE_RESTORE
-    }
-
-/**
- *  @publishedAll
- *  
- *  Class destructor.
- *  
- *  @capability None
- */
-EXPORT_C CVoiceMailDeletion::~CVoiceMailDeletion()
-	{
-	LOGGSMU1("CVoiceMailDeletion::~CVoiceMailDeletion");
-
-	delete iExtension;
-	} // CVoiceMailDeletion::operator
-
-
-void CVoiceMailDeletion::ConstructL()
-	{
-	LOGGSMU1("CVoiceMailDeletion::ConstructL()");
-
-	NewBufferL(0);
-	} // CVoiceMailDeletion::ConstructL
-
-
-void CVoiceMailDeletion::NewBufferL(TInt aLength)
-	{
-	LOGGSMU1("CVoiceMailDeletion::NewBufferL()");
-
-	HBufC* buffer=HBufC::NewL(aLength);
-	delete iExtension;
-	iExtension=buffer;
-	iExtension->Des().SetLength(aLength);
-	iExtension->Des().FillZ();
-	} // CVoiceMailDeletion::NewBufferL
-
-
-/**
- *  @publishedAll
- *  
- *  Class constructor
- *  
- *  @capability None
- */
-EXPORT_C CVoiceMailDeletion* CVoiceMailDeletion::NewL()
-	{
-	LOGGSMU1("CVoiceMailDeletion::NewL()");
-
-	CVoiceMailDeletion* voiceMailDeletion=new(ELeave) CVoiceMailDeletion();
-	CleanupStack::PushL(voiceMailDeletion);
-	voiceMailDeletion->ConstructL();
-	CleanupStack::Pop(voiceMailDeletion);
-	return voiceMailDeletion;
-	} // CVoiceMailDeletion::NewL
-
-
-/*
-void CVoiceMailDeletion::SetExtension(TDesC& aExtension)
-	{
-	LOGGSMU1("CVoiceMailDeletion::SetExtension()");
-
-	TInt length=aExtension.Length();
-	NewBufferL(length);
-	iExtension->Des().Copy(aExtension);
-	} // CVoiceMailDeletion::SetExtension
-
-
-TPtrC CVoiceMailDeletion::Extension() const
-	{
-	LOGGSMU1("CVoiceMailDeletion::Extension()");
-
-	TPtrC ptr;
-	if (iExtension)
-	    ptr.Set(iExtension->Des());
-	return ptr;
-	}*/
-
-
-void CEnhancedVoiceMailDeleteConfirmations::NewExtensionL(TInt aLength)
-	{
-	LOGGSMU1("CEnhancedVoiceMailDeleteConfirmations::NewExtensionL()");
-
-	HBufC* buffer=HBufC::NewL(aLength);
-	delete iExtension;
-	iExtension=buffer;
-	iExtension->Des().SetLength(aLength);
-	iExtension->Des().FillZ();
-	} // CEnhancedVoiceMailDeleteConfirmations::NewExtensionL
-
-
-CEnhancedVoiceMailDeleteConfirmations::CEnhancedVoiceMailDeleteConfirmations() : CEnhancedVoiceMailBoxInformation(EGsmSmsVoiceMailDeleteConfirmation)
-	{
-	//NOP
-	} // CEnhancedVoiceMailDeleteConfirmations::CEnhancedVoiceMailDeleteConfirmations
-
-
-/**
- *  @publishedAll
- *  
- *  Class destructor
- *  
- *  @capability None
- */
-EXPORT_C  CEnhancedVoiceMailDeleteConfirmations::~CEnhancedVoiceMailDeleteConfirmations()
-	{
-	LOGGSMU1("CEnhancedVoiceMailDeleteConfirmations::~CEnhancedVoiceMailDeleteConfirmations");
-
-	delete iExtension;
-	iVoiceMailDeletions->ResetAndDestroy();
-	iVoiceMailDeletions->Close();
-	delete iVoiceMailDeletions;
-	} // CEnhancedVoiceMailDeleteConfirmations::CEnhancedVoiceMailDeleteConfirmations
-
-
-/**
- *  @internalComponent
- *  
- *  Prevent clients from using the copy constructor by including it in the class definition
- *  but making it protected and not exporting it.
- *  
- *  @capability None
- */
-CEnhancedVoiceMailDeleteConfirmations::CEnhancedVoiceMailDeleteConfirmations(const CEnhancedVoiceMailDeleteConfirmations&)
-    {
-    // Ignore in code coverage - not intended to be used
-    BULLSEYE_OFF    
-    LOGGSMU1("CEnhancedVoiceMailDeleteConfirmations::CEnhancedVoiceMailDeleteConfirmations");
-    Panic(KGsmuPanicMethodBodyNotImplemented);
-    BULLSEYE_RESTORE
-    }
-
-/**
- *  @internalComponent
- *  
- *  Prevent clients from using the equality operator by including it in the class definition
- *  but making it protected and not exporting it.
- *  
- *  @capability None
- */
-TBool CEnhancedVoiceMailDeleteConfirmations::operator==(const CEnhancedVoiceMailDeleteConfirmations&)
-    {
-    // Ignore in code coverage - not intended to be used
-    BULLSEYE_OFF    
-    LOGGSMU1("CEnhancedVoiceMailDeleteConfirmations::operator==");
-    Panic(KGsmuPanicMethodBodyNotImplemented);
-    return EFalse;
-    BULLSEYE_RESTORE
-    }
-
-/**
- *  @internalComponent
- *  
- *  Prevent clients from using the assignment operator by including it in the class definition
- *  but making it protected and not exporting it.
- *  
- *  @capability None
- */
-void CEnhancedVoiceMailDeleteConfirmations::operator=(const CEnhancedVoiceMailDeleteConfirmations&)
-    {
-    // Ignore in code coverage - not intended to be used
-    BULLSEYE_OFF    
-    LOGGSMU1("CEnhancedVoiceMailDeleteConfirmations::operator=");
-    Panic(KGsmuPanicMethodBodyNotImplemented);
-    BULLSEYE_RESTORE
-    }
-
-void CEnhancedVoiceMailDeleteConfirmations::ConstructL()
-	{
-	LOGGSMU1("CEnhancedVoiceMailDeleteConfirmations::ConstructL()");
-
-	NewExtensionL(0);
-
-	iVoiceMailDeletions = new (ELeave) RPointerArray<CVoiceMailDeletion>(15);
-	} // CEnhancedVoiceMailDeleteConfirmations::ConstructL
-
-
-/**
- *  @publishedAll
- *  
- *  Class constructor
- *  
- *  @capability None
- */
-EXPORT_C  CEnhancedVoiceMailDeleteConfirmations* CEnhancedVoiceMailDeleteConfirmations::NewL()
-	{
-	LOGGSMU1("CEnhancedVoiceMailDeleteConfirmations::NewL()");
-
-	CEnhancedVoiceMailDeleteConfirmations* aCEnhancedVoiceMailDeleteConfirmations=new(ELeave) CEnhancedVoiceMailDeleteConfirmations();
-	CleanupStack::PushL(aCEnhancedVoiceMailDeleteConfirmations);
-	aCEnhancedVoiceMailDeleteConfirmations->CEnhancedVoiceMailBoxInformation::ConstructL();
-	aCEnhancedVoiceMailDeleteConfirmations->ConstructL();
-	CleanupStack::Pop(aCEnhancedVoiceMailDeleteConfirmations);
-	return aCEnhancedVoiceMailDeleteConfirmations;
-	} // CEnhancedVoiceMailDeleteConfirmations::NewL
-
-
-/**
- *  @publishedAll
- *  
- *  Indicates the number of message IDs that follow in this IE.
- *  
- *  @return
- *  The number of message IDs that follow.
- *  
- *  @capability None
- */
-EXPORT_C TUint8  CEnhancedVoiceMailDeleteConfirmations::NumberOfDeletes()
-	{
-	LOGGSMU1("CEnhancedVoiceMailDeleteConfirmations::NumberOfDeletes()");
-
-	return iVoiceMailDeletions->Count();
-	} // CEnhancedVoiceMailDeleteConfirmations::NumberOfDeletes
-
-
-/**
- *  @publishedAll
- *  
- *  Provides a reference to the collection that is used to contain the Voice Mail Deletion
- *  notifications. Up to 31 instances of CVoiceMailDeletion can be stored. If more than
- *  31 instances are added, the CEnhancedVoiceMailDeleteConfirmations will not be added to
- *  the CSmsMessage.
- *  
- *  @return
- *  A reference to the collection that is used to contain the Voice Mail Deletion
- *  notifications.
- *  
- *  @capability None
- */
-EXPORT_C RPointerArray<CVoiceMailDeletion>& CEnhancedVoiceMailDeleteConfirmations::GetVoiceMailDeletions()
-	{
-	LOGGSMU1("CEnhancedVoiceMailDeleteConfirmations::GetVoiceMailDeletions()");
-
-	return *iVoiceMailDeletions;
-	} // CEnhancedVoiceMailDeleteConfirmations::GetVoiceMailDeletions
-
-
-/*
-void CEnhancedVoiceMailDeleteConfirmations::SetExtension(TDesC& aExtension)
-	{
-	LOGGSMU1("CEnhancedVoiceMailDeleteConfirmations::SetExtension()");
-
-	TInt length=aExtension.Length();
-	NewBufferL(length);
-	iExtension->Des().Copy(aExtension);
-	} // CEnhancedVoiceMailDeleteConfirmations::SetExtension
-
-
-TPtrC CEnhancedVoiceMailDeleteConfirmations::Extension() const
-	{
-	LOGGSMU1("CEnhancedVoiceMailDeleteConfirmations::Extension()");
-
-	TPtrC ptr;
-	if (iExtension)
-		{
-		ptr.Set(iExtension->Des());
-		}
-	return ptr;
-	}*/
-
-
-TUint8* CEnhancedVoiceMailDeleteConfirmations::EncodeL(TUint8* aCurrentPtr, CCnvCharacterSetConverter& aCharacterSetConverter, RFs& aFs) const
-	{
-	LOGGSMU1("CEnhancedVoiceMailDeleteConfirmations::EncodeL");
-
-	TUint8* startPtr   = aCurrentPtr;
-
-	aCurrentPtr = CEnhancedVoiceMailBoxInformation::EncodeL(aCurrentPtr, aCharacterSetConverter, aFs);
-
-	TUint8 count = ((TUint8)iVoiceMailDeletions->Count());
-
-	if (count > KMaxNumberOfNotifications)
-	    {
-	    User::Leave(KErrArgument);
-	    }
-
-	*aCurrentPtr= (count & KSmsNotificationBitMask);
-	aCurrentPtr++;
-
-	TInt16 spaceAlreadyAllocated; // handle architectures whose address space increments and whose address space decrements.
-	(aCurrentPtr > startPtr) ? (spaceAlreadyAllocated = aCurrentPtr - startPtr) : (spaceAlreadyAllocated = startPtr - aCurrentPtr);
-
-	// allow space for id and length bytes
-	TInt16 remainingSize = (TInt16)(CEnhancedVoiceMailBoxInformation::KSmsMaxEnhancedVoiceMailSize - spaceAlreadyAllocated);
-
-	for (TUint i = 0; i < count; i++)
-	    {
-	    remainingSize -= (TInt16)(*iVoiceMailDeletions)[i]->SizeL();
-	    if (remainingSize < 0)
-	        {
-	        User::Leave(KErrArgument);
-	        }
-
-	    aCurrentPtr = (*iVoiceMailDeletions)[i]->EncodeL(aCurrentPtr);
-	    }
-
-	return aCurrentPtr;
-	} // CEnhancedVoiceMailDeleteConfirmations::EncodeL
-
-
-void CEnhancedVoiceMailDeleteConfirmations::DecodeL(TGsmuLex8& aVoiceMailInfo, CCnvCharacterSetConverter& aCharacterSetConverter, RFs& aFs)
-	{
-	LOGGSMU1("CEnhancedVoiceMailDeleteConfirmations::DecodeL");
-
-	CEnhancedVoiceMailBoxInformation::DecodeL(aVoiceMailInfo, aCharacterSetConverter, aFs);
-
-	TUint numberOfVMDeletions = (aVoiceMailInfo.GetL() & KSmsNotificationBitMask);
-
-	if (iExtensionIndicator)
-		{
-		TUint8 extensionLength = aVoiceMailInfo.GetL();
-		aVoiceMailInfo.Inc(extensionLength);
-		}
-
-	for (TUint8 i = 0; i < numberOfVMDeletions; i++)
-		{
-		// Create a Voice Mail Deletion
-		CVoiceMailDeletion* voiceMailDeletion = CVoiceMailDeletion::NewL();
-		CleanupStack::PushL(voiceMailDeletion);
-		voiceMailDeletion->DecodeL(aVoiceMailInfo);
-		CleanupStack::Pop(voiceMailDeletion);
-		iVoiceMailDeletions->Append(voiceMailDeletion);
-		}
-	} // CEnhancedVoiceMailDeleteConfirmations::DecodeL
+// Copyright (c) 1999-2009 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of "Eclipse Public License v1.0"
+// which accompanies this distribution, and is available
+// at the URL "http://www.eclipse.org/legal/epl-v10.html".
+//
+// Initial Contributors:
+// Nokia Corporation - initial contribution.
+//
+// Contributors:
+//
+// Description:
+// This file implements the different PDU elements
+// 
+//
+
+/**
+ @file
+*/
+
+#include <gsmuelem.h>
+#include <gsmumsg.h>
+#include "Gsmumain.h"
+#include <gsmusar.h>
+#include "gsmupriv.h"
+#include <s32strm.h>
+#include <etelmm.h>
+#include <gsmuetel.h>
+#include <exterror.h>
+#include <emsinformationelement.h>
+#include <emsformatie.h>
+#include <charconv.h>
+
+/**
+ *  Question Mark character.
+ */
+const TInt  KReplacementCharacter = 0x003f;
+
+
+/**
+ *  Constructs the object with a descriptor. The extraction mark and next character members are initialised to point to the start of the string.
+ *  
+ *  @param aSource Descriptor to be assigned by reference
+ */
+TGsmuLex8::TGsmuLex8(const TDesC8& aSource): TLex8(aSource)
+	{
+	//NOP
+	} // TGsmuLex8::TGsmuLex8
+
+
+/**
+ *  Gets the next character in the string and increments the next character position.
+ *  
+ *  @return The next character in the string
+ *  @leave Leaves with KErrGsmuDecoding if at end of string
+ */
+TUint8 TGsmuLex8::GetL()
+	{
+	if (Eos())
+		LeaveL();
+
+	return static_cast<TUint8>(Get());
+	} // TGsmuLex8::GetL
+
+
+/**
+ *  Increments the next character position by aNumber
+ *  
+ *  @param aNumber The number of characters to increment the next character position by.
+ *  @leave If the increment puts the next character position before the start or beyond the end of the string, the function leaves with KErrGsmuDecoding.
+ */
+void TGsmuLex8::IncL(TInt aNumber)
+	{
+	if (aNumber != 0)
+		{
+		if (aNumber < 0 || Eos() || Remainder().Length() < aNumber)
+			LeaveL();
+		else
+			Inc(aNumber);
+		}
+	} // TGsmuLex8::IncL
+
+
+/**
+ *  Checks there are enough remaining characters, then returns a TPtrC containing the next aLength characters. Does not increment the current position.
+ *  
+ *  @param aLength Number of characters to return
+ *  @return Remainder().Left(aLength)
+ *  @leave Leaves with KErrGsmuDecoding if there are insufficient characters remaining
+ */
+TPtrC8 TGsmuLex8::NextWithNoIncL(TInt aLength) const
+	{
+	return NextWithNoIncL(aLength, EFalse);
+	}
+
+/**
+ * Checks there are enough remaining characters, then returns a TPtrC containing the next aLength characters. Does not increment the current position.
+ *
+ * @param aLength Number of characters to return
+ * @param aAcceptTruncation ETrue if a mismatch between length indicator and actual length is acceptable. EFalse otherwise.
+ * @return Remainder().Left(aLength) if aAcceptTruncation is EFalse. Remainder() otherwise.
+ * @leave Leaves with KErrGsmuDecoding if there are insufficient characters remaining, unless aAcceptTruncation is ETrue.
+ */
+TPtrC8 TGsmuLex8::NextWithNoIncL(TInt aLength, TBool aAcceptTruncation) const
+	{
+	const TPtrC8 remainder(Remainder());
+
+	if ( (aLength < 0) || (remainder.Length()< aLength && !aAcceptTruncation) )
+		{
+		LeaveL();
+		}
+	
+  if (!aAcceptTruncation)
+		{
+		return Remainder().Left(aLength);
+		}
+	// aAcceptTruncation is ETrue
+	else if (remainder.Length() < aLength)
+		{
+		return Remainder();
+		}
+	// otherwise, no need for truncation:
+  
+	return Remainder().Left(aLength);
+	}
+
+
+/**
+ *  Calls TGsmuLeax8::NextWithNoIncL then increments the next character position by aLength
+ *  
+ *  @param aLength Number of characters to return and increment the next character position
+ *  @return Remainder().Left(aLength)
+ *  @leave If the increment puts the next character position before the start or beyond the end of the string, the function leaves with KErrGsmuDecoding.
+ */
+TPtrC8 TGsmuLex8::NextAndIncL(TInt aLength)
+	{
+	const TPtrC8 next(NextWithNoIncL(aLength));
+	IncL(aLength);
+	return next;
+	} // TGsmuLeax8::NextWithNoIncL
+
+
+const TSmsOctet& TSmsOctet::operator = (TInt aValue)
+	{
+	iValue = static_cast<TUint8>(aValue);
+	return *this;
+	} // TSmsOctet::operator
+
+
+TUint8* TSmsOctet::EncodeL(TUint8* aPtr) const
+	{
+	*aPtr=iValue;
+	return aPtr+1;
+	} // TSmsOctet::EncodeL
+
+
+TSmsFirstOctet::TSmsFirstOctet(TInt aValue):
+	TSmsOctet(aValue)
+	{
+	} // TSmsFirstOctet::TSmsFirstOctet
+
+
+const TSmsFirstOctet& TSmsFirstOctet::operator = (TInt aValue)
+	{
+	TSmsOctet::operator = (aValue);
+	return *this;
+	} // TSmsFirstOctet::operator
+
+
+TSmsFailureCause::TSmsFailureCause():
+	TSmsOctet(ESmsErrorUnspecified)
+	{
+	} // TSmsFailureCause::TSmsFailureCause
+
+
+TSmsStatus::TSmsStatus():
+	TSmsOctet(ESmsShortMessageReceivedBySME)
+	{
+	} // TSmsStatus::TSmsStatus
+
+
+CSmsCommandData* CSmsCommandData::NewL(TSmsFirstOctet& aFirstOctet)
+	{
+	LOGGSMU1("CSmsCommandData::NewL()");
+
+	CSmsCommandData* commanddata=new(ELeave) CSmsCommandData(aFirstOctet);
+	CleanupStack::PushL(commanddata);
+	TPtrC8 ptr;
+	commanddata->SetDataL(ptr);
+	CleanupStack::Pop();
+	return commanddata;
+	} // CSmsCommandData::NewL
+
+
+CSmsCommandData::~CSmsCommandData()
+	{
+	iInformationElementArray.ResetAndDestroy();
+	delete iBuffer;
+	} // CSmsCommandData::NewL
+
+
+/**
+ *  Duplicates this CSmsCommandData object.
+ * 
+ *  @return  Pointer to the newly created CSmsCommandData object.
+ */
+CSmsCommandData* CSmsCommandData::DuplicateL() const
+	{
+	LOGGSMU1("CSmsCommandData::DuplicateL()");
+
+	CSmsCommandData*  smsCommandData = CSmsCommandData::NewL(iFirstOctet);
+	CleanupStack::PushL(smsCommandData);
+
+	smsCommandData->SetDataL(Data());
+
+	for (TInt ie = 0;  ie < iInformationElementArray.Count();  ie++)
+		{
+		smsCommandData->AddInformationElementL(iInformationElementArray[ie]->Identifier(),
+											   iInformationElementArray[ie]->Data());
+		}
+
+	CleanupStack::Pop(smsCommandData);
+
+	return smsCommandData;
+	} // CSmsCommandData::DuplicateL
+
+
+CSmsInformationElement& CSmsCommandData::InformationElement(TInt aIndex) const
+	{
+	LOGGSMU1("CSmsCommandData::InformationElement()");
+
+	CSmsInformationElement* ie=iInformationElementArray[aIndex];
+	return *ie;
+	} // CSmsCommandData::InformationElement
+
+
+CSmsInformationElement*& CSmsCommandData::InformationElementPtr(TInt aIndex)
+    {
+    // Ignore in code coverage - not used in SMS stack and not exported
+    // but cannot be removed as impacts public header.
+    BULLSEYE_OFF    
+    LOGGSMU1("CSmsCommandData::InformationElementPtr()");
+    return iInformationElementArray[aIndex];
+    BULLSEYE_RESTORE
+    }
+
+TBool CSmsCommandData::InformationElementIndex(CSmsInformationElement::TSmsInformationElementIdentifier aIdentifier,
+		TInt& aIndex) const
+	{
+	LOGGSMU1("CSmsCommandData::InformationElementIndex()");
+
+	TBool found=EFalse;
+	TInt count=NumInformationElements();
+	for (TInt i=0; (!found) && (i<count); i++)
+		if (InformationElement(i).Identifier()==aIdentifier)
+			{
+			found=ETrue;
+			aIndex=i;
+			}
+	return found;
+	} // CSmsCommandData::InformationElementIndex
+
+
+void CSmsCommandData::AddInformationElementL(const TSmsId aIdentifier,const TDesC8& aData)
+	{
+	LOGGSMU1("CSmsCommandData::AddInformationElementL()");
+
+	//
+	// Currently there is no restriction on how many instances of an information element can be
+	// placed in the collection.
+	// No restriction will be placed on the number of Special SMS Message Indications that can be
+	// added in order to maintain FC.
+	// (cf CSmsUserData::AddInformationElementL(const TSmsId aIdentifier,const TDesC8& aData);
+	//
+	CSmsInformationElement* informationelement=CSmsInformationElement::NewL(aIdentifier,aData);
+	CleanupStack::PushL(informationelement);
+	iInformationElementArray.AppendL(informationelement);
+	CleanupStack::Pop();
+	if (NumInformationElements()>=1)
+		SetHeaderPresent(ETrue);
+	} // CSmsCommandData::AddInformationElementL
+
+
+void CSmsCommandData::RemoveInformationElement(TInt aIndex)
+	{
+	LOGGSMU1("CSmsCommandData::RemoveInformationElement()");
+	// Since iInformationElementArray[aIndex] is removed from iInformationElementArray, no double free issue.
+	// coverity[double_free]
+	delete iInformationElementArray[aIndex];
+	iInformationElementArray[aIndex] = NULL;
+	iInformationElementArray.Delete(aIndex);
+
+	if (NumInformationElements()==0)
+		{
+		SetHeaderPresent(EFalse);
+		}
+	} // CSmsCommandData::RemoveInformationElement
+
+
+TPtrC8 CSmsCommandData::Data() const
+	{
+	LOGGSMU1("CSmsCommandData::Data()");
+
+	TPtrC8 ptr;
+	ptr.Set(iBuffer->Des());
+	return ptr;
+	} // CSmsCommandData::Data
+
+
+void CSmsCommandData::SetDataL(const TDesC8& aData)
+	{
+	LOGGSMU1("CSmsCommandData::SetDataL()");
+
+	TInt length=aData.Length();
+	__ASSERT_DEBUG(length<=KSmsMaxDataSize,Panic(KGsmuPanicCommandDataLengthTooLong));
+	HBufC8* buffer=HBufC8::NewL(length);
+	delete iBuffer;
+	iBuffer=buffer;
+	iBuffer->Des().SetLength(length);
+	iBuffer->Des().Copy(aData);
+	} // CSmsCommandData::SetDataL
+
+
+TUint8* CSmsCommandData::EncodeL(TUint8* aPtr) const
+	{
+	LOGGSMU1("CSmsCommandData::EncodeL()");
+
+	__ASSERT_DEBUG(iBuffer->Length()<=MaxDataLength(),Panic(KGsmuPanicCommandDataBufferTooLong));
+	TSmsOctet datalength=iBuffer->Length()+TSmsOctet(TotalHeaderLengthInUDLUnits());
+	aPtr=datalength.EncodeL(aPtr);
+	TPtr8 ptr((TUint8*) aPtr,datalength);
+
+    if (HeaderPresent())
+        {
+		TSmsOctet headerLength(HeaderLength());
+		aPtr=headerLength.EncodeL(aPtr);
+		for (TInt i=0; i<NumInformationElements(); i++)
+		    {
+			aPtr=iInformationElementArray[i]->EncodeL(aPtr);
+		    }
+        }
+
+	ptr.Copy(iBuffer->Des());
+	aPtr+=TInt(iBuffer->Length());
+	return aPtr;
+	} // CSmsCommandData::EncodeL
+
+
+void CSmsCommandData::DecodeL(TGsmuLex8& aPdu)
+	{
+	LOGGSMU1("CSmsCommandData::DecodeL()");
+
+	iInformationElementArray.ResetAndDestroy();
+	const TBool headerPresent=HeaderPresent();
+	TSmsOctet dataLength;
+	dataLength.DecodeL(aPdu);
+
+	if (headerPresent)
+		{
+		TSmsOctet headerLength;
+		headerLength.DecodeL(aPdu);
+		if ((1+headerLength)>KSmsMaxDataSize)
+			User::Leave(KErrGsmSMSTpduNotSupported);
+		while (HeaderLength()<headerLength)
+			{
+			CSmsInformationElement* informationElement=CSmsInformationElement::NewL();
+			CleanupStack::PushL(informationElement);
+			informationElement->DecodeL(aPdu);
+			iInformationElementArray.AppendL(informationElement);
+			CleanupStack::Pop(informationElement);
+			}
+		if (HeaderLength()!=headerLength)
+			User::Leave(KErrGsmSMSTpduNotSupported);
+		}
+	const TInt totalHeaderLength=TotalHeaderLengthInUDLUnits();
+	const TInt totalDataLength=dataLength-totalHeaderLength;
+	const TPtrC8 next(aPdu.NextAndIncL(totalDataLength));
+	SetDataL(next);
+	} // CSmsCommandData::DecodeL
+
+
+void CSmsCommandData::InternalizeL(RReadStream& aStream)
+	{
+	iInformationElementArray.ResetAndDestroy();
+	TInt numInformationElements=aStream.ReadInt32L();
+	for (TInt i=0; i<numInformationElements; i++)
+		{
+		CSmsInformationElement* informationElement=CSmsInformationElement::NewL();
+		CleanupStack::PushL(informationElement);
+		aStream >> *informationElement;
+		iInformationElementArray.AppendL(informationElement);
+		CleanupStack::Pop();
+		}
+	HBufC8* buffer=HBufC8::NewL(aStream,KSmsMaxDataSize);
+	delete iBuffer;
+	iBuffer=buffer;
+	} // CSmsCommandData::InternalizeL
+
+
+void CSmsCommandData::ExternalizeL(RWriteStream& aStream) const
+	{
+	TInt numInformationElements=iInformationElementArray.Count();
+	aStream.WriteInt32L(numInformationElements);
+	for (TInt i=0; i<numInformationElements; i++)
+		aStream << *iInformationElementArray[i];
+	aStream << *iBuffer;
+	} // CSmsCommandData::ExternalizeL
+
+
+CSmsCommandData::CSmsCommandData(TSmsFirstOctet& aFirstOctet):
+	iFirstOctet(aFirstOctet),
+	iInformationElementArray(8)
+	{
+	} // CSmsCommandData::CSmsCommandData
+
+
+TInt CSmsCommandData::HeaderLength() const
+	{
+	LOGGSMU1("CSmsCommandData::HeaderLength()");
+
+	TInt headerLength=0;
+	for (TInt i=0; i<NumInformationElements(); i++)
+		headerLength+=iInformationElementArray[i]->Length();
+	return headerLength;
+	} // CSmsCommandData::HeaderLength
+
+
+TInt CSmsCommandData::TotalHeaderLengthInUDLUnits() const
+	{
+	LOGGSMU1("CSmsCommandData::TotalHeaderLengthInUDLUnits()");
+
+	if (iInformationElementArray.Count()==0)
+		return 0;
+	else
+		return (HeaderLength()+1);   // +1 stands for  UDHL
+	} // CSmsCommandData::TotalHeaderLengthInUDLUnits
+
+
+TBool CSmsCommandData::HeaderPresent() const
+	{
+	LOGGSMU1("CSmsCommandData::HeaderPresent()");
+
+	return (iFirstOctet&TSmsFirstOctet::ESmsUDHIMask)==TSmsFirstOctet::ESmsUDHIHeaderPresent;
+	} // CSmsCommandData::HeaderPresent
+
+
+void CSmsCommandData::SetHeaderPresent(TBool aHeaderPresent)
+	{
+	LOGGSMU1("CSmsCommandData::SetHeaderPresent()");
+
+	iFirstOctet=aHeaderPresent? (iFirstOctet&(~TSmsFirstOctet::ESmsUDHIMask))|TSmsFirstOctet::ESmsUDHIHeaderPresent: (iFirstOctet&(~TSmsFirstOctet::ESmsUDHIMask))|TSmsFirstOctet::ESmsUDHIHeaderNotPresent;
+	} // CSmsCommandData::SetHeaderPresent
+
+
+TSmsParameterIndicator::TSmsParameterIndicator():
+	TSmsOctet(ESmsPIDProtocolIdentifierPresent|ESmsPIDUserDataPresent|ESmsPIDDataCodingSchemePresent)
+	{
+	} // TSmsParameterIndicator::TSmsParameterIndicator
+
+
+TSmsCommandType::TSmsCommandType():
+	TSmsOctet(ESmsCommandTypeEnquiry)
+	{
+	} // TSmsCommandType::TSmsCommandType
+
+
+TSmsProtocolIdentifier::TSmsProtocolIdentifier():
+	TSmsOctet((TInt)ESmsPIDTelematicInterworking|(TInt)ESmsNoTelematicDevice)
+	{
+	} // TSmsProtocolIdentifier::TSmsProtocolIdentifier
+
+
+TSmsProtocolIdentifier::TSmsTelematicDeviceIndicator TSmsProtocolIdentifier::TelematicDeviceIndicator() const
+	{
+	__ASSERT_DEBUG(PIDType()==ESmsPIDTelematicInterworking,Panic(KGsmuPanicNoTelematicInterworking));
+	return (TSmsTelematicDeviceIndicator) (iValue&EPIDTelematicDeviceIndicatorMask);
+	} // TSmsProtocolIdentifier::TSmsTelematicDeviceIndicator
+
+
+void TSmsProtocolIdentifier::SetTelematicDeviceIndicator(TSmsTelematicDeviceIndicator aIndicator)
+	{
+	LOGGSMU1("TSmsProtocolIdentifier::SetTelematicDeviceIndicator()");
+
+	__ASSERT_DEBUG(PIDType()==ESmsPIDTelematicInterworking,Panic(KGsmuPanicNoTelematicInterworking));
+
+	//iValue=(TUint8) ((iValue&ESmsPIDTypeMask)|aIndicator);
+	iValue=(TUint8) ((iValue&(~EPIDTelematicDeviceIndicatorMask))|aIndicator);
+	} // TSmsProtocolIdentifier::SetTelematicDeviceIndicator
+
+
+TSmsProtocolIdentifier::TSmsTelematicDeviceType TSmsProtocolIdentifier::TelematicDeviceType() const
+	{
+	__ASSERT_DEBUG(TelematicDeviceIndicator()==ESmsTelematicDevice,Panic(KGsmuPanicNoTelematicDevice));
+	return (TSmsTelematicDeviceType) (iValue&ESmsTelematicDeviceTypeMask);
+	} // TSmsProtocolIdentifier::TSmsTelematicDeviceType
+
+
+void TSmsProtocolIdentifier::SetTelematicDeviceType(TSmsTelematicDeviceType aDeviceType)
+	{
+	LOGGSMU1("TSmsProtocolIdentifier::SetTelematicDeviceType()");
+
+	__ASSERT_DEBUG(TelematicDeviceIndicator()==ESmsTelematicDevice,Panic(KGsmuPanicNoTelematicDevice));
+	iValue=(TUint8) ((iValue&(~ESmsTelematicDeviceTypeMask))|aDeviceType);
+	} // TSmsProtocolIdentifier::SetTelematicDeviceType
+
+
+TInt TSmsProtocolIdentifier::ShortMessageALProtocol() const
+    {
+    // Ignore in code coverage - not used in SMS stack and not exported
+    // but cannot be removed as impacts public header.
+    BULLSEYE_OFF    
+    LOGGSMU1("TSmsProtocolIdentifier::ShortMessageALProtocol()");
+    
+    __ASSERT_DEBUG(TelematicDeviceIndicator()==ESmsNoTelematicDevice,Panic(KGsmuPanicNoTelematicDevice));
+    return (TSmsShortMessageALProtocol) (iValue&ESmsShortMessageALProtocolMask);
+    BULLSEYE_RESTORE
+    }
+
+void TSmsProtocolIdentifier::SetShortMessageALProtocol(TSmsShortMessageALProtocol aProtocol)
+    {
+    // Ignore in code coverage - not used in SMS stack and not exported
+    // but cannot be removed as impacts public header.
+    BULLSEYE_OFF    
+    LOGGSMU1("TSmsProtocolIdentifier::SetShortMessageALProtocol()");
+    
+    __ASSERT_DEBUG(TelematicDeviceIndicator()==ESmsNoTelematicDevice,Panic(KGsmuPanicNoTelematicDevice));
+    iValue=(TUint8) ((iValue&(~ESmsShortMessageALProtocolMask))|aProtocol);
+    BULLSEYE_RESTORE
+    }
+
+TInt TSmsProtocolIdentifier::ShortMessageType() const
+	{
+	LOGGSMU1("TSmsProtocolIdentifier::ShortMessageType()");
+
+	__ASSERT_DEBUG(PIDType()==ESmsPIDShortMessageType,Panic(KGsmuPanicNoShortMessageType));
+	return (TSmsShortMessageType) (iValue&ESmsShortMessageTypeMask);
+	} // TSmsProtocolIdentifier::ShortMessageType
+
+
+void TSmsProtocolIdentifier::SetShortMessageType(TSmsShortMessageType aShortMessageType)
+	{
+	LOGGSMU1("TSmsProtocolIdentifier::SetShortMessageType()");
+
+	__ASSERT_DEBUG(PIDType()==ESmsPIDShortMessageType,Panic(KGsmuPanicNoShortMessageType));
+	//iValue=(TUint8) ((iValue&(~ESmsPIDTypeMask))|aShortMessageType);
+	iValue=(TUint8) ((iValue&(~ESmsShortMessageTypeMask))|aShortMessageType);
+	} // TSmsProtocolIdentifier::SetShortMessageType
+
+
+TSmsDataCodingScheme::TSmsDataCodingScheme():
+	TSmsOctet((TInt)ESmsDCSTextUncompressedWithNoClassInfo|(TInt)ESmsAlphabet7Bit|(TInt)ESmsClass0)
+	// Constructor is expected to set the octet = 0, This is needed by
+	// CSmsDeliverReport::DecodeL, CSmsSubmitReport::DecodeL and CSmsStatusReport::DecodeL, per
+	// 23.040 v6.5.0 section 9.2.3.27.
+	{
+	} // CSmsDeliverReport::DecodeL
+
+
+TBool TSmsDataCodingScheme::TextCompressed() const
+	{
+	LOGGSMU1("TSmsDataCodingScheme::TextCompressed()");
+
+	TInt bits7to4=Bits7To4();
+	return (bits7to4==ESmsDCSTextCompressedWithNoClassInfo)    || (bits7to4==ESmsDCSTextCompressedWithClassInfo)      ||
+           (bits7to4==ESmsDCSAutoDelNoClassInfoCompressedText) || (bits7to4==ESmsDCSAutoDelClassInfoTextCompressedText);
+	} // TSmsDataCodingScheme::TextCompressed
+
+
+void TSmsDataCodingScheme::SetTextCompressed(TBool aCompressed)
+	{
+	LOGGSMU1("TSmsDataCodingScheme::SetTextCompressed()");
+
+	TInt bits7to4=Bits7To4();
+	if (aCompressed)
+		{
+		switch (bits7to4)
+			{
+			case (ESmsDCSTextUncompressedWithNoClassInfo):
+				{
+				iValue=(TUint8) (ESmsDCSTextCompressedWithNoClassInfo|(iValue&(~ESmsDCSBits7To4Mask)));
+				break;
+				}
+			case (ESmsDCSAutoDelNoClassInfoUncompressedText):
+				{
+				iValue=(TUint8) (ESmsDCSAutoDelNoClassInfoCompressedText|(iValue&(~ESmsDCSBits7To4Mask)));
+				break;
+				}
+			case (ESmsDCSAutoDelClassInfoUncompressedText):
+				{
+				iValue=(TUint8) (ESmsDCSAutoDelClassInfoTextCompressedText|(iValue&(~ESmsDCSBits7To4Mask)));
+				break;
+				}
+			case (ESmsDCSTextUncompressedWithClassInfo):
+			case (ESmsDCSTextUncompressed7BitOr8Bit):
+				{
+				iValue=(TUint8) (ESmsDCSTextCompressedWithClassInfo|(iValue&(~ESmsDCSBits7To4Mask)));
+				break;
+				}
+			case (ESmsDCSTextCompressedWithNoClassInfo):
+			case (ESmsDCSTextCompressedWithClassInfo):
+			case (ESmsDCSAutoDelNoClassInfoCompressedText):
+			case (ESmsDCSAutoDelClassInfoTextCompressedText):
+				break;
+			default:
+                break;
+                // has to be tested, what happens in this default case
+				//Panic(KGsmuPanicNotSupportedWithDCSBits7To4);
+			}
+		}
+	else
+		{
+		switch (bits7to4)
+			{
+			case (ESmsDCSTextCompressedWithNoClassInfo):
+				{
+				iValue=(TUint8) (ESmsDCSTextUncompressedWithNoClassInfo|(iValue&(~ESmsDCSBits7To4Mask)));
+				break;
+				}
+			case (ESmsDCSTextCompressedWithClassInfo):
+				{
+				iValue=(TUint8) (ESmsDCSTextUncompressedWithClassInfo|(iValue&(~ESmsDCSBits7To4Mask)));
+				break;
+				}
+			case (ESmsDCSAutoDelNoClassInfoCompressedText):
+				{
+				iValue=(TUint8) (ESmsDCSAutoDelNoClassInfoUncompressedText|(iValue&(~ESmsDCSBits7To4Mask)));
+				break;
+				}
+			case (ESmsDCSAutoDelClassInfoTextCompressedText):
+				{
+				iValue=(TUint8) ( ESmsDCSAutoDelClassInfoUncompressedText|(iValue&(~ESmsDCSBits7To4Mask)));
+				break;
+				}
+			case (ESmsDCSTextUncompressedWithNoClassInfo):
+			case (ESmsDCSTextUncompressedWithClassInfo):
+            case (ESmsDCSAutoDelClassInfoUncompressedText):
+            case (ESmsDCSAutoDelNoClassInfoUncompressedText):
+			case (ESmsDCSTextUncompressed7BitOr8Bit):
+			default:
+				{
+				}
+			}
+		}
+	} // TSmsDataCodingScheme::SetTextCompressed
+
+
+TSmsDataCodingScheme::TSmsAlphabet TSmsDataCodingScheme::Alphabet() const
+	{
+	LOGGSMU1("TSmsDataCodingScheme::TSmsAlphabet()");
+
+	TInt bits7to4=Bits7To4();
+	TInt alphabet=ESmsAlphabet7Bit;
+	switch (bits7to4)
+		{
+		case (ESmsDCSTextUncompressedWithNoClassInfo):
+		case (ESmsDCSTextUncompressedWithClassInfo):
+		case (ESmsDCSTextCompressedWithNoClassInfo):  //  Alphabet not used in these cases
+		case (ESmsDCSTextCompressedWithClassInfo):
+		case (ESmsDCSAutoDelNoClassInfoUncompressedText):
+		case (ESmsDCSAutoDelClassInfoUncompressedText):
+		case (ESmsDCSAutoDelNoClassInfoCompressedText):
+		case (ESmsDCSAutoDelClassInfoTextCompressedText):
+			{
+			alphabet=iValue&ESmsAlphabetMask;
+			break;
+			}
+		case (ESmsDCSTextUncompressed7BitOr8Bit):
+			{
+			alphabet=iValue&ESmsAlphabet8Bit;  //  N.B. only one bit used to code alphabet
+			break;
+			}
+		case (ESmsDCSMessageWaitingIndicationDiscardMessage):
+		case (ESmsDCSMessageWaitingIndication7Bit):
+			{
+			alphabet=ESmsAlphabet7Bit;
+			break;
+			}
+		case (ESmsDCSMessageWaitingIndicationUCS2):
+			{
+			alphabet=ESmsAlphabetUCS2;
+			break;
+			}
+		default:
+		    LOGGSMU1("TSmsDataCodingScheme::Alphabet() WARNING! default case has been reached");
+            break;
+ 		}
+	return (TSmsAlphabet) alphabet;
+	} // TSmsDataCodingScheme::TSmsAlphabet
+
+void TSmsDataCodingScheme::SetAlphabet(TSmsAlphabet aAlphabet)
+	{
+	LOGGSMU1("TSmsDataCodingScheme::SetAlphabet()");
+
+	TInt bits7to4=Bits7To4();
+	switch (bits7to4)
+		{
+		case (ESmsDCSTextUncompressedWithNoClassInfo):
+		case (ESmsDCSTextUncompressedWithClassInfo):
+		case (ESmsDCSTextCompressedWithNoClassInfo):  //  Alphabet not used in these cases
+		case (ESmsDCSTextCompressedWithClassInfo):
+		case (ESmsDCSAutoDelNoClassInfoUncompressedText):
+		case (ESmsDCSAutoDelClassInfoUncompressedText):
+		case (ESmsDCSAutoDelNoClassInfoCompressedText):
+		case (ESmsDCSAutoDelClassInfoTextCompressedText):
+			{
+			iValue=(TUint8) ((iValue&(~ESmsAlphabetMask))|aAlphabet);
+			break;
+			}
+		case (ESmsDCSTextUncompressed7BitOr8Bit):
+			{
+			if ((aAlphabet==ESmsAlphabet7Bit) || (aAlphabet==ESmsAlphabet8Bit))
+				{
+				iValue=(TUint8) ((iValue&(~ESmsAlphabet8Bit))|aAlphabet);  //  N.B. only one bit used to code alphabet
+				}
+			break;
+			}
+		case (ESmsDCSMessageWaitingIndicationDiscardMessage):
+			{
+            if (aAlphabet!=ESmsAlphabet7Bit)
+                {
+                LOGGSMU3("TSmsDataCodingScheme::SetAlphabet() WARNING! Not Supported With Discard Message  [Bits7To4=%d], [aAlphabet=%d]", bits7to4, aAlphabet);
+                }
+			break;
+			}
+		case (ESmsDCSMessageWaitingIndication7Bit):
+			{
+ 			if (aAlphabet==ESmsAlphabetUCS2)
+ 			    {
+				iValue=(TUint8) (ESmsDCSMessageWaitingIndicationUCS2|(iValue&(~ESmsDCSBits7To4Mask)));
+ 			    }
+ 			else 
+                {
+        		LOGGSMU3("TSmsDataCodingScheme::SetAlphabet() WARNING! Not Supported With Discard Message  [Bits7To4=%d], [aAlphabet=%d]", bits7to4, aAlphabet);
+			    }	     
+			break;
+			}
+		case (ESmsDCSMessageWaitingIndicationUCS2):
+			{
+  			if (aAlphabet==ESmsAlphabet7Bit)
+			    {
+				iValue=(TUint8) (ESmsDCSMessageWaitingIndication7Bit|(iValue&(~ESmsDCSBits7To4Mask)));
+			    }
+			else 
+			    {
+				LOGGSMU3("TSmsDataCodingScheme::SetAlphabet() WARNING! Not Supported With Discard Message  [Bits7To4=%d], [aAlphabet=%d]", bits7to4, aAlphabet);
+			    }
+			break;
+			}
+		default:
+		    LOGGSMU1("TSmsDataCodingScheme::SetAlphabet() WARNING! default case has been reached");
+            break;
+      		}
+	} // TSmsDataCodingScheme::SetAlphabet
+
+
+TBool TSmsDataCodingScheme::Class(TSmsClass& aClass) const
+	{
+	LOGGSMU1("TSmsDataCodingScheme::Class()");
+
+	switch (Bits7To4())
+		{
+		case (ESmsDCSTextUncompressedWithClassInfo):
+		case (ESmsDCSTextCompressedWithClassInfo):
+		case (ESmsDCSAutoDelClassInfoUncompressedText):
+		case (ESmsDCSAutoDelClassInfoTextCompressedText):
+		case (ESmsDCSTextUncompressed7BitOr8Bit):
+			aClass=(TSmsClass) (iValue&ESmsClassMask);
+			return ETrue;
+		default:
+			return EFalse;
+		}
+	} // TSmsDataCodingScheme::Class
+
+
+void TSmsDataCodingScheme::SetClass(TBool aClassDefined,TSmsDataCodingScheme::TSmsClass aClass)
+	{
+	LOGGSMU1("TSmsDataCodingScheme::SetClass()");
+
+	TInt bits7to4=Bits7To4();
+	if (aClassDefined)
+		{
+		switch (bits7to4)
+			{
+			case (ESmsDCSTextUncompressedWithNoClassInfo):
+				{
+				iValue=(TUint8) (ESmsDCSTextUncompressedWithClassInfo|(iValue&ESmsAlphabetMask|aClass));
+				break;
+				}
+			case (ESmsDCSTextCompressedWithNoClassInfo):
+				{
+				iValue=(TUint8) (ESmsDCSTextCompressedWithClassInfo|(iValue&ESmsAlphabetMask|aClass));
+				break;
+				}
+			case (ESmsDCSAutoDelNoClassInfoUncompressedText):
+				{
+				iValue=(TUint8) (ESmsDCSAutoDelClassInfoUncompressedText|(iValue&ESmsAlphabetMask|aClass));
+				break;
+				}
+			case (ESmsDCSAutoDelNoClassInfoCompressedText):
+				{
+				iValue=(TUint8) (ESmsDCSAutoDelClassInfoTextCompressedText|(iValue&ESmsAlphabetMask|aClass));
+				break;
+				}
+			case (ESmsDCSTextUncompressedWithClassInfo):
+			case (ESmsDCSTextCompressedWithClassInfo):
+			case (ESmsDCSAutoDelClassInfoUncompressedText):
+			case (ESmsDCSAutoDelClassInfoTextCompressedText):
+			case (ESmsDCSTextUncompressed7BitOr8Bit):
+
+				{
+				iValue=(TUint8) (iValue&(~ESmsClassMask)|aClass);
+				break;
+				}
+			default:
+		        LOGGSMU1("WARNING! default case has been reached");
+                break;
+			}
+		}
+	else
+		{
+		switch (bits7to4)
+			{
+			case (ESmsDCSTextUncompressedWithClassInfo):
+				{
+				iValue=(TUint8) (ESmsDCSTextUncompressedWithNoClassInfo|(iValue&ESmsAlphabetMask)|aClass);
+				break;
+				}
+			case (ESmsDCSTextCompressedWithClassInfo):
+				{
+				iValue=(TUint8) (ESmsDCSTextCompressedWithNoClassInfo|(iValue&ESmsAlphabetMask)|aClass);
+				break;
+				}
+			case (ESmsDCSAutoDelClassInfoUncompressedText):
+				{
+				iValue=(TUint8) (ESmsDCSAutoDelNoClassInfoUncompressedText|(iValue&ESmsAlphabetMask)|aClass);
+				break;
+				}
+			case (ESmsDCSAutoDelClassInfoTextCompressedText):
+				{
+				iValue=(TUint8) (ESmsDCSAutoDelNoClassInfoCompressedText|(iValue&ESmsAlphabetMask)|aClass);
+				break;
+				}
+			case (ESmsDCSTextUncompressed7BitOr8Bit):
+				{
+				iValue=(TUint8) (ESmsDCSTextUncompressedWithNoClassInfo|(iValue&ESmsAlphabetMask)|aClass);
+				break;
+				}
+			case (ESmsDCSTextUncompressedWithNoClassInfo):
+			case (ESmsDCSTextCompressedWithNoClassInfo):
+			case (ESmsDCSAutoDelNoClassInfoUncompressedText):
+			case (ESmsDCSAutoDelNoClassInfoCompressedText):
+			case (ESmsDCSMessageWaitingIndicationDiscardMessage):
+			case (ESmsDCSMessageWaitingIndication7Bit):
+			case (ESmsDCSMessageWaitingIndicationUCS2):
+			default:
+				{
+				}
+			}
+		}
+	} // TSmsDataCodingScheme::SetClass
+
+
+TSmsDataCodingScheme::TSmsIndicationState TSmsDataCodingScheme::IndicationState() const
+	{
+	LOGGSMU1("TSmsDataCodingScheme::IndicationState()");
+
+	TInt bits7to4=Bits7To4();
+	TSmsIndicationState state=ESmsIndicationInactive;
+	switch (bits7to4)
+		{
+		case (ESmsDCSMessageWaitingIndicationDiscardMessage):
+		case (ESmsDCSMessageWaitingIndication7Bit):
+		case (ESmsDCSMessageWaitingIndicationUCS2):
+			{
+			state=(TSmsIndicationState) (iValue&ESmsIndicationStateMask);
+			break;
+			}
+		default:
+		    LOGGSMU1("WARNING! default case has been reached");
+            break;
+  		}
+	return state;
+	} // TSmsDataCodingScheme::TSmsIndicationState
+
+
+void TSmsDataCodingScheme::SetIndicationState(TSmsIndicationState aState)
+	{
+	LOGGSMU1("TSmsDataCodingScheme::SetIndicationState()");
+
+	TInt bits7to4=Bits7To4();
+	switch (bits7to4)
+		{
+		case (ESmsDCSMessageWaitingIndicationDiscardMessage):
+		case (ESmsDCSMessageWaitingIndication7Bit):
+		case (ESmsDCSMessageWaitingIndicationUCS2):
+			{
+			iValue=(TUint8) (aState | (iValue&(~ESmsIndicationStateMask)));
+			break;
+			}
+		default:
+		    LOGGSMU1("TSmsDataCodingScheme::SetIndicationState() WARNING! default case has been reached");
+            break;
+  		}
+	} // TSmsDataCodingScheme::SetIndicationState
+
+
+TSmsDataCodingScheme::TSmsIndicationType TSmsDataCodingScheme::IndicationType() const
+	{
+	LOGGSMU1("TSmsDataCodingScheme::IndicationType()");
+
+	TInt bits7to4=Bits7To4();
+	TSmsIndicationType type=ESmsVoicemailMessageWaiting;
+	switch (bits7to4)
+		{
+		case (ESmsDCSMessageWaitingIndicationDiscardMessage):
+		case (ESmsDCSMessageWaitingIndication7Bit):
+		case (ESmsDCSMessageWaitingIndicationUCS2):
+			{
+			type=(TSmsIndicationType) (iValue&ESmsIndicationTypeMask);
+			break;
+			}
+		default:
+		    LOGGSMU1("TSmsDataCodingScheme::IndicationType() WARNING default case has been reached");
+            break;
+		}
+	return type;
+	} // TSmsDataCodingScheme::TSmsIndicationType
+
+
+void TSmsDataCodingScheme::SetIndicationType(TSmsIndicationType aType)
+	{
+	LOGGSMU1("TSmsDataCodingScheme::SetIndicationType()");
+
+	TInt bits7to4=Bits7To4();
+	switch (bits7to4)
+		{
+		case (ESmsDCSMessageWaitingIndicationDiscardMessage):
+		case (ESmsDCSMessageWaitingIndication7Bit):
+		case (ESmsDCSMessageWaitingIndicationUCS2):
+			{
+			iValue=(TUint8) (aType | (iValue&(~ESmsIndicationTypeMask)));
+			break;
+			}
+		default:
+		    LOGGSMU1("TSmsDataCodingScheme::SetIndicationType() WARNING! default case has been reached");
+            break;
+ 		}
+	} // TSmsDataCodingScheme::SetIndicationType
+
+
+/**
+ *  Allocates and creates a CSmsAlphabetConverter object, specifying an Alphabet
+ *  Coding scheme and a Binary flag.
+ *  
+ *  @param aCharacterSetConverter Pre-initialised character set converter
+ *  @param aFs File system handle
+ *  @param aSmsAlphabet Data coding scheme alphabet
+ *  @param aIsBinary Set to true for WAP or compressed data
+ *  @return New CSmsAlphabetConverter object
+ *  @capability None
+ */
+EXPORT_C CSmsAlphabetConverter* CSmsAlphabetConverter::NewLC(CCnvCharacterSetConverter& aCharacterSetConverter,RFs& aFs,TSmsDataCodingScheme::TSmsAlphabet aSmsAlphabet,TBool aIsBinary)
+	{
+	LOGGSMU1("CSmsAlphabetConverter::NewLC()");
+
+	CSmsAlphabetConverter* converter=new (ELeave)CSmsAlphabetConverter(aCharacterSetConverter,aFs,aSmsAlphabet,aIsBinary);
+	CleanupStack::PushL(converter);
+	converter->ConstructL();
+	return converter;
+	} // CSmsAlphabetConverter::NewLC
+
+
+/**
+ *  Destructor.
+ *  @capability None
+ */
+EXPORT_C CSmsAlphabetConverter::~CSmsAlphabetConverter()
+    {
+    delete iConvertedNativeCharacters;
+    delete iConvertedUDElements;
+    delete iUnconvertedNativeCharacters;
+    delete iUnconvertedUDElements;
+    } // CSmsAlphabetConverter::NewLC
+
+
+//
+// C'tor - standard stuff
+//
+CSmsAlphabetConverter::CSmsAlphabetConverter(CCnvCharacterSetConverter& aCharacterSetConverter,RFs& aFs,TSmsDataCodingScheme::TSmsAlphabet aSmsAlphabet,TBool aIsBinary)
+    : iCharacterSetConverter(aCharacterSetConverter),
+    iFs(aFs),
+    iSmsAlphabet(aSmsAlphabet),
+    iIsBinary(aIsBinary),
+    iUnconvertedNativeCharactersPtr(NULL,0),
+    iUnconvertedUDElementsPtr(NULL,0)
+    {
+    } // CSmsAlphabetConverter::CSmsAlphabetConverter
+
+
+//
+// Ensures this is a supported character set if not binary conversion
+//
+void CSmsAlphabetConverter::ConstructL()
+	{
+	LOGGSMU1("CSmsAlphabetConverter::ConstructL()");
+
+
+	if (!iIsBinary)
+		{
+		switch (iSmsAlphabet)
+			{
+			case TSmsDataCodingScheme::ESmsAlphabet7Bit:
+			case TSmsDataCodingScheme::ESmsAlphabet8Bit:
+			case TSmsDataCodingScheme::ESmsAlphabetUCS2:
+				{
+				// Supported
+				break;
+				}
+			default:
+				{
+				// Not supported
+				User::Leave(KErrGsmSMSDataCodingSchemeNotSupported);
+				break;
+				}
+			}
+		}
+	} // CSmsAlphabetConverter::ConstructL
+
+
+//
+// Returns whether the character set converter is invoked.  Provided to allow
+// clients to provided efficient converted length calculation where no
+// conversion is required.
+//
+void CSmsAlphabetConverter::ConversionPropertiesL(TSmsAlphabetConversionProperties& aConversionProperties) const
+	{
+	LOGGSMU1("CSmsAlphabetConverter::ConversionPropertiesL()");
+
+
+	// Set defaults
+	aConversionProperties.iWidthConversion=ESmsAlphabetWidthConversionFixed;
+	aConversionProperties.iUDElementsPerNativeCharacter=1;
+	// Modify if different
+	if (iIsBinary)
+		return;
+	switch (iSmsAlphabet)
+		{
+		case TSmsDataCodingScheme::ESmsAlphabet7Bit:
+		case TSmsDataCodingScheme::ESmsAlphabet8Bit:
+			{
+			aConversionProperties.iWidthConversion=ESmsAlphabetWidthConversionVariable;
+			break;
+			}
+		case TSmsDataCodingScheme::ESmsAlphabetUCS2:
+			{
+			aConversionProperties.iUDElementsPerNativeCharacter=sizeof(TText);
+			break;
+			}
+		default:
+			{
+			User::Leave(KErrGsmSMSDataCodingSchemeNotSupported);
+			}
+		}
+	} // CSmsAlphabetConverter::ConversionPropertiesL
+
+
+/**
+ *  Converts from the native character set to unpacked user data elements of the
+ *  desired character set.
+ *  
+ *  The function stores the converted data internally.
+ *  
+ *  @param aNativeCharacters The native character set data (Unicode only)
+ *  @return Converted characters
+ *  @capability None
+ */
+EXPORT_C TPtrC8 CSmsAlphabetConverter::ConvertFromNativeL(const TDesC& aNativeCharacters)
+	{
+	LOGGSMU1("CSmsAlphabetConverter::ConvertFromNativeL()");
+
+	TInt  numberOfUnconvertibleCharacters, numberOfDowngradedCharacters;
+
+	return ConvertFromNativeL(aNativeCharacters, ESmsEncodingNone,
+			                  numberOfUnconvertibleCharacters,
+			                  numberOfDowngradedCharacters);
+	} // CSmsAlphabetConverter::ConvertFromNativeL
+
+
+/**
+ *  Converts from the native character set to unpacked user data elements of the
+ *  desired character set.
+ *  
+ *  The function stores the converted data internally.
+ *  
+ *  @param aNativeCharacters                 The native character set data (Unicode only)
+ *  @param aNumberOfUnconvertibleCharacters  Number of characters unconverted
+ *  @param aNumberOfDowngradedCharacters     Number of characters downgraded
+ *  @param aEncoding                         Alternative 7bit encoding to used (if needed)
+ * 
+ *  @return Converted characters
+ * 
+ *  @capability None
+ */
+EXPORT_C TPtrC8 CSmsAlphabetConverter::ConvertFromNativeL(const TDesC& aNativeCharacters,
+                                                          TSmsEncoding aEncoding,
+                                                          TInt& aNumberOfUnconvertibleCharacters,
+			                                              TInt& aNumberOfDowngradedCharacters)
+	{
+	LOGGSMU2("CSmsAlphabetConverter::ConvertFromNativeL(): aEncoding=%d", aEncoding);
+	
+	aNumberOfUnconvertibleCharacters = 0;
+	aNumberOfDowngradedCharacters    = 0;
+
+	// Check for some shortcuts
+	if (iIsBinary ||  iSmsAlphabet == TSmsDataCodingScheme::ESmsAlphabet8Bit)
+		{
+		// Binary data stored as padded unicode
+		TPtr8 outputPtr=CheckAllocBufferL(&iConvertedUDElements,aNativeCharacters.Length(),0);
+		outputPtr.Copy(aNativeCharacters);
+		iUnconvertedNativeCharactersPtr.Zero();
+		return outputPtr;
+		}
+	else if (iSmsAlphabet==TSmsDataCodingScheme::ESmsAlphabetUCS2)
+		{
+		TInt nativeCharactersLength = aNativeCharacters.Length();
+		// 16-bit copy with possible endianess correction
+		TInt elementCount=nativeCharactersLength*2;
+		TPtr8 outputPtr(CheckAllocBufferL(&iConvertedUDElements,elementCount,elementCount));
+	    for (TInt i=0;i<nativeCharactersLength;i++)
+		    {
+		    outputPtr[2*i]=(TUint8)(aNativeCharacters[i]>>8);
+		    outputPtr[2*i+1]=(TUint8)aNativeCharacters[i];
+		    }
+		iUnconvertedNativeCharactersPtr.Zero();
+		return outputPtr;
+		}
+	else // No shortcuts, do proper conversion
+		{
+		PrepareForConversionFromNativeL(aEncoding);
+		
+		// Create input buffer
+		TInt newInputLength=iUnconvertedNativeCharactersPtr.Length()+aNativeCharacters.Length();
+		iUnconvertedNativeCharactersPtr.Set(CheckAllocBufferL(&iUnconvertedNativeCharacters,newInputLength,iUnconvertedNativeCharactersPtr.Length()));
+		iUnconvertedNativeCharactersPtr.Append(aNativeCharacters);
+
+		// Ensure buffer is at least the length of the input buffer
+		TPtr8 outputPtr=CheckAllocBufferL(&iConvertedUDElements,iUnconvertedNativeCharactersPtr.Length(),0);
+
+		TInt retryCount=0;
+		TInt unconvertedCount=iUnconvertedNativeCharactersPtr.Length();
+		while (unconvertedCount)
+			{
+			TInt  tempNumberOfUnconvertibleCharacters = 0;
+			TInt  tempNumberOfDowngradedCharacters    = 0;
+			
+			// Get a pointer to unfilled area of output buffer
+			TPtr8 fillPtr((TUint8*)outputPtr.Ptr()+outputPtr.Length(),0,outputPtr.MaxLength()-outputPtr.Length());
+			// Try the conversion & get number of unconverted characters
+			TInt newUnconvertedCount=iCharacterSetConverter.ConvertFromUnicode(fillPtr,iUnconvertedNativeCharactersPtr);
+			if (newUnconvertedCount<0)
+				break;
+
+			// Compare what is converted with the original, to get downgrade count
+			TPtr  tempBufPtr((TUint16*)iUnconvertedNativeCharactersPtr.Ptr(), 0, fillPtr.Length());
+			TInt  offset      = aNativeCharacters.Length() - unconvertedCount;
+			TInt  state       = CCnvCharacterSetConverter::KStateDefault;
+			TInt  notRestored = iCharacterSetConverter.ConvertToUnicode(tempBufPtr, fillPtr, state);
+			
+			if (notRestored > 0)
+				{
+				tempNumberOfUnconvertibleCharacters += notRestored;
+				}
+			
+			for (TInt pos = 0;  pos < tempBufPtr.Length();  pos++)
+				{
+				if (tempBufPtr[pos] != aNativeCharacters[offset + pos])
+					{
+					if (tempBufPtr[pos] != KReplacementCharacter)
+						{
+						tempNumberOfDowngradedCharacters++;
+						}
+					else
+						{
+						tempNumberOfUnconvertibleCharacters++;
+						}
+					}
+				}
+
+			//
+			// If characters were downgraded or unconverted then replace them
+			// with downgrades from the PREQ2090 converter.
+			//
+			if (tempNumberOfUnconvertibleCharacters > 0  &&
+				aEncoding != ESmsEncodingNone)
+				{
+				HBufC8*  downgradesBuf = HBufC8::NewLC(iUnconvertedNativeCharactersPtr.Length());
+				HBufC*  nativeBuf = HBufC::NewLC(iUnconvertedNativeCharactersPtr.Length());
+				TPtr8  downgradesPtr = downgradesBuf->Des();
+				TPtr  nativePtr = nativeBuf->Des();
+
+				PrepareForConversionFromNativeL(ESmsEncodingNone);
+
+				// Attempt to convert the text
+	 			TInt ret = iCharacterSetConverter.ConvertFromUnicode(downgradesPtr, iUnconvertedNativeCharactersPtr);
+		 		if (ret >= 0)
+		 			{
+					// Compare what is converted with the original...
+					state       = CCnvCharacterSetConverter::KStateDefault;
+					notRestored = iCharacterSetConverter.ConvertToUnicode(nativePtr, downgradesPtr, state);
+						
+					if (notRestored >= 0)
+						{
+						// Merge in the downgrades
+						TInt  pos;
+						
+						for (pos = 0;  pos < tempBufPtr.Length();  pos++)
+							{
+							if (tempBufPtr[pos] != aNativeCharacters[offset + pos])
+								{
+								if (tempBufPtr[pos] != KReplacementCharacter)
+									{
+									tempBufPtr[pos] = nativePtr[pos];
+									}
+								}
+							}
+
+						// Reconvert...
+						PrepareForConversionFromNativeL(aEncoding);
+
+						newUnconvertedCount=iCharacterSetConverter.ConvertFromUnicode(fillPtr,iUnconvertedNativeCharactersPtr);
+						if (newUnconvertedCount<0)
+							break;
+
+						// Recount the changed characters...
+						tempNumberOfUnconvertibleCharacters = 0;
+						tempNumberOfDowngradedCharacters    = 0;
+
+						for (pos = 0;  pos < tempBufPtr.Length();  pos++)
+							{
+							if (tempBufPtr[pos] != aNativeCharacters[offset + pos])
+								{
+								if (tempBufPtr[pos] != KReplacementCharacter)
+									{
+									tempNumberOfDowngradedCharacters++;
+									}
+								else
+									{
+									tempNumberOfUnconvertibleCharacters++;
+									}
+								}
+							}
+		 				}
+					}
+				
+				CleanupStack::PopAndDestroy(2, downgradesBuf);
+				}
+
+			//
+			// Store these downgraded/unconvertible character counts...
+			//
+			aNumberOfDowngradedCharacters    += tempNumberOfDowngradedCharacters;
+			aNumberOfUnconvertibleCharacters += tempNumberOfUnconvertibleCharacters;
+			
+			// Update original buffer length, check retry count and realloc if req'd
+			outputPtr.SetLength(outputPtr.Length()+fillPtr.Length());
+			if (newUnconvertedCount==unconvertedCount)
+				{
+				if (++retryCount>KMaxSmsAlphabetConversionRetries)
+					{
+					__ASSERT_DEBUG(EFalse,Panic(KGsmuPanicConversionRetriedOut));
+					break;
+					}
+				}
+			else
+				{
+				iUnconvertedNativeCharactersPtr.Delete(0,unconvertedCount-newUnconvertedCount);
+				retryCount=0;
+				}
+			unconvertedCount=newUnconvertedCount;
+			// Check for realloc
+			if (unconvertedCount)
+				outputPtr.Set(CheckAllocBufferL(&iConvertedUDElements,iConvertedUDElements->Length()+Max(unconvertedCount,KMinSmsAlphabetConversionAllocIncrement),outputPtr.Length()));
+			}
+
+		return outputPtr;
+		}
+	} // CSmsAlphabetConverter::ConvertFromNativeL
+
+
+/**
+ *  Converts the user data elements of the specified character set to the native
+ *  character set.
+ *  
+ *  @param aUDElements The converted character set data
+ * 
+ *  @return Native character set data (Unicode only)
+ * 
+ *  @capability None
+ */
+EXPORT_C TPtrC CSmsAlphabetConverter::ConvertToNativeL(const TDesC8& aUDElements)
+	{
+	LOGGSMU1("CSmsAlphabetConverter::ConvertToNativeL()");
+
+	return ConvertToNativeL(aUDElements, ESmsEncodingNone);
+	} // CSmsAlphabetConverter::ConvertToNativeL
+
+
+/**
+ *  Converts the user data elements of the specified character set to the native
+ *  character set.
+ *  
+ *  @param aUDElements The converted character set data
+ *  @param aEncoding   Alternative 7bit encoding to used (if needed)
+ * 
+ *  @return Native character set data (Unicode only)
+ * 
+ *  @capability None
+ */
+EXPORT_C TPtrC CSmsAlphabetConverter::ConvertToNativeL(const TDesC8& aUDElements,
+													   TSmsEncoding aEncoding)
+	{
+	LOGGSMU2("CSmsAlphabetConverter::ConvertToNativeL(): aEncoding=%d", aEncoding);
+
+	// Check for some shortcuts
+	if (iIsBinary ||  iSmsAlphabet == TSmsDataCodingScheme::ESmsAlphabet8Bit)
+		{
+		// Binary data stored as padded unicode
+		TPtr16 outputPtr=CheckAllocBufferL(&iConvertedNativeCharacters,aUDElements.Length(),0);
+		outputPtr.Copy(aUDElements);
+		iUnconvertedUDElementsPtr.Zero();
+		return outputPtr;
+		}
+	else if (iSmsAlphabet==TSmsDataCodingScheme::ESmsAlphabetUCS2)
+		{
+		// 16-bit copy with possible endianess correction
+		TInt charCount=aUDElements.Length()/2;
+		TPtr16 outputPtr=CheckAllocBufferL(&iConvertedNativeCharacters,charCount,charCount);
+	    for (TInt i=0; i<charCount; i++)
+		    {
+		    outputPtr[i]=(TText)(aUDElements[2*i]<<8);
+		    outputPtr[i]=(TText)(outputPtr[i]+(aUDElements[2*i+1]));
+		    }
+		iUnconvertedUDElementsPtr.Zero();
+		return outputPtr;
+		}
+	else
+		{
+		PrepareForConversionToNativeL(aEncoding);
+
+		// Create input buffer with unconverted characters prepended
+		TInt newInputLength=iUnconvertedUDElementsPtr.Length()+aUDElements.Length();
+		iUnconvertedUDElementsPtr.Set(CheckAllocBufferL(&iUnconvertedUDElements,newInputLength,iUnconvertedUDElementsPtr.Length()));
+		iUnconvertedUDElementsPtr.Append(aUDElements);
+
+		// Ensure buffer is at least the length of the input buffer
+		TPtr outputPtr=CheckAllocBufferL(&iConvertedNativeCharacters,iUnconvertedUDElementsPtr.Length(),0);
+
+		TInt retryCount=0;
+		TInt unconvertedCount=iUnconvertedUDElementsPtr.Length();
+		TInt state=CCnvCharacterSetConverter::KStateDefault;
+		while (unconvertedCount)
+			{
+			// Get a pointer to unfilled area of output buffer
+			TPtr16 fillPtr((TUint16*)outputPtr.Ptr()+outputPtr.Length(),0,outputPtr.MaxLength()-outputPtr.Length());
+			// Try the conversion & get number of unconverted characters
+			TInt newUnconvertedCount=iCharacterSetConverter.ConvertToUnicode(fillPtr,iUnconvertedUDElementsPtr,state);
+			if (newUnconvertedCount<0)
+				break;
+			// Update original buffer length & check retry count
+			outputPtr.SetLength(outputPtr.Length()+fillPtr.Length());
+			if (newUnconvertedCount==unconvertedCount)
+				{
+				if (++retryCount>KMaxSmsAlphabetConversionRetries)
+					{
+					__ASSERT_DEBUG(EFalse,Panic(KGsmuPanicConversionRetriedOut));
+					break;
+					}
+				}
+			else
+				{
+				iUnconvertedUDElementsPtr.Delete(0,unconvertedCount-newUnconvertedCount);
+				retryCount=0;
+				}
+			unconvertedCount=newUnconvertedCount;
+			// Check for realloc
+			if (unconvertedCount)
+				outputPtr.Set(CheckAllocBufferL(&iConvertedNativeCharacters,iConvertedNativeCharacters->Length()+Max(unconvertedCount,KMinSmsAlphabetConversionAllocIncrement),outputPtr.Length()));
+			}
+		return outputPtr;
+		}
+	} // CSmsAlphabetConverter::ConvertToNativeL
+
+
+/**
+ *  Tests if the character is supported by the current character set.
+ *  This function can be used with 7bit and 8bit alphabets.
+ * 
+ *  @param aChar  Character to investigate.
+ * 
+ *  @return  ETrue if the character is supported.
+ * 
+ *  @note Since the function is based on the old behaviour (pre-PREQ2090)
+ *        it does not accept a downgraded character or alternative encoding
+ *        as being supported.
+ */
+TBool CSmsAlphabetConverter::IsSupportedL(TChar aChar)
+	{
+	LOGGSMU2("[1] CSmsAlphabetConverter::IsSupportedL(aChar=0x%04x)", (TUint) aChar);
+
+	TBool isDowngrade, isRequiresAlternativeEncoding;
+
+    TBool  supported = IsSupportedL(aChar, ESmsEncodingNone,
+            isDowngrade, isRequiresAlternativeEncoding);
+	
+	LOGGSMU2("CSmsAlphabetConverter::IsSupportedL(): supported=%d.", supported);
+
+	return supported;
+	} // CSmsAlphabetConverter::IsSupportedL
+
+
+/**
+ *  Tests if the descriptor text is supported by the current character set.
+ *  This function can be used with 7bit and 8bit alphabets.
+ * 
+ *  @param aDes                                 Text string to check.
+ *  @param aNumberOfUnconvertibleCharacters     Exit param for the number of
+ *                                              characters unconvertible.
+ *  @param aIndexOfFirstUnconvertibleCharacter  Exit param for the first
+ *                                              unconverted character.
+ * 
+ *  @return  ETrue if the character is supported.
+ */
+TBool CSmsAlphabetConverter::IsSupportedL(const TDesC& aDes, TInt& aNumberOfUnconvertibleCharacters,
+                                          TInt& aIndexOfFirstUnconvertibleCharacter)
+	{
+	LOGGSMU2("[2] CSmsAlphabetConverter::IsSupportedL(aDes=\"%S\")", &aDes);
+
+	TInt desLength = aDes.Length();
+	//
+	// Initialise the exit params...
+	//
+	aNumberOfUnconvertibleCharacters    = 0;
+	aIndexOfFirstUnconvertibleCharacter = desLength;
+
+    //
+    // Create buffers for the input converted to 7Bit and a buffer for it once
+    // converted back again...
+    //
+    HBufC8* encodedBuf       = HBufC8::NewLC(desLength*2); // worse case
+    HBufC*  backToUnicodeAfterStdBuf = HBufC::NewLC(desLength);
+    TPtr8  encoded(encodedBuf->Des());
+    TPtr  backToUnicodeAfterStd(backToUnicodeAfterStdBuf->Des());
+
+    //
+    // Convert the input string to standard 7bit (with downgrades if needed)...
+    // 
+    PrepareForConversionFromNativeL(ESmsEncodingNone);
+
+    TInt  notConverted = iCharacterSetConverter.ConvertFromUnicode(encoded, aDes);
+
+    if (notConverted > 0)
+        {
+        aNumberOfUnconvertibleCharacters += notConverted;
+        }
+    else if (notConverted < 0)
+        {
+        aNumberOfUnconvertibleCharacters = desLength;
+        }
+    
+    //
+    // Convert it back again to the native format...
+    //
+    TInt  state       = CCnvCharacterSetConverter::KStateDefault;
+    TInt  notRestored = iCharacterSetConverter.ConvertToUnicode(backToUnicodeAfterStd, encoded, state);
+
+    if (notRestored > 0)
+        {
+        aNumberOfUnconvertibleCharacters += notRestored;
+        }
+    else if (notRestored < 0)
+        {
+        aNumberOfUnconvertibleCharacters = desLength;
+        }
+
+    //
+    // Work out if the string is acceptable as it is (e.g. no unconvertible
+    // and no downgrades). We only need do this if the previous conversions were
+    // complete with no issues.
+    //
+    for (TInt pos = desLength-1;  pos >= 0;  --pos)
+        {
+        if (backToUnicodeAfterStd[pos] != aDes[pos])
+            {
+            aNumberOfUnconvertibleCharacters++;
+            aIndexOfFirstUnconvertibleCharacter = pos;
+            }
+        }
+    
+    CleanupStack::PopAndDestroy(backToUnicodeAfterStdBuf);
+    CleanupStack::PopAndDestroy(encodedBuf);
+	
+	//
+	// Useful logging...
+	//
+	TBool  supported = (aNumberOfUnconvertibleCharacters == 0);
+
+	LOGGSMU2("CSmsAlphabetConverter::IsSupportedL(): aNumberOfUnconvertibleCharacters=%d.", aNumberOfUnconvertibleCharacters);
+	LOGGSMU2("CSmsAlphabetConverter::IsSupportedL(): aIndexOfFirstUnconvertibleCharacter=%d.", aIndexOfFirstUnconvertibleCharacter);
+	LOGGSMU2("CSmsAlphabetConverter::IsSupportedL(): supported=%d.", supported);
+
+	return supported;
+	} // CSmsAlphabetConverter::IsSupportedL
+
+
+/**
+ *  Tests if the character is supported by the current character set.
+ *  This function can be used with 7bit and 8bit alphabets.
+ * 
+ *  @param aChar                         Character to investigate.
+ *  @param aEncoding                     Alternative 7bit encoding (if used).
+ *  @param aIsDowngrade                  Exit param set to ETrue if the
+ *                                       character has to be downgraded.
+ *  @param aRequiresAlternativeEncoding  Exit param set to ETrue if the
+ *                                       alternative encoding has to be
+ *                                       used to encode it.
+ * 
+ *  @return  ETrue if the character is supported.
+ */
+TBool CSmsAlphabetConverter::IsSupportedL(TChar aChar, TSmsEncoding aEncoding,
+		                                  TBool& aIsDowngrade,
+                                          TBool& aRequiresAlternativeEncoding)
+	{
+	LOGGSMU2("[3] CSmsAlphabetConverter::IsSupportedL(aChar=0x%04x)", (TUint) aChar);
+
+	//
+	// Convert the character...
+	//
+	TInt  numberOfUnconvertibleCharacters, numberOfDowngradedCharacters, 
+            numberRequiringAlternativeEncoding, indexOfFirstUnconvertibleCharacter;
+	TBuf<4>   toEncode;
+
+	toEncode.SetLength(1);
+	toEncode[0]=(TText)aChar;
+
+	TBool supported = IsSupportedL(toEncode, aEncoding, 
+	        numberOfUnconvertibleCharacters,
+	        numberOfDowngradedCharacters,
+	        numberRequiringAlternativeEncoding,
+	        indexOfFirstUnconvertibleCharacter);
+
+	//
+	// Calculate the exit params...
+	//
+	aIsDowngrade                 = (numberOfDowngradedCharacters > 0);
+	aRequiresAlternativeEncoding = (numberRequiringAlternativeEncoding > 0);
+	    
+	//
+	// Useful logging...
+	//
+	LOGGSMU2("CSmsAlphabetConverter::IsSupportedL(): aIsDowngrade=%d.", aIsDowngrade);
+	LOGGSMU2("CSmsAlphabetConverter::IsSupportedL(): aRequiresAlternativeEncoding=%d.", aRequiresAlternativeEncoding);
+	LOGGSMU2("CSmsAlphabetConverter::IsSupportedL(): supported=%d.", supported);
+
+	return supported;
+	} // CSmsAlphabetConverter::IsSupportedL
+
+
+/**
+ *  Tests if the descriptor text is supported by the current character set.
+ *  This function can be used with 7bit and 8bit alphabets.
+ * 
+ *  @param aDes                                 Text string to check.
+ *  @param aEncoding                            Alternative 7bit encoding (if used).
+ *  @param aNumberOfUnconvertibleCharacters     Exit param for the number of
+ *                                              characters unconvertible.
+ *  @param aNumberOfDowngradedCharacters        Exit param for the number of
+ *                                              downgraded characters.
+ *  @param aNumberRequiringAlternativeEncoding  Exit param for the number of
+ *                                              characters requiring use of
+ *                                              the alternative encoder.
+ *  @param aIndexOfFirstUnconvertibleCharacter  Exit param for the first
+ *                                              unconverted character.
+ * 
+ *  @return  ETrue if the character is supported.
+ */
+TBool CSmsAlphabetConverter::IsSupportedL(const TDesC& aDes, TSmsEncoding aEncoding,
+										  TInt& aNumberOfUnconvertibleCharacters,
+                                          TInt& aNumberOfDowngradedCharacters,
+                                          TInt& aNumberRequiringAlternativeEncoding,
+                                          TInt& aIndexOfFirstUnconvertibleCharacter)
+	{
+	LOGGSMU2("[4] CSmsAlphabetConverter::IsSupportedL(aDes=\"%S\")", &aDes);
+
+	TInt desLength = aDes.Length();
+	//
+	// Initialise the exit params...
+	//
+	aNumberOfUnconvertibleCharacters    = 0;
+	aNumberOfDowngradedCharacters       = 0;
+	aNumberRequiringAlternativeEncoding = 0;
+	aIndexOfFirstUnconvertibleCharacter = desLength;
+	
+	//
+	// Create buffers for the input converted to 7Bit and a buffer for it once
+	// converted back again...
+	//
+    HBufC8* encodedBuf       = HBufC8::NewLC(desLength*2); // worse case
+    HBufC*  backToUnicodeAfterStdBuf = HBufC::NewLC(desLength);
+    TPtr8  encoded(encodedBuf->Des());
+    TPtr  backToUnicodeAfterStd(backToUnicodeAfterStdBuf->Des());
+
+    //
+    // Convert the input string to standard 7bit (with downgrades if needed)...
+    // 
+    PrepareForConversionFromNativeL(ESmsEncodingNone);
+
+    TInt  notConverted = iCharacterSetConverter.ConvertFromUnicode(encoded, aDes);
+
+    if (notConverted > 0)
+        {
+        aNumberOfUnconvertibleCharacters += notConverted;
+        }
+    else if (notConverted < 0)
+        {
+        aNumberOfUnconvertibleCharacters = desLength;
+        }
+    
+    //
+    // Convert it back again to the native format...
+    //
+    TInt  state       = CCnvCharacterSetConverter::KStateDefault;
+    TInt  notRestored = iCharacterSetConverter.ConvertToUnicode(backToUnicodeAfterStd, encoded, state);
+
+    if (notRestored > 0)
+        {
+        aNumberOfUnconvertibleCharacters += notRestored;
+        }
+    else if (notRestored < 0)
+        {
+        aNumberOfUnconvertibleCharacters = desLength;
+        }
+
+    //
+    // Work out if the string is acceptable as it is (e.g. no unconvertible
+    // and no downgrades).
+    //
+    for (TInt pos = desLength-1;  pos >= 0;  --pos)
+        {
+        if (backToUnicodeAfterStd[pos] != aDes[pos])
+            {
+            if (backToUnicodeAfterStd[pos] != KReplacementCharacter)
+                {
+                aNumberOfDowngradedCharacters++;
+                }
+            else
+                {
+                aNumberOfUnconvertibleCharacters++;
+                aIndexOfFirstUnconvertibleCharacter = pos;
+                }
+            }
+        }
+
+    TInt  totalCharFaultsSoFar = aNumberOfUnconvertibleCharacters + 
+                                    aNumberOfDowngradedCharacters;
+    
+    //
+    // If the total unconvertible plus downgrades is zero, then there is nothing
+    // more to do as the string can be converted to 7bit with no issues and no
+    // other encoder is needed.
+    //
+    // Otherwise we have to look at the alternative encoder...
+    //
+    if (totalCharFaultsSoFar == 0)
+        {
+        //
+        // We are done (the return counts are already zero and therefore
+        // correct at this point too!).
+        //
+        }
+    else if (iSmsAlphabet != TSmsDataCodingScheme::ESmsAlphabet7Bit  ||
+             aEncoding == ESmsEncodingNone)
+        {
+        //
+        // The string was not perfectly converted, but there is no alternative
+        // encoder to try.  We are done.
+        //
+        }
+    else
+        {
+        //
+        // Initialise the params...
+        //
+        TInt  tmpDowngradedCharacters        = 0;
+        TInt  tmpUnconvertibleCharacters     = 0;
+        TInt  tmpIndexOfFirstUnconvertibleCharacter = desLength;
+		
+        //
+        // Convert the input string to the alternative encoding...
+        //
+        PrepareForConversionFromNativeL(aEncoding);
+
+        notConverted = iCharacterSetConverter.ConvertFromUnicode(encoded, aDes);
+        if (notConverted > 0)
+            {
+            tmpUnconvertibleCharacters = notConverted;
+            }
+        else if (notConverted < 0)
+            {
+            tmpUnconvertibleCharacters = desLength;
+            }
+
+        //
+        // Convert it back again to the native format...
+        //
+        HBufC*  backToUnicodeAfterAltBuf = HBufC::NewLC(desLength);
+        TPtr  backToUnicodeAfterAlt(backToUnicodeAfterAltBuf->Des());
+        TInt  state       = CCnvCharacterSetConverter::KStateDefault;
+        TInt  notRestored = iCharacterSetConverter.ConvertToUnicode(backToUnicodeAfterAlt, encoded, state);
+
+        if (notRestored > 0)
+            {
+            tmpUnconvertibleCharacters += notRestored;
+            }
+        else if (notRestored < 0)
+            {
+            tmpUnconvertibleCharacters = desLength;
+            }
+
+        //
+        // Now work out which characters are downgrades, require alternative encoding
+        // or are unsupported.
+        //
+        for (TInt pos = desLength-1;  pos >= 0;  --pos)
+            {
+            if (backToUnicodeAfterStd[pos] != aDes[pos])
+                {
+                // Not supported by standard encoder...
+                if (backToUnicodeAfterAlt[pos] == aDes[pos])
+                    {
+                    // Supported by alternative encoder...
+                    aNumberRequiringAlternativeEncoding++;
+                    }
+                else if (backToUnicodeAfterStd[pos] != KReplacementCharacter)
+                    {
+                    // Downgraded by standard encoder...
+                    tmpDowngradedCharacters++;
+                    }
+                else if (backToUnicodeAfterAlt[pos] != KReplacementCharacter)
+                    {
+                    // Downgraded by alternative encoder...
+                    tmpDowngradedCharacters++;
+                    aNumberRequiringAlternativeEncoding++;
+                    }
+                else
+                    {
+                    // Unconvertible...
+                    tmpUnconvertibleCharacters++;
+                    tmpIndexOfFirstUnconvertibleCharacter = pos;
+                    }
+                }
+            }
+
+        // Is this better?  
+        if ( totalCharFaultsSoFar >= (tmpUnconvertibleCharacters + tmpDowngradedCharacters) )
+            {
+            // Best conversion is the alternative conversion
+            aNumberOfUnconvertibleCharacters     = tmpUnconvertibleCharacters;
+            aNumberOfDowngradedCharacters        = tmpDowngradedCharacters;
+            aIndexOfFirstUnconvertibleCharacter  = tmpIndexOfFirstUnconvertibleCharacter;
+            }
+        else
+            {
+            // Best conversion is the standard conversion
+            aNumberRequiringAlternativeEncoding = 0;
+            }
+        
+        CleanupStack::PopAndDestroy(backToUnicodeAfterAltBuf);
+        }
+    
+    CleanupStack::PopAndDestroy(backToUnicodeAfterStdBuf);
+    CleanupStack::PopAndDestroy(encodedBuf);
+
+	//
+	// Useful logging...
+	//
+	TBool  supported = (aNumberOfUnconvertibleCharacters == 0);
+
+	LOGGSMU2("CSmsAlphabetConverter::IsSupportedL(): aNumberOfUnconvertibleCharacters=%d.", aNumberOfUnconvertibleCharacters);
+	LOGGSMU2("CSmsAlphabetConverter::IsSupportedL(): aNumberOfDowngradedCharacters=%d.", aNumberOfDowngradedCharacters);
+	LOGGSMU2("CSmsAlphabetConverter::IsSupportedL(): aNumberRequiringAlternativeEncoding=%d.", aNumberRequiringAlternativeEncoding);
+	LOGGSMU2("CSmsAlphabetConverter::IsSupportedL(): aIndexOfFirstUnconvertibleCharacter=%d.", aIndexOfFirstUnconvertibleCharacter);
+	LOGGSMU2("CSmsAlphabetConverter::IsSupportedL(): supported=%d.", supported);
+
+	return supported;
+	} // CSmsAlphabetConverter::IsSupportedL
+
+
+/**
+ *  Given a piece of text and an alternative encoding, this function works out
+ *  which encoding is best to use and returns the ID of that converter.
+ * 
+ *  @param aNativeCharacters      Text to use as a sample.
+ *  @param aEncoding              Suggested alternative 7bit encoding method.
+ * 
+ *  @return Encoding that should be used.
+ */
+TSmsEncoding CSmsAlphabetConverter::FindBestAlternativeEncodingL(const TDesC& aNativeCharacters,
+									                     		 TSmsEncoding aSuggestedEncoding)
+	{
+	LOGGSMU2("CSmsAlphabetConverter::FindBestAlternativeEncodingL(): aSuggestedEncoding=%d",
+			 aSuggestedEncoding);
+
+	TSmsEncoding  encodingToUse = ESmsEncodingNone;
+
+	//
+	// If this is not 7bit or the alternative encoding is not set then do
+	// nothing...
+	//
+	if (aSuggestedEncoding != ESmsEncodingNone  &&
+		iSmsAlphabet == TSmsDataCodingScheme::ESmsAlphabet7Bit)
+		{
+		TInt  numberOfUnconvertibleCharacters, numberOfDowngradedCharacters;
+		TInt  numberRequiringAlternativeEncoding, indexOfFirstUnconvertibleCharacter;
+		
+		//
+		// First try the default encoding (but in this case treat downgrades
+		// as unconverted, since later encoders might do better)...
+		//
+		IsSupportedL(aNativeCharacters, ESmsEncodingNone,
+					 numberOfUnconvertibleCharacters,
+                     numberOfDowngradedCharacters,
+                     numberRequiringAlternativeEncoding,
+                     indexOfFirstUnconvertibleCharacter);
+
+		TInt leastUnconvertibleCharacters = numberOfUnconvertibleCharacters + numberOfDowngradedCharacters;
+
+		//
+		// Create a list of alternative encodings to try...
+		//
+		TSmsEncoding  encodingList[8];
+		TInt          encodingCount = 0;
+		
+		if (aSuggestedEncoding == ESmsEncodingTurkishLockingAndSingleShift)
+			{
+			encodingList[encodingCount++] = ESmsEncodingTurkishSingleShift;
+			encodingList[encodingCount++] = ESmsEncodingTurkishLockingShift;
+			}
+		else if (aSuggestedEncoding == ESmsEncodingPortugueseLockingAndSingleShift)
+			{
+			encodingList[encodingCount++] = ESmsEncodingPortugueseSingleShift;
+			encodingList[encodingCount++] = ESmsEncodingPortugueseLockingShift;
+			}
+
+		encodingList[encodingCount++] = aSuggestedEncoding;
+		encodingList[encodingCount++] = ESmsEncodingNone;
+
+		//
+		// Now try the all the alternatives...
+		//
+		for (TInt  encoder = 0;  encoder < encodingCount;  encoder++)
+			{
+			IsSupportedL(aNativeCharacters, encodingList[encoder],
+						 numberOfUnconvertibleCharacters,
+	                     numberOfDowngradedCharacters,
+	                     numberRequiringAlternativeEncoding,
+	                     indexOfFirstUnconvertibleCharacter);
+			if (numberOfUnconvertibleCharacters + numberOfDowngradedCharacters < leastUnconvertibleCharacters)
+				{
+				encodingToUse = encodingList[encoder];
+				leastUnconvertibleCharacters = numberOfUnconvertibleCharacters + numberOfDowngradedCharacters;
+				}
+			}
+		}
+
+	LOGGSMU2("CSmsAlphabetConverter::FindBestAlternativeEncodingL(): encodingToUse=%d", encodingToUse);
+
+	return encodingToUse;
+	} // CSmsAlphabetConverter::FindBestAlternativeEncoding
+
+
+/**
+ *  Confirms that the requested encoding method is present (e.g. the converter
+ *  plug-in can be loaded).
+ * 
+ *  @param aEncoding  Alternative 7bit encoding method.
+ * 
+ *  @leave KErrNotSupported if the encoder is not available.
+ */
+void CSmsAlphabetConverter::ConfirmAlternativeEncoderL(TSmsEncoding aEncoding) const
+	{
+	//
+	// Check the ID for the encoder exists...
+	//
+	if (aEncoding != ESmsEncodingNone)
+		{
+		TUint  encoderID;
+		
+		GetAlternativeEncoderIDL(aEncoding, encoderID);
+		
+		//
+		// Confirm it can be loaded...
+		//
+		if (iCharacterSetConverter.PrepareToConvertToOrFromL(encoderID, iFs) != CCnvCharacterSetConverter::EAvailable)
+			{
+			User::Leave(KErrNotSupported);
+			}
+		}
+	} // CSmsAlphabetConverter::ConfirmAlternativeEncoderL
+
+
+/**
+ *  Prepares the converted for conversion from native charset.
+ *  Character set specific preparation is performed here.
+ * 
+ *  @param aEncoding  Alternative 7bit encoding to use if required.
+ */
+void CSmsAlphabetConverter::PrepareForConversionFromNativeL(TSmsEncoding aEncoding)
+	{
+	LOGGSMU2("CSmsAlphabetConverter::PrepareForConversionFromNativeL(): aEncoding=%d",
+			 aEncoding);
+
+	__ASSERT_DEBUG(iIsBinary==EFalse,Panic(KGsmuPanicUnsupportedAlphabet));
+	switch (iSmsAlphabet)
+		{
+		case TSmsDataCodingScheme::ESmsAlphabet7Bit:
+			{
+			//
+			// If an alternative encoding has been specified then try and
+			// load that converter...
+			//
+			if (aEncoding != ESmsEncodingNone)
+				{
+				TUint  alternativeEncoderID;
+				
+				GetAlternativeEncoderIDL(aEncoding, alternativeEncoderID);
+				if (alternativeEncoderID != 0)
+					{
+					CCnvCharacterSetConverter::TAvailability  availability;
+		
+					LOGGSMU2("CSmsAlphabetConverter::PrepareForConversionFromNativeL(): Converter 0x%08x",
+							 alternativeEncoderID);
+					
+					availability = iCharacterSetConverter.PrepareToConvertToOrFromL(alternativeEncoderID, iFs);
+					if (availability == CCnvCharacterSetConverter::EAvailable)
+						{
+			 			// Force unicode line termination characters to simple line feed
+			 			iCharacterSetConverter.SetDowngradeForExoticLineTerminatingCharacters(
+				 				CCnvCharacterSetConverter::EDowngradeExoticLineTerminatingCharactersToJustLineFeed);
+					
+						// Job done, return
+			 			return;
+						}
+					
+					// Plug-in could not be loaded, so drop through and load the default!
+					}
+				}
+			
+			//
+			// Check for the PREQ2090 7bit converter with Eastern European
+			// downgrade support first, otherwise if the plug-in is not found
+			// use the standard internal converter.
+			//
+			CCnvCharacterSetConverter::TAvailability  availability;
+			
+			availability = iCharacterSetConverter.PrepareToConvertToOrFromL(KCharacterSetIdentifierExtendedSms7Bit, iFs);
+			if (availability == CCnvCharacterSetConverter::ENotAvailable)
+				{
+				availability = iCharacterSetConverter.PrepareToConvertToOrFromL(KCharacterSetIdentifierSms7Bit, iFs);
+				if (availability == CCnvCharacterSetConverter::ENotAvailable)
+					{
+					User::Leave(KErrNotFound);
+					}
+				}
+
+ 			// Force unicode line termination characters to simple line feed
+ 			iCharacterSetConverter.SetDowngradeForExoticLineTerminatingCharacters(
+ 				CCnvCharacterSetConverter::EDowngradeExoticLineTerminatingCharactersToJustLineFeed);
+			break;
+			}
+		case TSmsDataCodingScheme::ESmsAlphabet8Bit:
+			{
+			CCnvCharacterSetConverter::TAvailability availability=iCharacterSetConverter.PrepareToConvertToOrFromL(KCharacterSetIdentifierCodePage1252,iFs);
+			if (availability==CCnvCharacterSetConverter::ENotAvailable)
+				{
+				User::Leave(KErrNotFound);
+				}
+
+ 			// Force unicode line termination characters to simple line feed
+ 			iCharacterSetConverter.SetDowngradeForExoticLineTerminatingCharacters(
+ 				CCnvCharacterSetConverter::EDowngradeExoticLineTerminatingCharactersToJustLineFeed);
+			break;
+			}
+		case TSmsDataCodingScheme::ESmsAlphabetUCS2:
+		default:
+			{
+            User::Leave(KErrNotSupported);
+			}
+		}
+	} // CSmsAlphabetConverter::PrepareForConversionFromNativeL
+
+
+/**
+ *  Prepares the converted for conversion to unicode.  Character set
+ *  specific preparation is performed here.
+ * 
+ *  @param aEncoding  Alternative 7bit encoding to use if required.
+ */
+void CSmsAlphabetConverter::PrepareForConversionToNativeL(TSmsEncoding aEncoding)
+	{
+	LOGGSMU2("CSmsAlphabetConverter::PrepareForConversionToNativeL(): aEncoding=%d",
+			 aEncoding);
+
+	switch (iSmsAlphabet)
+		{
+		case TSmsDataCodingScheme::ESmsAlphabet7Bit:
+			{
+			//
+			// If an alternative encoding has been specified then try and
+			// load that converter...
+			//
+			if (aEncoding != ESmsEncodingNone)
+				{
+				TUint  alternativeEncoderID;
+				
+				GetAlternativeEncoderIDL(aEncoding, alternativeEncoderID);
+				if (alternativeEncoderID != 0)
+					{
+					CCnvCharacterSetConverter::TAvailability  availability;
+		
+					LOGGSMU2("CSmsAlphabetConverter::PrepareForConversionFromNativeL(): Converter 0x%08x",
+							 alternativeEncoderID);
+					
+					availability = iCharacterSetConverter.PrepareToConvertToOrFromL(alternativeEncoderID, iFs);
+					if (availability == CCnvCharacterSetConverter::EAvailable)
+						{
+						// Job done, return
+			 			return;
+						}
+					
+					// Plug-in could not be loaded, so drop through and load the default!
+					}
+				}
+			
+			//
+			// Always use the internal converter, as it is quicker to prepare
+			// and the PREQ2090 7bit converter with Eastern European downgrade
+			// offers no benefit when converting to native.
+			//
+			CCnvCharacterSetConverter::TAvailability availability=iCharacterSetConverter.PrepareToConvertToOrFromL(KCharacterSetIdentifierSms7Bit,iFs);
+			if (availability==CCnvCharacterSetConverter::ENotAvailable)
+				{
+				User::Leave(KErrNotFound);
+				}
+			break;
+			}
+		case TSmsDataCodingScheme::ESmsAlphabet8Bit:
+			{
+			CCnvCharacterSetConverter::TAvailability availability=iCharacterSetConverter.PrepareToConvertToOrFromL(KCharacterSetIdentifierCodePage1252,iFs);
+			if (availability==CCnvCharacterSetConverter::ENotAvailable)
+				{
+				User::Leave(KErrNotFound);
+				}
+			break;
+			}
+		case TSmsDataCodingScheme::ESmsAlphabetUCS2:
+		default:
+			{
+			User::Leave(KErrNotSupported);
+			}
+		}
+	} // CSmsAlphabetConverter::PrepareForConversionToNativeL
+
+
+/**
+ *  This function returns the alternative encoding converters that are used
+ *  incase the default GSM encoding cannot encode the message completely
+ *  without data loss.
+ * 
+ *  @param aEncoding   Encoding to obtain the converter for.
+ *  @param aEncoderID  Returned converter UID if present.
+ * 
+ *  @leave KErrArgument if the encoding enum is invalid or
+ */
+void CSmsAlphabetConverter::GetAlternativeEncoderIDL(TSmsEncoding aEncoding, TUint& aEncoderID) const
+	{
+	LOGGSMU2("CSmsAlphabetConverter::GetAlternativeEncoderIDL(%d)", aEncoding);
+
+	aEncoderID = 0;
+	
+	//
+	// Decide on appropriate encoders.
+	//
+	switch (aEncoding)
+		{
+		case ESmsEncodingNone:
+			{
+			// Nothing to set.
+			}
+			break;
+		
+		case ESmsEncodingTurkishSingleShift:
+			{
+			aEncoderID = KCharacterSetIdentifierTurkishSingleSms7Bit;
+			}
+			break;
+		
+		case ESmsEncodingTurkishLockingShift:
+			{
+			aEncoderID = KCharacterSetIdentifierTurkishLockingSms7Bit;
+			}
+			break;
+		
+		case ESmsEncodingTurkishLockingAndSingleShift:
+			{
+			aEncoderID = KCharacterSetIdentifierTurkishLockingAndSingleSms7Bit;
+			}
+			break;
+		
+		case ESmsEncodingSpanishSingleShift:
+			{
+			aEncoderID = KCharacterSetIdentifierSpanishSingleSms7Bit;
+			}
+			break;
+		
+		case ESmsEncodingPortugueseSingleShift:
+			{
+			aEncoderID = KCharacterSetIdentifierPortugueseSingleSms7Bit;
+			}
+			break;
+		
+		case ESmsEncodingPortugueseLockingShift:
+			{
+			aEncoderID = KCharacterSetIdentifierPortugueseLockingSms7Bit;
+			}
+			break;
+		
+		case ESmsEncodingPortugueseLockingAndSingleShift:
+			{
+			aEncoderID = KCharacterSetIdentifierPortugueseLockingAndSingleSms7Bit;
+			}
+			break;
+
+		default:
+			{
+			//
+			// Invalid encoder method!
+			//
+			User::Leave(KErrArgument);
+			}
+		};
+	} // CSmsAlphabetConverter::GetAlternativeEncoderIDL
+
+
+//
+// Ensures the allocated 16 bit buffer is at least of the specified length
+//
+TPtr16 CSmsAlphabetConverter::CheckAllocBufferL(HBufC16** aBuffer,TInt aMaxLength,TInt aUsedLength)
+	{
+	LOGGSMU1("CSmsAlphabetConverter::CheckAllocBufferL()");
+
+	if (*aBuffer!=NULL)
+		{
+		if ((*aBuffer)->Length()<aMaxLength)
+			{
+			*aBuffer=(*aBuffer)->ReAllocL(aMaxLength);
+			(*aBuffer)->Des().SetLength(aMaxLength);
+			}
+		}
+	else
+		{
+		*aBuffer=HBufC16::NewMaxL(aMaxLength);
+		}
+	return TPtr16((TUint16*)(*aBuffer)->Des().Ptr(),aUsedLength,(*aBuffer)->Length());
+	} // CSmsAlphabetConverter::CheckAllocBufferL
+
+
+//
+// Ensures the allocated 8 bit buffer is at least of the specified length
+//
+TPtr8 CSmsAlphabetConverter::CheckAllocBufferL(HBufC8** aBuffer,TInt aMaxLength,TInt aUsedLength)
+	{
+	LOGGSMU1("CSmsAlphabetConverter::CheckAllocBufferL()");
+
+	if (*aBuffer!=NULL)
+		{
+		if ((*aBuffer)->Length()<aMaxLength)
+			{
+			*aBuffer=(*aBuffer)->ReAllocL(aMaxLength);
+			(*aBuffer)->Des().SetLength(aMaxLength);
+			}
+		}
+	else
+		{
+		*aBuffer=HBufC8::NewMaxL(aMaxLength);
+		}
+	return TPtr8((TUint8*)(*aBuffer)->Des().Ptr(),aUsedLength,(*aBuffer)->Length());
+	} // CSmsAlphabetConverter::CheckAllocBufferL
+
+
+/**
+ *  @internalComponent
+ *  
+ *  Determines whether the address format matches the specified type.
+ *  
+ *  @param aType Specifies an indicator type, as defined in the Common PCN Handset Specification
+ *  @return returns ETrue if address is of specified type, EFalse otherwise 
+ */
+EXPORT_C TBool TGsmSmsTelNumber::IsInstanceOf(TTypeOfIndicator aType)
+    {
+    LOGGSMU1("TGsmSmsTelNumber::IsInstanceOf()");
+
+    TBool rc = EFalse;
+
+    (void) aType;
+
+    if((aType == EVoiceMessageWaitingIndicator)
+     && ((iTypeOfAddress & TGsmSmsTypeOfAddress::EGsmSmsTONMask)==EGsmSmsTONAlphaNumeric)
+     && (iTelNumber.Length()==ECPHSSizeOfAddressField)
+     && ((iTelNumber[ECPHSAddressIndicatorType] & ECPSHIndicatorTypeBitMask) == ECPSHVoiceMailId)
+     && ((iTelNumber[ECPHSAddressIndicatorId] & ECPSHIndicatorIdBitMask) == ECPSHIndicatorId ))
+      rc = ETrue;
+
+    return rc;
+    } // TGsmSmsTelNumber::IsInstanceOf
+
+
+//
+// CSmsAddress
+//
+
+CSmsAddress* CSmsAddress::NewL(CCnvCharacterSetConverter& aCharacterSetConverter,RFs& aFs)
+	{
+	LOGGSMU1("CSmsAddress::NewL()");
+
+	CSmsAddress* address=new(ELeave) CSmsAddress(aCharacterSetConverter,aFs);
+	CleanupStack::PushL(address);
+	TPtrC ptr;
+	address->SetAddressL(ptr);
+	CleanupStack::Pop();
+	return address;
+	} // CSmsAddress::NewL
+
+
+CSmsAddress::~CSmsAddress()
+    {
+    delete iBuffer;
+    } // CSmsAddress::NewL
+
+
+/**
+ *  Duplicates this CSmsAddress object.
+ * 
+ *  @return  Pointer to the newly created CSmsAddress object.
+ */
+CSmsAddress* CSmsAddress::DuplicateL() const
+	{
+	LOGGSMU1("CSmsAddress::DuplicateL()");
+
+	CSmsAddress*  address = CSmsAddress::NewL(iCharacterSetConverter, iFs);
+	CleanupStack::PushL(address);
+
+	address->SetRawAddressL(iTypeOfAddress, *iBuffer);
+	
+	CleanupStack::Pop();
+
+	return address;
+	} // CSmsAddress::DuplicateL
+
+
+TPtrC CSmsAddress::Address() const
+	{
+	LOGGSMU1("CSmsAddress::Address()");
+
+	TPtrC ptr;
+	if (iBuffer)
+		ptr.Set(iBuffer->Des());
+	return ptr;
+	} // CSmsAddress::Address
+
+
+void CSmsAddress::SetRawAddressL(TGsmSmsTypeOfAddress aTypeOfAddress, TPtrC aBufferPtr)
+    {
+    LOGGSMU1("CSmsAddress::SetRawAddressL()");
+
+    iTypeOfAddress = aTypeOfAddress;
+
+    NewBufferL(aBufferPtr.Length());
+
+	*iBuffer=aBufferPtr;
+    } // CSmsAddress::SetRawAddressL
+
+
+TGsmSmsTypeOfAddress& CSmsAddress::TypeOfAddress()
+    {
+    LOGGSMU1("CSmsAddress::TypeOfAddress()");
+
+    return iTypeOfAddress;
+    } // CSmsAddress::TypeOfAddress
+
+
+void CSmsAddress::SetAddressL(const TDesC& aAddress)
+	{
+	LOGGSMU1("CSmsAddress::SetAddressL()");
+
+	TInt length=aAddress.Length();
+	NewBufferL(length);
+	iBuffer->Des().Copy(aAddress);
+
+	const TGsmSmsTypeOfNumber typeofnumber=length && (iBuffer->Des()[0]=='+')? EGsmSmsTONInternationalNumber: EGsmSmsTONUnknown;
+	iTypeOfAddress.SetTON(typeofnumber);
+	} // CSmsAddress::SetAddressL
+
+
+void CSmsAddress::ParsedAddress(TGsmSmsTelNumber& aParsedAddress) const
+	{
+	aParsedAddress.iTypeOfAddress = iTypeOfAddress;
+
+	TInt maxparsedlength=aParsedAddress.iTelNumber.MaxLength();
+
+	if (iTypeOfAddress.TON()==EGsmSmsTONAlphaNumeric)
+		{
+		TInt parsedlength=Address().Length();
+		if (parsedlength>maxparsedlength)
+			parsedlength=maxparsedlength;
+		aParsedAddress.iTelNumber.Copy(Address().Mid(0,parsedlength));
+		}
+	else
+		{
+		aParsedAddress.iTelNumber.SetLength(maxparsedlength);
+
+		TInt length=iBuffer->Des().Length();
+		TInt parsedlength=0;
+		for (TInt i=0; (i<length) && (parsedlength<maxparsedlength); i++)
+			{
+			TText ch=iBuffer->Des()[i];
+            switch(ch)
+                {
+                case '*':
+                case '#':
+                case 'a':
+                case 'b':
+                case 'c':
+                    aParsedAddress.iTelNumber[parsedlength]=(TUint8) ch;
+                    parsedlength++;
+                    break;                    
+                default:
+                    if ((ch>='0') && (ch<='9'))
+                        {
+                        aParsedAddress.iTelNumber[parsedlength]=(TUint8) ch;
+                        parsedlength++;
+                        }
+                    break;
+                }			
+			}
+
+		aParsedAddress.iTelNumber.SetLength(parsedlength);
+		}
+	}
+
+
+void CSmsAddress::SetParsedAddressL(const TGsmSmsTelNumber& aParsedAddress)
+	{
+	LOGGSMU1("CSmsAddress::SetParsedAddressL()");
+
+	iTypeOfAddress=aParsedAddress.iTypeOfAddress;
+	DoSetParsedAddressL(aParsedAddress.iTelNumber);
+	} // CSmsAddress::SetParsedAddressL
+
+
+TUint8 CSmsAddress::SizeL()
+    {
+    LOGGSMU1("CSmsAddress::SizeL()");
+
+    TUint8 size = 0;
+
+    TBuf8<KSmsAddressMaxAddressLength> testBuffer;
+    testBuffer.SetLength(KSmsAddressMaxAddressLength);
+    TUint8* startPtr = &testBuffer[0];
+    TUint8* endPtr = NULL;
+
+    TRAPD(err,endPtr = EncodeL(startPtr));
+
+    if (err != KErrNone)
+        {
+        User::Leave(KErrArgument);
+        }
+    else
+        {
+        // handle architectures whose address space increments or whose address space decrements.
+        (endPtr > startPtr) ? (size = endPtr - startPtr) : (size = startPtr - endPtr);
+        }
+
+	return size;
+    } // CSmsAddress::SizeL
+
+
+TUint8* CSmsAddress::EncodeL(TUint8* aPtr) const
+	{
+	TGsmSmsTelNumber parsedaddress;
+	ParsedAddress(parsedaddress);
+
+	switch (iTypeOfAddress.TON())
+		{
+		case EGsmSmsTONAlphaNumeric:
+			{
+			// Mark buffer for length encoding after conversion
+			TUint8* lengthPtr=aPtr++;
+			// Encode type
+			aPtr=iTypeOfAddress.EncodeL(aPtr);
+			// 7-bit conversion
+			TPtrC address=Address();
+			TInt convertedNumUDUnits=0;
+			TPtr8 packedPtr(aPtr,0,KSmsAddressMaxAddressValueLength);
+			TSmsAlphabetPacker packer(TSmsDataCodingScheme::ESmsAlphabet7Bit,EFalse,0);
+			aPtr+=packer.ConvertAndPackL(iCharacterSetConverter,iFs,packedPtr,address,convertedNumUDUnits);
+			// Now encode length
+			TSmsOctet length=(convertedNumUDUnits*7+3)/4;
+			length.EncodeL(lengthPtr);
+			break;
+			}
+		case EGsmSmsTONInternationalNumber:
+		default:
+			{
+			TSmsOctet length=parsedaddress.iTelNumber.Length();
+			if (length > KSmsAddressMaxAddressValueLength * 2)
+			// each address value occupies one nibble.
+                {
+                User::Leave(KErrArgument);
+                }
+			aPtr=length.EncodeL(aPtr);
+			aPtr=iTypeOfAddress.EncodeL(aPtr);
+			TSmsOctet octet;
+			for (TInt i=0; i<length; i++)
+				{
+                if ((i%2)==0)  //  even
+                    {
+                    switch(parsedaddress.iTelNumber[i])
+                        {
+                        case '*':
+                            {
+                            octet=10; // 1010 as a binary, according to 23.040 …
+                            }
+                            break;
+
+                        case '#':
+                            {
+                            octet=11; // 1011 as a binary, according to 23.040…
+                            }
+                            break; 
+
+                        case 'a':
+                            {
+                            octet=12; // 1100 as a binary, according to 23.040...
+                            }
+                            break;
+
+                        case 'b':
+                            {
+                            octet=13; // 1101 as a binary, according to 23.040…
+                            }
+                            break;
+
+                        case 'c':
+                            {
+                            octet=14; // 1110 as a binary, according to 23.040…
+                            }
+                            break;
+
+                        default:
+                            octet=(parsedaddress.iTelNumber[i])-'0';
+                            break;
+                        }
+                    } 
+                else
+                    {
+                    TInt tempOctet = 0;
+       
+                    switch(parsedaddress.iTelNumber[i])
+                        {
+                        case '*':
+                            {
+                            tempOctet=10; // 1010 as a binary, according to 23.040…
+                            }
+                            break;
+
+                        case '#':
+                            {
+                            tempOctet=11; // 1011 as a binary, according to 23.040…
+                            }
+                            break;
+
+                        case 'a':
+                            {
+                            tempOctet=12; // 1100 as a binary, according to 23.040…
+                            }
+                            break;
+
+                        case 'b':
+                            {
+                            tempOctet=13; // 1101 as a binary, according to 23.040…
+                            }
+                            break;
+
+                        case 'c':
+                            {
+                            tempOctet=14; // 1110 as a binary, according to 23.040…
+                            }
+                            break;
+
+                        default:
+                            tempOctet=(parsedaddress.iTelNumber[i])-'0';
+                            break;
+                        }
+                    octet=octet|tempOctet<<4;
+                    aPtr=octet.EncodeL(aPtr);				
+				    }
+                
+			    } // end for loop
+
+			if (length%2)   // odd number of semioctets
+				{
+				octet=octet|0xF0;
+				aPtr=octet.EncodeL(aPtr);
+				}
+						
+		    } // end default case
+	    }
+	return aPtr;
+	}
+
+
+void CSmsAddress::DecodeL(TGsmuLex8& aPdu)
+	{
+	TSmsOctet length;  //represents the number of valid semi-octets
+	length.DecodeL(aPdu);
+	iTypeOfAddress.DecodeL(aPdu);
+
+	switch (iTypeOfAddress.TON())
+		{
+		case EGsmSmsTONAlphaNumeric:
+			{
+			const TUint cphs1 = aPdu.GetL();
+			const TUint cphs2 = aPdu.GetL();
+			aPdu.UnGet();
+			aPdu.UnGet();
+
+			const TPtrC8 remainder(aPdu.Remainder());
+			// we assume that it is a cphs message waiting indicator
+            // we might want to do further tests tobe sure that it is a CPHS message
+			if(    (length==4)
+				&& ((cphs1 & 0x7E) == 0x10) // x001 000x constant value
+				&& ((cphs2 & 0x7E) == 0x00) // x000 000x constant value
+			  )
+				{
+				TGsmSmsTelNumber parsedaddress;
+				parsedaddress.iTelNumber.SetLength(length);
+				//Copy the two bytes of the cphs message waiting address into the parsed address
+				parsedaddress.iTelNumber[0]=(TUint8)length;
+				parsedaddress.iTelNumber[1]= (TUint8)iTypeOfAddress;
+				parsedaddress.iTelNumber[2]= (TUint8)aPdu.GetL();
+				parsedaddress.iTelNumber[3]= (TUint8)aPdu.GetL();
+				DoSetParsedAddressL(parsedaddress.iTelNumber);
+				}
+			else if(length==11 && remainder.Left(6).CompareF(KMOSES) ==KErrNone ) //check for MOSES
+				{
+					DoSetParsedAddressL(KNETWORK);
+					aPdu.IncL(6);
+				}
+			else
+				{
+				// Encoded length is number of semi-octets used to store address using
+				// 7-bit char set - determine number of user data units required
+				const TInt numUDUnits=length*4/7;
+				// Unpack the data - assume max converted length twice the unconverted length
+				// VEP Why this assumption, the length will be doubled at the client because of that??
+				// EXT-568BMW
+				// Fix is not to multiply by 2
+				//NewBufferL(2*numUDUnits);
+				NewBufferL(numUDUnits);
+				TPtr unpackedPtr((TText*)iBuffer->Des().Ptr(),0,iBuffer->Length());
+
+				if (remainder.Length() < KSmsAddressMaxAddressValueLength)
+					User::Leave(KErrGsmuDecoding);
+
+				TPtrC8 packedPtr(remainder.Ptr(), KSmsAddressMaxAddressValueLength);
+				TSmsAlphabetPacker unpacker(TSmsDataCodingScheme::ESmsAlphabet7Bit,EFalse,0);
+				unpacker.UnpackAndConvertL(iCharacterSetConverter,iFs,packedPtr,unpackedPtr,numUDUnits);
+				aPdu.IncL(length / 2);
+				if ((length % 2) != 0)
+					aPdu.IncL();
+				}
+			break;
+			}
+		case EGsmSmsTONInternationalNumber:
+		default:
+			{
+			TGsmSmsTelNumber parsedaddress;
+			if (length>parsedaddress.iTelNumber.MaxLength())
+				User::Leave(KErrGsmuDecoding);
+			parsedaddress.iTelNumber.SetLength(length);
+			TSmsOctet octet;
+			for (TInt i=0; i<length; i++)
+				{
+				if ((i%2)==0)  //  even
+					{
+                    TUint8 tempOctet = 0;
+                    octet.DecodeL(aPdu);
+                    tempOctet = (TUint8)octet&0x0F; // four topmost bits set to zero
+                    
+                    switch(tempOctet)
+                        {
+                        case 10: // 1010
+                            {
+                            parsedaddress.iTelNumber[i] = '*';
+                            }
+                            break;
+
+                        case 11: // 1011
+                            {
+                            parsedaddress.iTelNumber[i] = '#';
+                            }
+                            break; 
+
+                        case 12: // 1100
+                            {
+                            parsedaddress.iTelNumber[i] = 'a';
+                            }
+                            break;
+
+                        case 13: //1101
+                            {
+                            parsedaddress.iTelNumber[i] = 'b'; 
+                            }
+                            break;
+
+                        case 14: //1110
+                            {
+                            parsedaddress.iTelNumber[i] = 'c';
+                            }
+                            break;
+
+                        case 15: 
+                            // Skip if 1111 is received 
+                            break;
+
+                        default:
+                            parsedaddress.iTelNumber[i]=(TUint8) (tempOctet+'0');
+                            break;
+                        }
+					}
+				else
+                    {
+                    TUint8 tempOctet = 0;
+                    octet&0xF0; // four least significant bits…
+                    tempOctet = (TUint8)octet>>4;
+
+                    switch(tempOctet)
+                        {
+                        case 10: // 1010
+                            {
+                            parsedaddress.iTelNumber[i] = '*';
+                            }
+                            break;
+
+                        case 11: // 1011
+                            {
+                            parsedaddress.iTelNumber[i] = '#';
+                            }
+                            break;
+
+                        case 12: // 1100
+                            {
+                            parsedaddress.iTelNumber[i] = 'a';
+                            }
+                            break;
+
+                        case 13: // 1101
+                            {
+                            parsedaddress.iTelNumber[i] = 'b';
+                            }
+                            break;
+
+                        case 14: // 1110
+                            {
+                            parsedaddress.iTelNumber[i] = 'c';
+                            }
+                            break;
+
+                        case 15: 
+                            // Skip if 1111 is received 
+                            break;
+
+                        default:
+                            parsedaddress.iTelNumber[i]=(TUint8) (tempOctet+'0'); 
+                            // unwanted bits zeroed in the beginning
+       
+                            break;
+                        }
+                    }
+				}
+			DoSetParsedAddressL(parsedaddress.iTelNumber);
+			}
+		}
+	}
+
+void CSmsAddress::InternalizeL(RReadStream& aStream)
+	{
+	aStream >> iTypeOfAddress;
+	HBufC* buffer=HBufC::NewL(aStream,256);
+	delete iBuffer;
+	iBuffer=buffer;
+	} // CSmsAddress::InternalizeL
+
+
+void CSmsAddress::ExternalizeL(RWriteStream& aStream) const
+	{
+	aStream << iTypeOfAddress;
+	aStream << *iBuffer;
+	} // CSmsAddress::ExternalizeL
+
+
+CSmsAddress::CSmsAddress(CCnvCharacterSetConverter& aCharacterSetConverter,RFs& aFs):
+	iCharacterSetConverter(aCharacterSetConverter),
+	iFs(aFs),
+	iTypeOfAddress(EGsmSmsTONUnknown, EGsmSmsNPIISDNTelephoneNumberingPlan)
+	{
+	} // CSmsAddress::CSmsAddress
+
+
+void CSmsAddress::NewBufferL(TInt aLength)
+	{
+	LOGGSMU1("CSmsAddress::NewBufferL()");
+
+    HBufC* buffer=HBufC::NewL(aLength);
+    delete iBuffer;
+    iBuffer=buffer;
+    iBuffer->Des().SetLength(aLength);
+    iBuffer->Des().FillZ();
+	}
+
+
+void CSmsAddress::DoSetParsedAddressL(const TDesC& aAddress)
+	{
+	LOGGSMU2("CSmsAddress::DoSetParsedAddressL() the length of the Address [Length = %d", aAddress.Length());
+
+	TInt length=aAddress.Length();
+	if ((iTypeOfAddress.TON()==EGsmSmsTONInternationalNumber) &&
+	    (length && (aAddress[0]!='+')))
+		{
+		NewBufferL(length+1);
+		iBuffer->Des()[0]='+';
+		TPtr ptr((TText*) (iBuffer->Des().Ptr()+1),length,length);
+		ptr.Copy(aAddress);
+		}
+	else
+		{
+		NewBufferL(length);
+		iBuffer->Des().Copy(aAddress);
+		}
+	} // CSmsAddress::DoSetParsedAddressL
+
+
+TSmsServiceCenterTimeStamp::TSmsServiceCenterTimeStamp()
+	{
+	iTimeZoneNumQuarterHours = 0;
+	} // TSmsServiceCenterTimeStamp::TSmsServiceCenterTimeStamp
+
+
+void TSmsServiceCenterTimeStamp::SetTimeOffset(TInt aNumQuarterHours)
+	{
+	__ASSERT_DEBUG((aNumQuarterHours>=-KSmsMaxTimeZoneNumQuarterHours) && (aNumQuarterHours<=KSmsMaxTimeZoneNumQuarterHours),Panic(KGsmuPanicNumQuarterHoursOutOfRange));
+	iTimeZoneNumQuarterHours=aNumQuarterHours;
+	} // TSmsServiceCenterTimeStamp::SetTimeOffset
+
+
+TUint8* TSmsServiceCenterTimeStamp::EncodeL(TUint8* aPtr) const
+    {
+    LOGGSMU1("TSmsServiceCenterTimeStamp::EncodeL()");
+
+    TInt numquarterhours=iTimeZoneNumQuarterHours;
+
+    TInt timeZoneOffsetInSeconds = numquarterhours * CSmsMessage::E15MinutesRepresentedInSeconds;
+    TTimeIntervalSeconds offsetFromUTCToLocal(timeZoneOffsetInSeconds);
+
+    TTime time = iTime;
+    time += offsetFromUTCToLocal;
+
+    TDateTime datetime=time.DateTime();
+
+    TSmsOctet octet;
+    octet.FillSemiOctets(datetime.Year()%100);
+    aPtr=octet.EncodeL(aPtr);
+    octet.FillSemiOctets(datetime.Month()+1);
+    aPtr=octet.EncodeL(aPtr);
+    octet.FillSemiOctets(datetime.Day()+1);
+    aPtr=octet.EncodeL(aPtr);
+    octet.FillSemiOctets(datetime.Hour());
+    aPtr=octet.EncodeL(aPtr);
+    octet.FillSemiOctets(datetime.Minute());
+    aPtr=octet.EncodeL(aPtr);
+    octet.FillSemiOctets(datetime.Second());
+    aPtr=octet.EncodeL(aPtr);
+
+    TInt signbit=ESmsTimeZonePositive;
+    if (numquarterhours<0)
+        {
+        numquarterhours=-numquarterhours;
+        signbit=ESmsTimeZoneNegative;
+        }
+
+    TSmsOctet timezone;
+    timezone.FillSemiOctets(numquarterhours);
+    timezone=timezone|signbit;
+    return timezone.EncodeL(aPtr);
+    } // TSmsServiceCenterTimeStamp::EncodeL
+
+
+void TSmsServiceCenterTimeStamp::DecodeL(TGsmuLex8& aPdu, TInt& aTimeError)
+	{
+	LOGGSMU1("TSmsServiceCenterTimeStamp::DecodeL()");
+
+	TSmsOctet octet;
+	octet.DecodeL(aPdu);
+	TInt year=octet.SemiOctetsToNum();
+	if (year>95)
+		year+=1900;
+	else
+		year+=2000;
+	octet.DecodeL(aPdu);
+	TInt month=octet.SemiOctetsToNum();
+	octet.DecodeL(aPdu);
+
+	TInt day=octet.SemiOctetsToNum();
+	octet.DecodeL(aPdu);
+	TInt hour=octet.SemiOctetsToNum();
+	octet.DecodeL(aPdu);
+	TInt minute=octet.SemiOctetsToNum();
+	octet.DecodeL(aPdu);
+	TInt second=octet.SemiOctetsToNum();
+
+    TDateTime datetime;
+    aTimeError = datetime.Set(year,(TMonth) (month-1),day-1,hour,minute,second,0);
+
+    TSmsOctet timezone;
+    timezone.DecodeL(aPdu);
+
+    TInt signBit = (timezone&ESmsTimeZoneSignBitMask) ?  ESmsTimeZoneNegative : ESmsTimeZonePositive;
+    timezone=timezone &(~ESmsTimeZoneSignBitMask); // clear sign bit
+
+    TInt offsetToUTCInSeconds = 0;
+    if (timezone.SemiOctetsToNum() <= KSmsMaxTimeZoneNumQuarterHours)
+        {
+        offsetToUTCInSeconds = ((TInt) timezone.SemiOctetsToNum()) * CSmsMessage::E15MinutesRepresentedInSeconds;
+        if (signBit == ESmsTimeZoneNegative)    
+            {
+            offsetToUTCInSeconds = -offsetToUTCInSeconds;
+            }
+
+        TTimeIntervalSeconds offsetToUTC(offsetToUTCInSeconds) ;      
+
+        if (aTimeError == KErrNone)
+            {
+            TTime time = datetime;    	
+            time -= offsetToUTC;
+            iTime = time;
+    	
+            iTimeZoneNumQuarterHours=(signBit == ESmsTimeZonePositive) ? timezone.SemiOctetsToNum(): -timezone.SemiOctetsToNum();
+            }
+            
+        }
+    else // Time zone out of range, set to 0 per 23.040 4.4.0 Section 9.2.3.11
+        {
+    	if (aTimeError == KErrNone)
+            {    		
+            iTime = datetime;    	
+    	    iTimeZoneNumQuarterHours=0;
+    	    }            
+        }
+	} // TSmsServiceCenterTimeStamp::DecodeL
+
+
+void TSmsServiceCenterTimeStamp::InternalizeL(RReadStream& aStream)
+	{
+	TInt64 time;
+	aStream >> time;
+	iTime=time;
+	iTimeZoneNumQuarterHours=aStream.ReadInt32L();
+	} // TSmsServiceCenterTimeStamp::InternalizeL
+
+
+void TSmsServiceCenterTimeStamp::ExternalizeL(RWriteStream& aStream) const
+	{
+	aStream << iTime.Int64();
+	aStream.WriteInt32L(iTimeZoneNumQuarterHours);
+	} // TSmsServiceCenterTimeStamp::ExternalizeL
+
+
+TSmsValidityPeriod::TSmsValidityPeriod(TSmsFirstOctet& aFirstOctet):
+	iFirstOctet(aFirstOctet),
+	iTimeIntervalMinutes(EOneDayUnitInMinutes)
+	{
+	} // TSmsValidityPeriod::TSmsValidityPeriod
+
+
+TTime TSmsValidityPeriod::Time() const
+	{
+	LOGGSMU1("TSmsValidityPeriod::Time()");
+
+	TTime time;
+	time.UniversalTime();
+	time+=iTimeIntervalMinutes;
+	return time;
+	} // TSmsValidityPeriod::Time
+
+
+TUint8* TSmsValidityPeriod::EncodeL(TUint8* aPtr) const
+	{
+	LOGGSMU1("TSmsValidityPeriod::EncodeL()");
+
+	TInt validityperiodformat=ValidityPeriodFormat();
+	switch (validityperiodformat)
+		{
+		case (TSmsFirstOctet::ESmsVPFNone):
+			break;
+		case (TSmsFirstOctet::ESmsVPFInteger):
+			{
+			TInt timeintervalminutes=iTimeIntervalMinutes.Int();
+			__ASSERT_DEBUG((timeintervalminutes>=EFiveMinuteUnitInMinutes) && (timeintervalminutes<=63*EOneWeekUnitLimitInMinutes),Panic(KGsmuPanicValidityPeriodOutOfRange));
+			TSmsOctet octet;
+			if (timeintervalminutes<=EFiveMinuteUnitLimitInMinutes)
+                octet=((timeintervalminutes/EFiveMinuteUnitInMinutes)-1);
+			else if (timeintervalminutes<=EHalfHourUnitLimitInMinutes)
+                octet=(((timeintervalminutes-(EHalfHourUnitLimitInMinutes/2))/EHalfHourUnitInMinutes)+EFiveMinuteUnitLimit);
+
+			else if (timeintervalminutes<=EOneDayUnitLimitInMinutes)
+                octet=((timeintervalminutes/EOneDayUnitInMinutes)+166);
+			else
+                octet=((timeintervalminutes/EOneWeekUnitInMinutes)+192);
+
+			aPtr=octet.EncodeL(aPtr);
+			break;
+			}
+		case (TSmsFirstOctet::ESmsVPFSemiOctet):
+			{
+			TSmsServiceCenterTimeStamp timestamp;
+			timestamp.SetTime(Time());
+
+	 		TTimeIntervalSeconds timeIntervalInSeconds(User::UTCOffset());
+			timestamp.SetTimeOffset(timeIntervalInSeconds.Int() / CSmsMessage::E15MinutesRepresentedInSeconds);
+
+			aPtr=timestamp.EncodeL(aPtr);
+			break;
+			}
+		default:
+            __ASSERT_DEBUG(EFalse,Panic(KGsmuPanicUnsupportedValidityPeriodFormat));
+			User::Leave(KErrGsmSMSTPVPFNotSupported);
+            break;
+		};
+	return aPtr;
+	} // TSmsValidityPeriod::EncodeL
+	
+TUint8* TSmsValidityPeriod::EncodeL(TUint8* aPtr, const TEncodeParams* aEncodeParams) const
+	{
+	LOGGSMU1("TSmsValidityPeriod::EncodeL()");
+
+	TInt validityperiodformat=ValidityPeriodFormat();
+	switch (validityperiodformat)
+		{
+		case (TSmsFirstOctet::ESmsVPFNone):
+			break;
+		case (TSmsFirstOctet::ESmsVPFInteger):
+			{
+			TInt timeintervalminutes=iTimeIntervalMinutes.Int();
+			__ASSERT_DEBUG((timeintervalminutes>=EFiveMinuteUnitInMinutes) && (timeintervalminutes<=63*EOneWeekUnitLimitInMinutes),Panic(KGsmuPanicValidityPeriodOutOfRange));
+			TSmsOctet octet;
+			if (timeintervalminutes<=EFiveMinuteUnitLimitInMinutes)
+                octet=((timeintervalminutes/EFiveMinuteUnitInMinutes)-1);
+			else if (timeintervalminutes<=EHalfHourUnitLimitInMinutes)
+                octet=(((timeintervalminutes-(EHalfHourUnitLimitInMinutes/2))/EHalfHourUnitInMinutes)+EFiveMinuteUnitLimit);
+
+			else if (timeintervalminutes<=EOneDayUnitLimitInMinutes)
+                octet=((timeintervalminutes/EOneDayUnitInMinutes)+166);
+			else
+                octet=((timeintervalminutes/EOneWeekUnitInMinutes)+192);
+
+			aPtr=octet.EncodeL(aPtr);
+			break;
+			}
+		case (TSmsFirstOctet::ESmsVPFSemiOctet):
+			{			
+			//The reason TSmsValidityPeriod::EncodeL(TUint8* aPtr, const TEncodeParams* aEncodeParams) was
+			//created was to allow the CSmsMessage's time stamp to be used when generating the validity time.
+			//The CSmsMessage's time stamp is typically created when the message is constructed by the SMS Stack client.
+			//This means the validity time is based from the point the SMS Stack client actually sends the message, rather
+			//than the SMS Stack encodes it
+						
+			TSmsServiceCenterTimeStamp timestamp;
+			timestamp.SetTime( *aEncodeParams->iTimeStamp + iTimeIntervalMinutes ); 									    		    		    		    		    
+
+	 		TTimeIntervalSeconds timeIntervalInSeconds( *aEncodeParams->iTimeIntervalInSeconds );
+			timestamp.SetTimeOffset(timeIntervalInSeconds.Int() / CSmsMessage::E15MinutesRepresentedInSeconds);
+
+			aPtr=timestamp.EncodeL(aPtr);
+			break;
+			}
+		default:
+            __ASSERT_DEBUG(EFalse,Panic(KGsmuPanicUnsupportedValidityPeriodFormat));
+			User::Leave(KErrGsmSMSTPVPFNotSupported);
+            break;
+		};
+	return aPtr;
+	} // TSmsValidityPeriod::EncodeL	
+
+void TSmsValidityPeriod::DecodeL(TGsmuLex8& aPdu)
+	{
+	LOGGSMU1("TSmsValidityPeriod::DecodeL()");
+
+	TInt validityperiodformat=ValidityPeriodFormat();
+	switch (validityperiodformat)
+		{
+		case (TSmsFirstOctet::ESmsVPFNone):
+			break;
+		case (TSmsFirstOctet::ESmsVPFInteger):
+			{
+			TSmsOctet octet;
+			octet.DecodeL(aPdu);
+            if (octet<=EFiveMinuteUnitLimit)
+                iTimeIntervalMinutes=(octet+1)*EFiveMinuteUnitInMinutes;
+			else if (octet<=EHalfHourUnitLimit)
+                iTimeIntervalMinutes=((EOneDayUnitInMinutes/2)+((octet-EFiveMinuteUnitLimit)*EHalfHourUnitInMinutes));
+			else if (octet<=EOneDayUnitLimit)
+                iTimeIntervalMinutes=(octet-166)*EOneDayUnitInMinutes;
+			else
+                iTimeIntervalMinutes=(octet-192)*EOneWeekUnitInMinutes;
+			break;
+			}
+		case (TSmsFirstOctet::ESmsVPFSemiOctet):
+			{
+			TSmsServiceCenterTimeStamp timestamp;
+			TInt timeError;
+			timestamp.DecodeL(aPdu, timeError);
+			User::LeaveIfError(timeError);
+			TTime time;
+			time.UniversalTime();
+			timestamp.Time().MinutesFrom(time,iTimeIntervalMinutes);
+			break;
+			}
+		default:
+            __ASSERT_DEBUG(EFalse,Panic(KGsmuPanicUnsupportedValidityPeriodFormat));
+			User::Leave(KErrGsmSMSTPVPFNotSupported);
+            break;
+		};
+	} // TSmsValidityPeriod::DecodeL
+
+
+void TSmsValidityPeriod::InternalizeL(RReadStream& aStream)
+	{
+	TInt timeintervalinminutes=aStream.ReadInt32L();
+	iTimeIntervalMinutes=timeintervalinminutes;
+	} // TSmsValidityPeriod::InternalizeL
+
+
+void TSmsValidityPeriod::ExternalizeL(RWriteStream& aStream) const
+	{
+	aStream.WriteInt32L(iTimeIntervalMinutes.Int());
+	} // TSmsValidityPeriod::ExternalizeL
+
+
+CSmsInformationElement* CSmsInformationElement::NewL(TSmsInformationElementIdentifier aIdentifier,const TDesC8& aData)
+	{
+	LOGGSMU1("CSmsInformationElement::NewL()");
+
+	CSmsInformationElement* informationelement=new(ELeave) CSmsInformationElement(aIdentifier);
+	CleanupStack::PushL(informationelement);
+	informationelement->ConstructL(aData);
+	CleanupStack::Pop();
+	return informationelement;
+	} // CSmsInformationElement::NewL
+
+
+CSmsInformationElement* CSmsInformationElement::NewL()
+	{
+	LOGGSMU1("CSmsInformationElement::NewL()");
+
+	CSmsInformationElement* informationelement=new(ELeave) CSmsInformationElement(ESmsIEIConcatenatedShortMessages8BitReference);
+	CleanupStack::PushL(informationelement);
+	TPtrC8 data;
+	informationelement->ConstructL(data);
+	CleanupStack::Pop();
+	return informationelement;
+	} // CSmsInformationElement::NewL
+
+
+/**
+ *  Destructor.
+ */
+CSmsInformationElement::~CSmsInformationElement()
+	{
+	delete iData;
+	} // CSmsInformationElement::NewL
+
+
+/**
+ *  Gets the Information Element data.
+ *  
+ *  @return Information Element data
+ *  @capability None
+ */
+EXPORT_C TPtr8 CSmsInformationElement::Data()
+	{
+	LOGGSMU1("CSmsInformationElement::Data()");
+
+	return iData->Des();
+	} // CSmsInformationElement::Data
+
+
+/**
+ *  Gets the (const) Information Element data.
+ *  
+ *  @return Information Element data
+ *  @capability None
+ */
+EXPORT_C const TDesC8& CSmsInformationElement::Data() const
+	{
+	LOGGSMU1("CSmsInformationElement::Data()");
+
+	return *iData;
+	} // CSmsInformationElement::Data
+
+
+/**
+ *  Gets the Information Element Identifier.
+ *  
+ *  @return Information Element Identifier
+ *  @capability None
+ */
+EXPORT_C CSmsInformationElement::TSmsInformationElementIdentifier CSmsInformationElement::Identifier() const
+	{
+	return TSmsId(TInt(iIdentifier));
+	} // CSmsInformationElement::TSmsInformationElementIdentifier
+
+
+TUint8* CSmsInformationElement::EncodeL(TUint8* aPtr) const
+	{
+	LOGGSMU1("CSmsInformationElement::EncodeL()");
+
+	TSmsOctet id=iIdentifier;
+	aPtr=id.EncodeL(aPtr);
+	TSmsOctet informationelementlength=iData->Des().Length();
+	aPtr=informationelementlength.EncodeL(aPtr);
+	Mem::Copy(aPtr,iData->Des().Ptr(),informationelementlength);
+	aPtr+=TInt(informationelementlength);
+	return aPtr;
+	} // CSmsInformationElement::EncodeL
+
+
+void CSmsInformationElement::DecodeL(TGsmuLex8& aPdu)
+	{
+	LOGGSMU1("CSmsInformationElement::DecodeL()");
+
+	TSmsOctet id;
+	id.DecodeL(aPdu);
+	iIdentifier=static_cast<TSmsInformationElementIdentifier>((TInt)id);
+
+	TSmsOctet informationelementlength;
+	informationelementlength.DecodeL(aPdu);
+
+ 	switch(iIdentifier)
+ 	{
+ 	case (ESmsIEIConcatenatedShortMessages8BitReference):
+ 		if(informationelementlength !=3)
+ 			User::Leave(KErrGsmSMSTpduNotSupported);
+ 		break;
+ 	case (ESmsIEISpecialSMSMessageIndication):
+ 		if(informationelementlength !=2)
+ 			User::Leave(KErrGsmSMSTpduNotSupported);
+ 		break;
+ 	case (ESmsIEIApplicationPortAddressing8Bit):
+ 		if(informationelementlength !=2)
+ 			User::Leave(KErrGsmSMSTpduNotSupported);
+ 		break;
+ 	case (ESmsIEIApplicationPortAddressing16Bit):
+ 		if(informationelementlength !=4)
+ 			User::Leave(KErrGsmSMSTpduNotSupported);
+ 		break;
+ 	case (ESmsIEISMSCControlParameters):
+ 		if(informationelementlength !=1)
+ 			User::Leave(KErrGsmSMSTpduNotSupported);
+ 		break;
+ 	case (ESmsIEIUDHSourceIndicator):
+ 		if(informationelementlength !=1)
+ 			User::Leave(KErrGsmSMSTpduNotSupported);
+ 		break;
+ 	case (ESmsIEIConcatenatedShortMessages16BitReference):
+ 		if(informationelementlength !=4)
+ 			User::Leave(KErrGsmSMSTpduNotSupported);
+ 		break;
+ 	case (ESmsIEIRFC822EmailHeader):
+ 		if(informationelementlength !=1)
+ 			User::Leave(KErrGsmSMSTpduNotSupported);
+ 		break;
+  	case (ESmsHyperLinkFormat):
+ 		if(informationelementlength !=4)
+ 			User::Leave(KErrGsmSMSTpduNotSupported);
+ 		break;
+  	case (ESmsNationalLanguageSingleShift):
+ 		if(informationelementlength != 1)
+ 			User::Leave(KErrGsmSMSTpduNotSupported);
+ 		break;
+  	case (ESmsNationalLanguageLockingShift):
+ 		if(informationelementlength != 1)
+ 			User::Leave(KErrGsmSMSTpduNotSupported);
+ 		break;
+ 	case (ESmsIEISIMToolkitSecurityHeaders1):
+ 	case (ESmsIEISIMToolkitSecurityHeaders2):
+ 	case (ESmsIEISIMToolkitSecurityHeaders3):
+ 	case (ESmsIEISIMToolkitSecurityHeaders4):
+ 	case (ESmsIEISIMToolkitSecurityHeaders5):
+ 	case (ESmsIEISIMToolkitSecurityHeaders6):
+ 	case (ESmsIEISIMToolkitSecurityHeaders7):
+ 	case (ESmsIEISIMToolkitSecurityHeaders8):
+ 	case (ESmsIEISIMToolkitSecurityHeaders9):
+ 	case (ESmsIEISIMToolkitSecurityHeaders10):
+ 	case (ESmsIEISIMToolkitSecurityHeaders11):
+ 	case (ESmsIEISIMToolkitSecurityHeaders12):
+ 	case (ESmsIEISIMToolkitSecurityHeaders13):
+ 	case (ESmsIEISIMToolkitSecurityHeaders14):
+ 	case (ESmsIEISIMToolkitSecurityHeaders15):
+ 	case (ESmsIEISIMToolkitSecurityHeaders16):
+ 	if(informationelementlength !=0)
+ 			User::Leave(KErrGsmSMSTpduNotSupported);
+ 		break;
+ 	default:
+ 		break;
+ 	}
+
+	const TPtrC8 data(aPdu.NextAndIncL(informationelementlength));
+	NewDataL(informationelementlength);
+	TPtr8 ptr(iData->Des());
+	ptr.Copy(data);
+	} // CSmsInformationElement::DecodeL
+
+
+void CSmsInformationElement::InternalizeL(RReadStream& aStream)
+	{
+	TSmsOctet id;
+	aStream >> id;
+	iIdentifier=static_cast<TSmsInformationElementIdentifier>((TInt)id);
+	delete iData;
+	iData=NULL;
+	iData=HBufC8::NewL(aStream,CSmsUserData::KSmsMaxUserDataSize);
+	} // CSmsInformationElement::InternalizeL
+
+
+void CSmsInformationElement::ExternalizeL(RWriteStream& aStream) const
+	{
+	TSmsOctet id;
+	id=(TInt)iIdentifier;
+	aStream << id;
+	aStream << *iData;
+	} // CSmsInformationElement::ExternalizeL
+
+
+void CSmsInformationElement::ConstructL(const TDesC8& aData)
+	{
+	LOGGSMU1("CSmsInformationElement::ConstructL()");
+
+	NewDataL(aData.Length());
+	iData->Des().Copy(aData);
+	} // CSmsInformationElement::ConstructL
+
+
+void CSmsInformationElement::NewDataL(TInt aLength)
+	{
+	LOGGSMU1("CSmsInformationElement::NewDataL()");
+
+	HBufC8* data=HBufC8::NewL(aLength);
+	delete iData;
+	iData=data;
+	iData->Des().SetLength(aLength);
+	} // CSmsInformationElement::NewDataL
+
+
+TUint CSmsInformationElement::Length()const
+	{
+	LOGGSMU1("CSmsInformationElement::Length()");
+
+	return 2+iData->Length();  // 2 stands for IEID and IEDL
+	} // CSmsInformationElement::Length
+
+
+/**
+ *  @internalComponent
+ *  
+ *  This method maps an information element to an index into an array of categories.
+ *  
+ *  @param aId
+ *  The information Element Identifier.
+ *  @param aIndex
+ *  The index into the array of categories
+ *  @return
+ *  True if the information element can be mapped.
+ *  False otherwise.
+ */
+TBool TSmsInformationElementCategories::TranslateCategoryToIndex(TInformationElementId aId, TInt& aIndex)
+    {
+    LOGGSMU1("CSmsMessage::TranslateCategoryToIndex");
+
+    TBool rc = ETrue;
+
+    if (aId < CSmsInformationElement::ESmsIEMaximum)
+        {
+        switch (aId)
+            {
+            case CSmsInformationElement::ESmsIEIConcatenatedShortMessages8BitReference:
+            case CSmsInformationElement::ESmsIEIConcatenatedShortMessages16BitReference:
+            case CSmsInformationElement::ESmsIEISMSCControlParameters:
+            case CSmsInformationElement::ESmsIEIRFC822EmailHeader:
+                {
+                aIndex = EIndexCtrlMandatoryInEveryPDUButWithValueSpecificToPDU;
+                break;
+                }
+            case CSmsInformationElement::ESmsIEISpecialSMSMessageIndication:
+                {
+                aIndex = EIndexCtrlMandatoryInEveryPDUMultipleInstancesPerPDU;
+                break;
+                }
+            case CSmsInformationElement::ESmsHyperLinkFormat:
+                {
+                aIndex = EIndexCtrlMultipleInstancesAllowed;
+                break;
+                }
+            case CSmsInformationElement::ESmsNationalLanguageSingleShift:
+            case CSmsInformationElement::ESmsNationalLanguageLockingShift:
+                {
+                aIndex = EIndexCtrlOptionalInEveryPDUWithValueSpecificToPDU;
+                break;
+                }
+            case CSmsInformationElement::ESmsReplyAddressFormat:
+                {
+                aIndex = EIndexCtrlMandatoryIn1stPDUOnly;
+                break;
+                }
+            case CSmsInformationElement::ESmsEnhanceVoiceMailInformation:
+                {
+                aIndex = EIndexCtrlSingleInstanceOnly;
+                break;
+                }
+            case CSmsInformationElement::ESmsEnhancedTextFormatting:
+            case CSmsInformationElement::ESmsEnhancedPredefinedSound:
+            case CSmsInformationElement::ESmsEnhancedUserDefinedSound:
+            case CSmsInformationElement::ESmsEnhancedPredefinedAnimation:
+            case CSmsInformationElement::ESmsEnhancedLargeAnimation:
+            case CSmsInformationElement::ESmsEnhancedSmallAnimation:
+            case CSmsInformationElement::ESmsEnhancedLargePicture:
+            case CSmsInformationElement::ESmsEnhancedSmallPicture:
+            case CSmsInformationElement::ESmsEnhancedVariablePicture:
+            case CSmsInformationElement::ESmsEnhancedUserPromptIndicator:
+            case CSmsInformationElement::ESmsEnhancedExtendedObject:
+            case CSmsInformationElement::ESmsEnhancedReusedExtendedObject:
+            case CSmsInformationElement::ESmsEnhancedCompressionControl:
+            case CSmsInformationElement::ESmsEnhancedODI:
+            case CSmsInformationElement::ESmsEnhancedStandardWVG:
+            case CSmsInformationElement::ESmsEnhancedCharacterSizeWVG:
+            case CSmsInformationElement::ESmsEnhancedextendedObjectDataRequest:
+                {
+                aIndex = EIndexEmsInformationElement;
+                break;
+                }
+            case CSmsInformationElement::ESmsIEIReserved:
+            case CSmsInformationElement::ESmsIEIValueNotUsed:
+                {
+                rc = EFalse;
+                break;
+                }
+            default:
+                {
+                aIndex = EIndexCtrlMandatoryInEveryPDUAndWithIdenticalValues;
+                break;
+                }
+            }
+        }
+    else
+        {
+        rc = EFalse;
+        LOGGSMU3("CSmsMessage::TranslateCategoryToIndex id = %d, found = %d", aId, rc);
+        }
+    return rc;
+    } // TSmsInformationElementCategories::TranslateCategoryToIndex
+
+
+/**
+ *  @internalComponent
+ *  
+ *  This method gets an information element identifier's category.
+ *  
+ *  @param aId
+ *  The information Element Identifier.
+ *  @param aCategory
+ *  The category of information element.
+ *  @return
+ *  ETrue if successful, EFalse if an information identifier is unknown or cannot
+ *  be mapped.
+ */
+TBool TSmsInformationElementCategories::GetCategoryDefinition(TInformationElementId aId, TInformationElementCategory& aCategory)
+    {
+    LOGGSMU1("TSmsInformationElementCategories::GetCategoryDefinition");
+    TInt index;
+
+    if (TranslateCategoryToIndex(aId,index))
+        {
+        aCategory = categories[index];
+        }
+    else
+        {
+        LOGGSMU2("TSmsInformationElementCategories::GetCategoryDefinition, Failure, aId = %d", aId);
+        return EFalse;
+        }
+
+    return ETrue;
+    } // TSmsInformationElementCategories::GetCategoryDefinition
+
+
+const TSmsInformationElementCategories::TInformationElementCategory TSmsInformationElementCategories::categories[TSmsInformationElementCategories::ENumberOfIndices] =
+    {
+    TSmsInformationElementCategories::EEmsInformationElement,                           // EDefaultEMSIndex
+    TSmsInformationElementCategories::ECtrlMandatoryInEveryPDUAndWithIdenticalValues,   // EDefaultControlIndex
+    TSmsInformationElementCategories::ECtrlMandatoryInEveryPDUMultipleInstancesPerPDU,  // EIndexForSpecialSMSMessageIndication, Concatenated Short Messages
+    TSmsInformationElementCategories::ECtrlMandatoryInEveryPDUButWithValueSpecificToPDU,// EIndexForIRFC822EmailHeader, Application Port Addresses
+    TSmsInformationElementCategories::ECtrlMandatoryIn1stPDUOnly,                       // EIndexReplyAddressFormat
+    TSmsInformationElementCategories::ECtrlSingleInstanceOnly,                          // EIndexEnhanceVoiceMailInformation
+    TSmsInformationElementCategories::ECtrlMultipleInstancesAllowed                     // EIndexForHyperLinkFormat
+    };
+
+
+CSmsUserData* CSmsUserData::NewL(CCnvCharacterSetConverter& aCharacterSetConverter,RFs& aFs,TSmsFirstOctet& aFirstOctet,const TSmsDataCodingScheme& aDataCodingScheme)
+	{
+	LOGGSMU1("CSmsUserData::NewL()");
+
+	CSmsUserData* userdata=new(ELeave) CSmsUserData(aCharacterSetConverter,aFs,aFirstOctet,aDataCodingScheme);
+	CleanupStack::PushL(userdata);
+	userdata->ConstructL();
+	CleanupStack::Pop();
+	return userdata;
+	} // CSmsUserData::NewL
+
+
+/**
+ *  Destructor.
+ */
+CSmsUserData::~CSmsUserData()
+    {
+    iInformationElementArray.ResetAndDestroy();
+    delete iBody;
+    } // CSmsUserData::NewL
+
+
+/**
+ *  Gets an information element by index.
+ *  
+ *  @param aIndex Index of the information element within the User Data
+ *  @return Information element
+ *  @capability None
+ */
+EXPORT_C  CSmsInformationElement& CSmsUserData::InformationElement(TInt aIndex) const
+	{
+	LOGGSMU1("CSmsUserData::InformationElement()");
+
+	return *iInformationElementArray[aIndex];
+	} // CSmsUserData::InformationElement
+
+
+CSmsInformationElement*& CSmsUserData::InformationElementPtr(TInt aIndex)
+    {
+    LOGGSMU1("CSmsUserData::InformationElementPtr()");
+
+    return iInformationElementArray[aIndex];
+    } // CSmsUserData::InformationElementPtr
+
+
+/**
+ *  Gets the index of an information element.
+ *  
+ *  @param aIdentifier An information element Identifier to search for
+ *  @param aIndex The index within the User Data of the information element (if
+ *  found). If more than 1 instance of this information element exists, then
+ *  the 1st instance will be returned.
+ *  
+ *  Use InformationELementIndexL to get all elements.
+ *  @return True if aIdentifier is found in the User Data
+ *  @capability None
+ */
+EXPORT_C TBool CSmsUserData::InformationElementIndex(CSmsInformationElement::TSmsInformationElementIdentifier aIdentifier,TInt& aIndex) const
+	{
+	LOGGSMU1("CSmsUserData::InformationElementIndex()");
+
+	TBool found=EFalse;
+	TInt count=NumInformationElements();
+	for (TInt i=0; (!found) && (i<count); i++)
+		if (InformationElement(i).Identifier()==aIdentifier)
+			{
+			found=ETrue;
+			aIndex=i;
+			}
+	return found;
+	} // CSmsUserData::InformationElementIndex
+
+
+/**
+ *  Gets the last index of an information element.
+ *  
+ *  @param aIdentifier An information element Identifier to search for
+ *  @param aIndex The index within the User Data of the information element (if
+ *  found). If more than 1 instance of this information element exists, then
+ *  the last instance will be returned.
+ *  
+ *  Use InformationELementIndexL to get all elements.
+ *  @return True if aIdentifier is found in the User Data
+ *  @capability None
+ */
+EXPORT_C TBool CSmsUserData::InformationElementLastIndex(CSmsInformationElement::TSmsInformationElementIdentifier aIdentifier,TInt& aIndex) const
+	{
+	LOGGSMU1("CSmsUserData::InformationElementLastIndex()");
+
+	TBool found=EFalse;
+	TInt count=NumInformationElements();
+	for (TInt i=count-1; (!found) && (i>=0); i--)
+		if (InformationElement(i).Identifier()==aIdentifier)
+			{
+			found=ETrue;
+			aIndex=i;
+			}
+	return found;
+	} // CSmsUserData::InformationElementLastIndex
+
+
+/**
+ *  @internalComponent
+ *  
+ *  Locates every information element of type aIdentifier and
+ *  stores its location index in the output array aIndices.
+ *  
+ *  @param aIdentifer
+ *  The information element Identifier to search for
+ *  @param aIndices
+ *  A collection containing the location index for each information element of this type.
+ */
+void CSmsUserData::InformationElementIndicesL(CSmsInformationElement::TSmsInformationElementIdentifier aIdentifier, CArrayFixFlat<TInt>& aIndices) const
+    {
+    LOGGSMU1("CSmsUserData::InformationElementIndicesL()");
+
+    aIndices.Reset();
+    
+	TInt count=NumInformationElements();
+	for (TInt i=0; i<count; i++)
+	    {
+    	if (InformationElement(i).Identifier()==aIdentifier)
+            {
+            aIndices.AppendL(i);
+            }
+        }
+    } // CSmsUserData::InformationElementIndicesL
+
+
+/**
+ *  Note that whilst a pointer to the aIe is passed as an
+ *  input argument, the information element is still owned
+ *  by the calling function, regardless of the return code.
+ *  @param aInformationElement An EMS Information Element
+ */
+TBool CSmsUserData::EmsInformationElementWillFitL(CEmsInformationElement* aIe,CSmsEMSBufferSegmenter& aSeg,TUint& aCharsAddedToCurrentPDU)
+	{
+	LOGGSMU1("CSmsUserData::EmsInformationElementWillFitL()");
+
+	// Before using an EmsInformationElement polymorphically as an SmsIE,
+	// we need to make sure that the IE has been encoded
+	aIe->EncodeInformationElementL();
+	iInformationElementArray.AppendL(aIe);
+
+	TInt sizeLeft=MaxPackedUDUnitsInBodyRemaining();
+	iInformationElementArray.Delete(iInformationElementArray.Count()-1);
+	if(sizeLeft==0 && iBody && (iBody->Length() > 0) && (*iBody)[iBody->Length()-1] == KSms7BitAlphabetEscapeChar)
+	{
+		--aCharsAddedToCurrentPDU;
+		--aSeg.iElementsExtracted;
+		TPtr8 ptr(iBody->Des());
+		ptr.Delete(iBody->Length()-1,1);
+		--sizeLeft;
+	}
+	return sizeLeft>=0;
+	} // CSmsUserData::EmsInformationElementWillFitL
+
+
+/**
+ *  Tests whether the control information element will fit in the current PDU.
+ *  
+ *  Note that whilst a pointer to the aIe is passed as an
+ *  input argument, the information element is still owned
+ *  by the calling function, regardless of the return code.
+ *  
+ *  @param aInformationElement A pointer to an information Element
+ *  @capability None
+ */
+TBool CSmsUserData::ControlInformationElementWillFitL(CSmsInformationElement* aIe)
+    {
+    LOGGSMU1("CSmsUserData::ControlInformationElementWillFitL()");
+
+    if (aIe == NULL)
+        {
+        User::Leave(KErrGeneral);
+        }
+
+    TSmsInformationElementCategories::TInformationElementCategory category;
+
+    if (TSmsInformationElementCategories::GetCategoryDefinition(aIe->Identifier(), category) == EFalse  ||
+    	category == TSmsInformationElementCategories::EEmsInformationElement)
+        {
+        User::Leave(KErrArgument);
+        }
+
+    iInformationElementArray.AppendL(aIe);
+
+    TInt sizeLeft=MaxPackedUDUnitsInBodyRemaining();
+    iInformationElementArray.Delete(iInformationElementArray.Count()-1);
+
+    // Not considering whether escape characters exist in the buffer
+    // as control information elements do not add text to the buffer.
+
+    return sizeLeft>=0;
+    } // CSmsUserData::ControlInformationElementWillFitL
+
+
+/**
+ *  Adds an information element.
+ *  This method can be used to create information elements in the range:
+ *  00 - 09 - i.e. Control Information Elements
+ *  It can be used to create information elements in the following ranges
+ *  (on the assumption that the information element is intended to be encoded into
+ *  every PDU):
+ *  24 - 25 - i.e. National Language Encodings
+ *  70 - 7F - i.e. SIM Tool Kit Security Headers
+ *  80 - 9F - i.e  SMS to SME specific use
+ *  C0 - CF - i.e. SC specific use
+ *  
+ *  Information elements in the following ranges should not be
+ *  added using this interface. Instead they should be added using
+ *  the following identified interfaces:
+ *  0A-1F - Use the interfaces provided to support EMS Elements
+ *  20 - Use the interfaces provided for Email in CSmsMessage
+ *  21 - Use the interface provided by CSmsHyperLinkOperations
+ *  22 - Use the interface provided by CSmsReplyAddressOperations
+ *  23 - Use the interface provided by CSmsEnhancedVoiceMailOperations
+ *  
+ *  This interface should not be used for information element in the following
+ *  ranges, these are reserved for future use in TS23.040 V6.5.0 and their
+ *  characteristics and repeatability have not yet been defined.
+ *  26-6F
+ *  A0-BF
+ *  E0-FF
+ *  
+ *  @param aIdentifier An information element Identifier for aData
+ *  @param aData The information element to add to the User Data
+ *  @leave
+ *  KErrNotSupported if the information element is not supported via this interface.
+ *  @capability None
+ */
+EXPORT_C void CSmsUserData::AddInformationElementL(TSmsId aIdentifier,const TDesC8& aData)
+    {
+    LOGGSMU1("CSmsUserData::AddInformationElementL");
+
+    if  ((aIdentifier >= 0x21) && (aIdentifier <= 0x23) ||
+         (aIdentifier >= 0x26) && (aIdentifier <= 0x6F) ||
+         (aIdentifier >= 0xA0) && (aIdentifier <= 0xBF) ||
+         (aIdentifier >= 0xE0) && (aIdentifier <= 0xFF))
+        {
+        User::Leave(KErrNotSupported);
+        }
+    UpdateInformationElementArrayL(aIdentifier, aData);
+
+    } // CSmsUserData::AddInformationElementL
+
+
+/**
+ *  @internalComponent
+ *  
+ *  Either adds an information element to
+ *  iInformationElementArray.
+ *  
+ *  @param aIdentifier An information element Identifier for aData
+ *  @param aData The information element to add to the User Data
+ */
+void CSmsUserData::UpdateInformationElementArrayL(TSmsId aIdentifier,const TDesC8& aData)
+    {
+    LOGGSMU1("CSmsUserData::UpdateInformationElementsL");
+
+    TInt count=NumInformationElements();
+    if(!CEmsFactory::Supported(aIdentifier))
+        {
+        for (TInt i=0; i<count; i++)
+            {
+ 	        if (InformationElement(i).Identifier()==aIdentifier)
+                {
+                TSmsInformationElementCategories::TInformationElementCategory category;
+                
+                if (TSmsInformationElementCategories::GetCategoryDefinition(aIdentifier, category) == EFalse)
+                	{
+                	User::Leave(KErrArgument);
+                	}
+
+                switch (category)
+                    {
+                    case TSmsInformationElementCategories::ECtrlMandatoryInEveryPDUMultipleInstancesPerPDU:
+                        {
+                        if (InformationElement(i).Identifier() == CSmsInformationElement::ESmsIEISpecialSMSMessageIndication)
+                            {
+                            LOGGSMU3("CSmsUserData::AddInformationElementL1 category = %d, identifier = %d",category,aIdentifier);
+
+                            //if Msg type is the same, swap with the most recent value
+                            if ((InformationElement(i).Data()[0] & ((TUint8) EGsmSmsSpecialMessageIndicationTypeMask)) ==
+                                (aData[0] & ((TUint8) EGsmSmsSpecialMessageIndicationTypeMask)))
+                                {
+                                User::Leave(KErrAlreadyExists);
+                                }
+                            }
+                        else
+                            {
+                            LOGGSMU4("CSmsUserData::AddInformationElementL3 category = %d, identifier = %d, data = %S",category,aIdentifier, &aData);
+                            User::Leave(KErrArgument);
+                            }
+                        break;
+                        }
+                    case TSmsInformationElementCategories::ECtrlMandatoryInEveryPDUAndWithIdenticalValues:
+                    case TSmsInformationElementCategories::ECtrlMandatoryIn1stPDUOnly:
+                    case TSmsInformationElementCategories::ECtrlSingleInstanceOnly:
+                        {
+                        LOGGSMU3("CSmsUserData::AddInformationElementL4 category = %d, identifier = %d",category,aIdentifier);
+                        User::Leave(KErrAlreadyExists);
+                        break;
+                        }
+                    case TSmsInformationElementCategories::ECtrlMultipleInstancesAllowed:
+                        {
+                        LOGGSMU3("CSmsUserData::AddInformationElementL5 category = %d, identifier = %d",category,aIdentifier);
+                        break;
+                        }
+                    case TSmsInformationElementCategories::ECtrlMandatoryInEveryPDUButWithValueSpecificToPDU:
+                        {
+                        LOGGSMU3("CSmsUserData::AddInformationElementL6 category = %d, identifier = %d",category,aIdentifier);
+                        User::Leave(KErrAlreadyExists);
+                        // currently the email header is updated in:
+                        // void CSmsMessage::DecodeBufferL(CArrayPtr<CSmsPDU>& aSmsPDUArray,CSmsBufferBase& aBuffer)
+                        break;
+                        }
+                    default:
+                        {
+                        LOGGSMU3("CSmsUserData::AddInformationElementL8 category = %d, identifier = %d",category,aIdentifier);
+                        User::Leave(KErrNotSupported);
+                        break;
+                        }
+                    }
+                }
+            }
+        }
+
+    	CSmsInformationElement* informationElement=CSmsInformationElement::NewL(aIdentifier,aData);
+    	CleanupStack::PushL(informationElement);
+    	iInformationElementArray.AppendL(informationElement);
+    	CleanupStack::Pop();
+    	SetHeaderPresent(ETrue);
+    } // CSmsUserData::UpdateInformationElementArrayL
+
+
+void CSmsUserData::AddEmsInformationElementL(CEmsInformationElement* aIe)
+	{
+	LOGGSMU1("CSmsUserData::AddEmsInformationElementL()");
+
+	// Before using an EmsInformationElement polymorphically as an SmsIE,
+	// we need to make sure that the IE has been encoded
+	aIe->EncodeInformationElementL();
+	iInformationElementArray.AppendL(aIe);
+	SetHeaderPresent(ETrue);
+	} // CSmsUserData::AddEmsInformationElementL
+
+
+/**
+ *  Removes an information element at the specified index.
+ *  
+ *  @param aIndex Information element index
+ *  @capability None
+ */
+EXPORT_C void CSmsUserData::RemoveInformationElement(TInt aIndex)
+	{
+	LOGGSMU1("CSmsUserData::RemoveInformationElement()");
+	// Since iInformationElementArray[aIndex] pointer is removed from iInformationElementArray, there is no double free issue.
+	// coverity[double_free]
+	delete iInformationElementArray[aIndex];
+	iInformationElementArray[aIndex] = NULL;
+	iInformationElementArray.Delete(aIndex);
+
+	if (NumInformationElements()==0)
+		{
+		SetHeaderPresent(EFalse);
+		}
+	} // CSmsUserData::RemoveInformationElement
+
+
+TInt CSmsUserData::MaxPackedUDUnitsInBodyRemaining() const
+	{
+	LOGGSMU1("CSmsUserData::MaxPackedUDUnitsInBodyRemaining()");
+
+	TInt totalHeaderLengthInUDLUnits=TotalHeaderLengthInUDLUnits();
+	TInt maxPackedUDUnitsInBody=0;
+	if (iDataCodingScheme.TextCompressed()||(iDataCodingScheme.Alphabet()!=TSmsDataCodingScheme::ESmsAlphabet7Bit))
+		{
+		maxPackedUDUnitsInBody=KSmsMaxUserDataSize-totalHeaderLengthInUDLUnits;
+		if (iDataCodingScheme.Alphabet()==TSmsDataCodingScheme::ESmsAlphabetUCS2)
+			{
+			// Cannot split unicode character across PDU boundary
+			maxPackedUDUnitsInBody&=~1;
+			}
+		}
+	else // 7-bit
+		{
+		maxPackedUDUnitsInBody=(8*KSmsMaxUserDataSize)/7-totalHeaderLengthInUDLUnits;
+		}
+
+	if (iBody)
+		return maxPackedUDUnitsInBody-=iBody->Length();
+	return maxPackedUDUnitsInBody;
+	} // CSmsUserData::MaxPackedUDUnitsInBodyRemaining
+
+
+TInt CSmsUserData::MaxPackedUDUnitsInBodyRemaining(TUint aIELen) const
+	{
+	LOGGSMU1("CSmsUserData::MaxPackedUDUnitsInBodyRemaining()");
+
+	TInt totalHeaderLengthInUDLUnits=TotalHeaderLengthInUDLUnits(aIELen);
+	TInt maxPackedUDUnitsInBody=0;
+	if (iDataCodingScheme.TextCompressed()||(iDataCodingScheme.Alphabet()!=TSmsDataCodingScheme::ESmsAlphabet7Bit))
+		{
+		maxPackedUDUnitsInBody=KSmsMaxUserDataSize-totalHeaderLengthInUDLUnits;
+		if (iDataCodingScheme.Alphabet()==TSmsDataCodingScheme::ESmsAlphabetUCS2)
+			{
+			// Cannot split unicode character across PDU boundary
+			maxPackedUDUnitsInBody&=~1;
+			}
+		}
+	else // 7-bit
+		{
+		maxPackedUDUnitsInBody=(8*KSmsMaxUserDataSize)/7-totalHeaderLengthInUDLUnits;
+		}
+
+	if (iBody)
+		return maxPackedUDUnitsInBody-=iBody->Length();
+	return maxPackedUDUnitsInBody;
+	} // CSmsUserData::MaxPackedUDUnitsInBodyRemaining
+
+
+/**
+ *  @capability None
+ */
+EXPORT_C TInt CSmsUserData::MaxBodyLengthInChars() const
+	{
+	LOGGSMU1("CSmsUserData::MaxBodyLengthInChars()");
+
+	TInt totalheaderlengthinudlunits=TotalHeaderLengthInUDLUnits();
+	TInt maxbodylengthinchars=0;
+	if (iDataCodingScheme.TextCompressed())
+		{
+		maxbodylengthinchars=KSmsMaxUserDataSize-totalheaderlengthinudlunits;
+		}
+	else
+		{
+		switch (iDataCodingScheme.Alphabet())
+			{
+			case (TSmsDataCodingScheme::ESmsAlphabet7Bit):
+				{
+				maxbodylengthinchars=(8*KSmsMaxUserDataSize)/7-totalheaderlengthinudlunits;
+				break;
+				}
+			case (TSmsDataCodingScheme::ESmsAlphabet8Bit):
+				{
+				maxbodylengthinchars=KSmsMaxUserDataSize-totalheaderlengthinudlunits;
+				break;
+				}
+			case (TSmsDataCodingScheme::ESmsAlphabetUCS2):
+				{
+				maxbodylengthinchars=(KSmsMaxUserDataSize-totalheaderlengthinudlunits)/2;
+				break;
+				}
+			default:
+			    LOGGSMU1("CSmsUserData::MaxBodyLengthInChars() WARNING! default case has been reached");
+                break;
+ 			}
+		}
+	return maxbodylengthinchars;
+	} // CSmsUserData::MaxBodyLengthInChars
+
+
+/**
+ *  Gets the unpacked User Data Elements.
+ *  
+ *  @return Unpacked User Data Elements
+ *  @capability None
+ */
+EXPORT_C TPtrC8 CSmsUserData::Body() const
+	{
+	LOGGSMU1("CSmsUserData::Body()");
+
+	return iBody->Des();
+	} // CSmsUserData::Body
+
+
+/**
+ *  Sets the User Data (unpacked).
+ *  
+ *  @param aBody Unpacked User Data Elements
+ *  @capability None
+ */
+EXPORT_C void CSmsUserData::SetBodyL(const TDesC8& aBody)
+	{
+	LOGGSMU1("CSmsUserData::SetBodyL()");
+
+	//Some tests fail with this line in, despite it being a valid condition!
+	//__ASSERT_DEBUG(aBody.Length() <= MaxBodyLengthInChars(), User::Leave(KErrTooBig));
+
+	NewBodyL(aBody.Length());
+	iBody->Des().Copy(aBody);
+	} // CSmsUserData::SetBodyL
+
+
+void CSmsUserData::AppendBodyL(const TDesC8& aBody)
+	{
+	LOGGSMU1("CSmsUserData::AppendBodyL()");
+
+	if (iBody)
+		{
+		//Some tests fail with this line in, despite it being a valid condition!
+		//__ASSERT_DEBUG(aBody.Length() + iBody->Length() <= MaxBodyLengthInChars(), User::Leave(KErrTooBig));
+
+		iBody = iBody->ReAllocL(aBody.Length()+iBody->Length());
+		iBody->Des().Append(aBody);
+		}
+	else
+		{
+		SetBodyL(aBody);
+		}
+	} // CSmsUserData::AppendBodyL
+
+
+/**
+ *  Tests if the character is supported by the current character set.
+ *  This function can be used with 7bit and 8bit alphabets.
+ * 
+ *  @param aChar  Character to investigate.
+ * 
+ *  @return  ETrue if the character is supported.
+ * 
+ *  @note Since the function is based on the old behaviour (pre-PREQ2090)
+ *        it does not accept a downgraded character or alternative encoding
+ *        as being supported.
+ *
+ *  @capability None
+ */
+EXPORT_C TBool CSmsUserData::IsSupportedL(TChar aChar)
+	{
+	LOGGSMU1("CSmsUserData::IsSupportedL()");
+
+	CSmsAlphabetConverter* converter=CSmsAlphabetConverter::NewLC(iCharacterSetConverter,iFs,iDataCodingScheme.Alphabet(),IsBinaryData());
+	TBool result=converter->IsSupportedL(aChar);
+	CleanupStack::PopAndDestroy();
+
+	return result;
+	} // CSmsUserData::IsSupportedL
+
+
+/**
+ *  Tests if the descriptor text is supported by the current character set.
+ *  This function can be used with 7bit and 8bit alphabets.
+ * 
+ *  @param aDes                                 Text string to check.
+ *  @param aNumberOfUnconvertibleCharacters     Exit param for the number of
+ *                                              characters unconvertible.
+ *  @param aIndexOfFirstUnconvertibleCharacter  Exit param for the first
+ *                                              unconverted character.
+ * 
+ *  @return  ETrue if the character is supported.
+ *
+ *  @capability None
+ */
+EXPORT_C TBool CSmsUserData::IsSupportedL(const TDesC& aDes, TInt& aNumberOfUnconvertibleCharacters,
+                                          TInt& aIndexOfFirstUnconvertibleCharacter) const
+	{
+	LOGGSMU1("[1] CSmsUserData::IsSupportedL()");
+
+	CSmsAlphabetConverter* converter=CSmsAlphabetConverter::NewLC(iCharacterSetConverter,iFs,iDataCodingScheme.Alphabet(),IsBinaryData());
+	TBool result=converter->IsSupportedL(aDes, aNumberOfUnconvertibleCharacters,
+			                             aIndexOfFirstUnconvertibleCharacter);
+	CleanupStack::PopAndDestroy();
+
+	return result;
+	} // CSmsUserData::IsSupportedL
+
+
+/**
+ *  Tests if the descriptor text is supported by the current character set.
+ *  This function can be used with 7bit and 8bit alphabets.
+ * 
+ *  @param aDes                                 Text string to check.
+ *  @param aEncoding                            Alternative encoding method.
+ *  @param aNumberOfUnconvertibleCharacters     Exit param for the number of
+ *                                              characters unconvertible.
+ *  @param aNumberOfDowngradedCharacters        Exit param for the number of
+ *                                              downgraded characters.
+ *  @param aNumberRequiringAlternativeEncoding  Exit param for the number of
+ *                                              characters requiring use of
+ *                                              the alternative encoder.
+ *  @param aIndexOfFirstUnconvertibleCharacter  Exit param for the first
+ *                                              unconverted character.
+ * 
+ *  @return  ETrue if the character is supported.
+ *
+ *  @capability None
+ */
+EXPORT_C TBool CSmsUserData::IsSupportedL(const TDesC& aDes, TSmsEncoding aEncoding,
+										  TInt& aNumberOfUnconvertibleCharacters,
+                                          TInt& aNumberOfDowngradedCharacters,
+                                          TInt& aNumberRequiringAlternativeEncoding,
+                                          TInt& aIndexOfFirstUnconvertibleCharacter) const
+	{
+	LOGGSMU1("[2] CSmsUserData::IsSupportedL()");
+
+	CSmsAlphabetConverter* converter=CSmsAlphabetConverter::NewLC(iCharacterSetConverter,iFs,iDataCodingScheme.Alphabet(),IsBinaryData());
+	TBool result=converter->IsSupportedL(aDes, aEncoding,
+			                             aNumberOfUnconvertibleCharacters,
+			                             aNumberOfDowngradedCharacters,
+			                             aNumberRequiringAlternativeEncoding,
+			                             aIndexOfFirstUnconvertibleCharacter);
+	CleanupStack::PopAndDestroy();
+
+	return result;
+	} // CSmsUserData::IsSupportedL
+
+
+TUint8* CSmsUserData::EncodeL(TUint8* aPtr) const
+	{
+	LOGGSMU1("CSmsUserData::EncodeL()");
+
+	__ASSERT_DEBUG(0<=MaxPackedUDUnitsInBodyRemaining(),Panic(KGsmuPanicUserDataBodyTooLong));
+	// Encode the user data length
+	TInt totalHeaderLengthInUDLUnits=TotalHeaderLengthInUDLUnits();
+	TSmsOctet userDataLength=totalHeaderLengthInUDLUnits+TSmsOctet(BodyLengthInUDLUnits());
+	aPtr=userDataLength.EncodeL(aPtr);
+	// Encode any user data header
+	if (HeaderPresent())
+		{
+		TSmsOctet headerLength=HeaderLength();
+		aPtr=headerLength.EncodeL(aPtr);
+		TInt numInformationElements=NumInformationElements();
+		for (TInt i=0; i<numInformationElements; i++)
+			aPtr=iInformationElementArray[i]->EncodeL(aPtr);
+		}
+	// Pack the user data body
+	TInt startBit=0;
+	if (iDataCodingScheme.Alphabet()==TSmsDataCodingScheme::ESmsAlphabet7Bit)
+		startBit=(totalHeaderLengthInUDLUnits*7)%8;
+	TSmsAlphabetPacker packer(iDataCodingScheme.Alphabet(),IsBinaryData(),startBit);
+	TPtr8 ptr((TUint8*)aPtr,0,packer.PackedOctetsRequiredL(Body().Length()));
+	aPtr+=packer.PackL(ptr,Body());
+	return aPtr;
+	} // CSmsUserData::EncodeL
+
+
+void CSmsUserData::DecodeL(TGsmuLex8& aPdu)
+	{
+	DecodeL(aPdu, EFalse);
+	}
+
+void CSmsUserData::DecodeL(TGsmuLex8& aPdu, TBool aAcceptTruncation)
+	{	
+	LOGGSMU1("CSmsUserData::DecodeL()");
+
+	// Reset current data
+	iInformationElementArray.ResetAndDestroy();
+	// Decode the user data
+	TSmsOctet userDataLength;
+	userDataLength.DecodeL(aPdu);
+	TSmsOctet headerLength;
+	// Decode any user data header
+	TBool headerPresent=HeaderPresent();
+	/*
+	if (headerPresent || IsHeaderPresent(aPtr,dataLength))
+	*/
+	if (headerPresent)
+		{
+		headerLength.DecodeL(aPdu);
+		if ((1+headerLength)>KSmsMaxUserDataSize)
+			User::Leave(KErrGsmSMSTpduNotSupported);
+		while (HeaderLength()<headerLength)
+			{
+			CSmsInformationElement* informationelement=CSmsInformationElement::NewL();
+			CleanupStack::PushL(informationelement);
+			informationelement->DecodeL(aPdu);
+			iInformationElementArray.AppendL(informationelement);
+			CleanupStack::Pop(informationelement);
+			}
+		if (HeaderLength()!=headerLength)
+			User::Leave(KErrGsmSMSTpduNotSupported);
+		}
+	// Decode the body - make sure we have enough buffer
+	TInt headerLengthInUDLUnits=TotalHeaderLengthInUDLUnits();
+	TInt bodyLengthInUDLUnits=userDataLength-headerLengthInUDLUnits;
+
+	if(bodyLengthInUDLUnits <=0)
+	{
+		NewBodyL(0);
+		return;
+	}
+
+	NewBodyL(bodyLengthInUDLUnits);
+
+	// Unpack the body
+	TInt startBit=0;
+	if (iDataCodingScheme.Alphabet()==TSmsDataCodingScheme::ESmsAlphabet7Bit)
+		startBit=(headerLengthInUDLUnits*7)%8;
+	TSmsAlphabetPacker unpacker(iDataCodingScheme.Alphabet(),IsBinaryData(),startBit);
+	TInt bodyLengthInOctets=unpacker.PackedOctetsRequiredL(bodyLengthInUDLUnits);
+	TPtr8 destPtr((TUint8*)iBody->Des().Ptr(),0,bodyLengthInUDLUnits);
+
+	const TPtrC8 sourcePtr(aPdu.NextWithNoIncL(bodyLengthInOctets,aAcceptTruncation));
+	if ( aAcceptTruncation && sourcePtr.Length() < bodyLengthInOctets)
+		{
+		// field was truncated in an acceptable situation (User Data in Status Report PDU)
+		bodyLengthInUDLUnits = unpacker.NumUDUnitsL(sourcePtr.Length());
+		}
+	unpacker.UnpackL(sourcePtr,destPtr,bodyLengthInUDLUnits);
+
+	//@note No need to call aPdu.IncL() because CSmsUserData is always at the end of a PDU
+	} // CSmsUserData::DecodeL
+
+
+void CSmsUserData::InternalizeL(RReadStream& aStream)
+	{
+	iInformationElementArray.ResetAndDestroy();
+	TInt numiformationelements=aStream.ReadInt32L();
+	// The "header present" flag must mirror whether information elements are present, and
+	// the parental iFirstOctet should already be set by its InternalizeL()
+	__ASSERT_DEBUG(((!HeaderPresent() && numiformationelements == 0) || (HeaderPresent() && numiformationelements > 0)), Panic(KGsmuPanicInformationElementIndexOutOfRange));
+	for (TInt i=0; i<numiformationelements; i++)
+		{
+		CSmsInformationElement* informationelement=CSmsInformationElement::NewL();
+		CleanupStack::PushL(informationelement);
+		aStream >> *informationelement;
+		iInformationElementArray.AppendL(informationelement);
+		CleanupStack::Pop();
+		}
+	delete iBody;
+	iBody=NULL;
+	iBody=HBufC8::NewL(aStream,KSmsMaxUserDataLengthInChars);
+	} // CSmsUserData::InternalizeL
+
+
+void CSmsUserData::ExternalizeL(RWriteStream& aStream) const
+	{
+	TInt numiformationelements=iInformationElementArray.Count();
+	aStream.WriteInt32L(numiformationelements);
+	for (TInt i=0; i<numiformationelements; i++)
+		aStream << *iInformationElementArray[i];
+	aStream << *iBody;
+	} // CSmsUserData::ExternalizeL
+
+
+CSmsUserData::CSmsUserData(CCnvCharacterSetConverter& aCharacterSetConverter,RFs& aFs,TSmsFirstOctet& aFirstOctet,const TSmsDataCodingScheme& aDataCodingScheme):
+    iCharacterSetConverter(aCharacterSetConverter),
+    iFs(aFs),
+    iFirstOctet(aFirstOctet),
+    iDataCodingScheme(aDataCodingScheme),
+    iInformationElementArray(8)
+    {
+    } // CSmsUserData::CSmsUserData
+
+
+void CSmsUserData::ConstructL()
+	{
+	LOGGSMU1("CSmsUserData::ConstructL()");
+
+	NewBodyL(0);
+	} // CSmsUserData::ConstructL
+
+
+/**
+ *  Duplicates this CSmsUserData object.
+ * 
+ *  @return  Pointer to the newly created CSmsUserData object.
+ */
+CSmsUserData* CSmsUserData::DuplicateL(TSmsFirstOctet& aFirstOctet,
+									   const TSmsDataCodingScheme& aDataCodingScheme) const
+	{
+	LOGGSMU1("CSmsUserData::DuplicateL()");
+
+	CSmsUserData*  userdata = CSmsUserData::NewL(iCharacterSetConverter, iFs,
+	                                             aFirstOctet, aDataCodingScheme);
+	CleanupStack::PushL(userdata);
+
+	userdata->SetBodyL(Body());
+
+	for (TInt ie = 0;  ie < iInformationElementArray.Count();  ie++)
+		{
+		CSmsInformationElement*  oldIE = iInformationElementArray[ie];
+
+		if (CEmsFactory::Supported(oldIE->Identifier()))
+			{
+			CEmsInformationElement*  newIE = static_cast<CEmsInformationElement*>(oldIE)->DuplicateL();
+			
+			CleanupStack::PushL(newIE);
+			userdata->AddEmsInformationElementL(newIE);
+			CleanupStack::Pop(newIE);
+			}
+		else
+			{
+			userdata->UpdateInformationElementArrayL(oldIE->Identifier(), oldIE->Data());
+			}
+		}
+
+	CleanupStack::Pop();
+
+	return userdata;
+	} // CSmsUserData::DuplicateL
+
+
+TInt CSmsUserData::HeaderLength() const
+	{
+	LOGGSMU1("CSmsUserData::HeaderLength()");
+
+	TInt numinformationelements=NumInformationElements();
+	TInt headerlength=0;
+	for (TInt i=0; i<numinformationelements; i++)
+		headerlength+=iInformationElementArray[i]->Length();
+	return headerlength;
+	} // CSmsUserData::HeaderLength
+
+
+TInt CSmsUserData::TotalHeaderLengthInUDLUnits() const
+	{
+	LOGGSMU1("CSmsUserData::TotalHeaderLengthInUDLUnits()");
+
+	TInt totalheaderlengthinudlunits=0;
+	if (iInformationElementArray.Count()>0)
+		{
+		TInt totalheaderlength=1+HeaderLength();
+		if (iDataCodingScheme.TextCompressed())
+			{
+			totalheaderlengthinudlunits=totalheaderlength;
+			}
+		else
+			{
+			switch(iDataCodingScheme.Alphabet())
+				{
+				case (TSmsDataCodingScheme::ESmsAlphabet7Bit):
+					{
+					totalheaderlengthinudlunits=((8*totalheaderlength)+6)/7; //  Rounds up
+					break;
+					}
+				case (TSmsDataCodingScheme::ESmsAlphabet8Bit):
+				case (TSmsDataCodingScheme::ESmsAlphabetUCS2):
+					{
+					totalheaderlengthinudlunits=totalheaderlength;
+					break;
+					}
+				default:
+				    LOGGSMU1("CSmsUserData::TotalHeaderLengthInUDLUnits() WARNING default case has been reached");
+                    break;
+				}
+			}
+		}
+	return totalheaderlengthinudlunits;
+	} // CSmsUserData::TotalHeaderLengthInUDLUnits
+
+
+TInt CSmsUserData::TotalHeaderLengthInUDLUnits(TInt aIElen) const
+	{
+	LOGGSMU1("CSmsUserData::TotalHeaderLengthInUDLUnits()");
+
+		TInt totalheaderlengthinudlunits=0;
+		TInt totalheaderlength=aIElen;
+
+		if (iInformationElementArray.Count()>0)
+			totalheaderlength+=HeaderLength();
+
+		if(totalheaderlength)totalheaderlength+=1; //UDHL
+
+		if (iDataCodingScheme.TextCompressed())
+			{
+			totalheaderlengthinudlunits=totalheaderlength;
+			}
+		else
+			{
+			switch(iDataCodingScheme.Alphabet())
+				{
+				case (TSmsDataCodingScheme::ESmsAlphabet7Bit):
+					{
+					totalheaderlengthinudlunits=((8*totalheaderlength)+6)/7; //  Rounds up
+					break;
+					}
+				case (TSmsDataCodingScheme::ESmsAlphabet8Bit):
+				case (TSmsDataCodingScheme::ESmsAlphabetUCS2):
+					{
+					totalheaderlengthinudlunits=totalheaderlength;
+					break;
+					}
+				default:
+                    break;
+				}
+			}
+		return totalheaderlengthinudlunits;
+	} // CSmsUserData::TotalHeaderLengthInUDLUnits
+
+
+TInt CSmsUserData::BodyLengthInUDLUnits() const
+	{
+	LOGGSMU1("CSmsUserData::BodyLengthInUDLUnits()");
+
+	return iBody->Des().Length();
+	} // CSmsUserData::BodyLengthInUDLUnits
+
+
+void CSmsUserData::NewBodyL(TInt aLength)
+	{
+	LOGGSMU1("CSmsUserData::NewBodyL()");
+
+
+		HBufC8* body=HBufC8::NewL(aLength);
+		delete iBody;
+		iBody=body;
+		iBody->Des().SetLength(aLength);
+
+	} // CSmsUserData::NewBodyL
+
+
+TBool CSmsUserData::HeaderPresent() const
+	{
+	LOGGSMU1("CSmsUserData::HeaderPresent()");
+
+	return (iFirstOctet&TSmsFirstOctet::ESmsUDHIMask)==TSmsFirstOctet::ESmsUDHIHeaderPresent;
+	} // CSmsUserData::HeaderPresent
+
+
+void CSmsUserData::SetHeaderPresent(TBool aHeaderPresent)
+	{
+	LOGGSMU1("CSmsUserData::SetHeaderPresent()");
+
+	iFirstOctet=aHeaderPresent? (iFirstOctet&(~TSmsFirstOctet::ESmsUDHIMask))|TSmsFirstOctet::ESmsUDHIHeaderPresent: (iFirstOctet&(~TSmsFirstOctet::ESmsUDHIMask))|TSmsFirstOctet::ESmsUDHIHeaderNotPresent;
+	} // CSmsUserData::SetHeaderPresent
+
+
+TBool CSmsUserData::IsBinaryData() const
+	{
+	LOGGSMU1("CSmsUserData::IsBinaryData()");
+
+	TInt index=0;
+	return (iDataCodingScheme.TextCompressed()) ||
+			((iDataCodingScheme.Alphabet()==TSmsDataCodingScheme::ESmsAlphabet8Bit) &&
+			(InformationElementIndex(CSmsInformationElement::ESmsIEIApplicationPortAddressing8Bit,index) ||
+	        InformationElementIndex(CSmsInformationElement::ESmsIEIApplicationPortAddressing16Bit,index)));
+	} // CSmsUserData::IsBinaryData
+
+
+/**
+ *  Converts type of number and numbering plan identification information
+ *  from the type of address parameter to the NMobilePhone::TMobileTON
+ *  and NMobilePhone::TMobileNPI format.
+ *  
+ *  @return aTon The number type
+ *  @return aNpi The numbering plan
+ *  
+ *  @capability None
+ */
+EXPORT_C void TGsmSmsTypeOfAddress::ConvertToETelMM(NMobilePhone::TMobileTON& aTon,NMobilePhone::TMobileNPI& aNpi) const
+    {
+    LOGGSMU1("TGsmSmsTypeOfAddress::ConvertToETelMM()");
+
+    switch (TON())
+    {
+		case EGsmSmsTONInternationalNumber:
+            {
+            aTon = (NMobilePhone::EInternationalNumber);
+            break;
+            }
+        case EGsmSmsTONNationalNumber:
+            {
+            aTon = (NMobilePhone::ENationalNumber);
+            break;
+            }
+        case EGsmSmsTONNetworkSpecificNumber:
+            {
+            aTon = (NMobilePhone::ENetworkSpecificNumber);
+            break;
+            }
+        case EGsmSmsTONSubscriberNumber:
+            {
+            aTon = (NMobilePhone::ESubscriberNumber);
+            break;
+            }
+        case EGsmSmsTONAlphaNumeric:
+            {
+            aTon = (NMobilePhone::EAlphanumericNumber);
+            break;
+            }
+        case EGsmSmsTONAbbreviatedNumber:
+            {
+            aTon = (NMobilePhone::EAbbreviatedNumber);
+            break;
+            }
+
+        default:
+            {
+            aTon = (NMobilePhone::EUnknownNumber);
+            break;
+            }
+		}
+
+    switch (NPI())
+		{
+        case EGsmSmsNPIISDNTelephoneNumberingPlan:
+            {
+            aNpi = (NMobilePhone::EIsdnNumberPlan);
+            break;
+            }
+        case EGsmSmsNPIDataNumberingPlan:
+            {
+            aNpi = (NMobilePhone::EDataNumberPlan);
+            break;
+            }
+        case EGsmSmsNPITelexNumberingPlan:
+            {
+            aNpi = (NMobilePhone::ETelexNumberPlan);
+            break;
+            }
+        case EGsmSmsNPINationalNumberingPlan:
+            {
+            aNpi = (NMobilePhone::ENationalNumberPlan);
+            break;
+            }
+        case EGsmSmsNPIPrivateNumberingPlan:
+            {
+            aNpi = (NMobilePhone::EPrivateNumberPlan);
+            break;
+            }
+        case EGsmSmsNPIERMESNumberingPlan:
+            {
+            aNpi = (NMobilePhone::EERMESNumberPlan);
+            break;
+            }
+
+        default:
+            {
+            aNpi = (NMobilePhone::EUnknownNumberingPlan);
+            break;
+            }
+		}
+	} // NMobilePhone::TMobileNPI
+
+
+/**
+ *  Converts type of number and numbering plan identification information
+ *  from the NMobilePhone::TMobileTON and NMobilePhone::TMobileNPI format
+ *  to the type of address parameter.
+ *  
+ *  @param aTon The number type
+ *  @param aNpi The numbering plan
+ *  
+ *  @capability None
+ */
+EXPORT_C void TGsmSmsTypeOfAddress::SetFromETelMM(NMobilePhone::TMobileTON aTon,NMobilePhone::TMobileNPI aNpi)
+    {
+    LOGGSMU1("TGsmSmsTypeOfAddress::SetFromETelMM()");
+
+    switch (aTon)
+    {
+		case NMobilePhone::EInternationalNumber:
+            {
+            SetTON( EGsmSmsTONInternationalNumber );
+            break;
+            }
+        case NMobilePhone::ENationalNumber:
+            {
+            SetTON( EGsmSmsTONNationalNumber );
+            break;
+            }
+        case NMobilePhone::ENetworkSpecificNumber:
+            {
+            SetTON( EGsmSmsTONNetworkSpecificNumber );
+            break;
+            }
+        case NMobilePhone::ESubscriberNumber:
+            {
+            SetTON( EGsmSmsTONSubscriberNumber );
+            break;
+            }
+        case NMobilePhone::EAlphanumericNumber:
+            {
+            SetTON( EGsmSmsTONAlphaNumeric );
+            break;
+            }
+        case NMobilePhone::EAbbreviatedNumber:
+            {
+            SetTON( EGsmSmsTONAbbreviatedNumber );
+            break;
+            }
+
+        default:
+            {
+            SetTON( EGsmSmsTONUnknown );
+            break;
+            }
+		}
+
+    switch (aNpi)
+		{
+        case NMobilePhone::EIsdnNumberPlan:
+            {
+            SetNPI( EGsmSmsNPIISDNTelephoneNumberingPlan );
+            break;
+            }
+        case NMobilePhone::EDataNumberPlan:
+            {
+            SetNPI( EGsmSmsNPIDataNumberingPlan );
+            break;
+            }
+        case NMobilePhone::ETelexNumberPlan:
+            {
+            SetNPI( EGsmSmsNPITelexNumberingPlan );
+            break;
+            }
+        case NMobilePhone::ENationalNumberPlan:
+            {
+            SetNPI( EGsmSmsNPINationalNumberingPlan );
+            break;
+            }
+        case NMobilePhone::EPrivateNumberPlan:
+            {
+            SetNPI( EGsmSmsNPIPrivateNumberingPlan );
+            break;
+            }
+        case NMobilePhone::EERMESNumberPlan:
+            {
+            SetNPI( EGsmSmsNPIERMESNumberingPlan );
+            break;
+            }
+
+        default:
+            {
+            SetNPI( EGsmSmsNPIUnknown );
+            break;
+            }
+		}
+	} // NMobilePhone::TMobileTON
+
+
+/**
+ *  @publishedAll
+ *  
+ *  Indicates whether this message is a Voice Mail Notification
+ *  or a Voice Mail Deletion Confirmation.
+ *  
+ *  @return
+ *  TVoiceMailInfoType, indicating whether this message is a Voice Mail
+ *  Notification or a Voice Mail Deletion Confirmation.
+ *  
+ *  @capability None
+ */
+EXPORT_C TVoiceMailInfoType CEnhancedVoiceMailBoxInformation::Type() const
+	{
+	LOGGSMU1("CEnhancedVoiceMailBoxInformation::Type()");
+
+	return iType;
+	} // CEnhancedVoiceMailBoxInformation::Type
+
+
+/**
+ *  @publishedAll
+ *  
+ *  Sets the subscriber profile per 23.040 v6.5 Section 9.2.3.24.13.1.
+ *  
+ *  @param aProfile
+ *  The required subscriber profile
+ *  
+ *  @capability None
+ */
+EXPORT_C void CEnhancedVoiceMailBoxInformation::SetProfile(TSmsMessageProfileType aProfile)
+	{
+	LOGGSMU1("CEnhancedVoiceMailBoxInformation::SetProfile()");
+
+	iProfile = aProfile;
+	} // CEnhancedVoiceMailBoxInformation::SetProfile
+
+
+/**
+ *  @publishedAll
+ *  
+ *  Gets the subscriber profile per 23.040 v6.5 Section 9.2.3.24.13.1.
+ *  
+ *  @param aProfile
+ *  The current subscriber profile
+ *  
+ *  @capability None
+ */
+EXPORT_C TSmsMessageProfileType CEnhancedVoiceMailBoxInformation::Profile() const
+	{
+	LOGGSMU1("CEnhancedVoiceMailBoxInformation::Profile()");
+
+	return iProfile;
+	} // CEnhancedVoiceMailBoxInformation::Profile
+
+
+/**
+ *  @publishedAll
+ *  
+ *  Configures the storage directive
+ *  
+ *  @param aIsStored
+ *  Set to True if the SM is to be stored in the ME or USIM,
+ *  False is the SM is to be discarded.
+ *  
+ *  @capability None
+ */
+EXPORT_C void CEnhancedVoiceMailBoxInformation::SetStorage(TBool aIsStored)
+	{
+	LOGGSMU1("CEnhancedVoiceMailBoxInformation::SetStorage()");
+
+	iStorage = aIsStored;
+	} // CEnhancedVoiceMailBoxInformation::SetStorage
+
+
+/**
+ *  @publishedAll
+ *  
+ *  Indicates whether the SM is to be stored or discarded
+ *  
+ *  @return
+ *  True if the SM is to be stored in the ME or USIM,
+ *  False is the SM is to be discarded.
+ *  
+ *  @capability None
+ */
+EXPORT_C TBool CEnhancedVoiceMailBoxInformation::Store() const
+	{
+	LOGGSMU1("CEnhancedVoiceMailBoxInformation::Store()");
+
+	return iStorage;
+	} // CEnhancedVoiceMailBoxInformation::Store
+
+
+/**
+ *  @publishedAll
+ *  
+ *  Used to set or reset the voice mail status to almost full.
+ *  
+ *  @param aIsStored
+ *  Set to True the voice mail system is almost full.
+ *  Set to False otherwise.
+ *  
+ *  @capability None
+ */
+EXPORT_C void CEnhancedVoiceMailBoxInformation::SetAlmostMaximumCapacity(TBool aIsAlmostFull)
+	{
+	LOGGSMU1("CEnhancedVoiceMailBoxInformation::SetAlmostMaximumCapacity()");
+
+	iAlmostFull = aIsAlmostFull;
+	} // CEnhancedVoiceMailBoxInformation::SetAlmostMaximumCapacity
+
+
+/**
+ *  @publishedAll
+ *  
+ *  Indicates whether the voice mail system is almost at full capacity.
+ *  
+ *  @return
+ *  True, if the voice mail system is almost full.
+ *  False otherwise.
+ *  
+ *  @capability None
+ */
+EXPORT_C TBool CEnhancedVoiceMailBoxInformation::AlmostMaximumCapacity() const
+	{
+	LOGGSMU1("CEnhancedVoiceMailBoxInformation::AlmostMaximumCapacity()");
+
+	return iAlmostFull;
+	} // CEnhancedVoiceMailBoxInformation::AlmostMaximumCapacity
+
+
+/**
+ *  @publishedAll
+ *  
+ *  Used to set or reset the voice mail status to full.
+ *  
+ *  @param aIsStored
+ *  Set to True the voice mail system is full.
+ *  Set to False otherwise.
+ *  
+ *  @capability None
+ */
+EXPORT_C void CEnhancedVoiceMailBoxInformation::SetMaximumCapacity(TBool aIsFull)
+	{
+	LOGGSMU1("CEnhancedVoiceMailBoxInformation::SetMaximumCapacity()");
+
+	iFull = aIsFull;
+	} // CEnhancedVoiceMailBoxInformation::SetMaximumCapacity
+
+
+/**
+ *  @publishedAll
+ *  
+ *  Indicates whether the voice mail status is full.
+ *  
+ *  @return
+ *  True if the voice mail system is almost full.
+ *  False otherwise.
+ *  
+ *  @capability None
+ */
+EXPORT_C TBool CEnhancedVoiceMailBoxInformation::MaximumCapacity() const
+	{
+	LOGGSMU1("CEnhancedVoiceMailBoxInformation::MaximumCapacity()");
+
+	return iFull;
+	} // CEnhancedVoiceMailBoxInformation::MaximumCapacity
+
+
+/**
+ *  @publishedAll
+ *  
+ *  Indicates whether the message contains extension bytes
+ *  
+ *  @return
+ *  True if the message contains extension bytes.
+ *  False otherwise.
+ *  
+ *  @capability None
+ */
+EXPORT_C TBool CEnhancedVoiceMailBoxInformation::ExtensionIndicator() const
+	{
+	LOGGSMU1("CEnhancedVoiceMailBoxInformation::ExtensionIndicator()");
+
+	return iExtensionIndicator;
+	} // CEnhancedVoiceMailBoxInformation::ExtensionIndicator
+
+
+void CEnhancedVoiceMailBoxInformation::NewBufferL(TInt aLength)
+	{
+	LOGGSMU2("CEnhancedVoiceMailBoxInformation::NewBufferL, length = %d",aLength);
+
+	HBufC* buffer=HBufC::NewL(aLength);
+	delete iAccessAddress;
+	iAccessAddress=buffer;
+	iAccessAddress->Des().SetLength(aLength);
+	iAccessAddress->Des().FillZ();
+	} // CEnhancedVoiceMailBoxInformation::NewBufferL
+
+
+/**
+ *  @publishedAll
+ *  
+ *  Used to set the voice mail box number, overwriting any pre-existing number.
+ *  
+ *  @param aAddress
+ *  The voice mail box address.
+ *  
+ *  @capability None
+ */
+EXPORT_C void  CEnhancedVoiceMailBoxInformation::SetAccessAddressL(const TDesC& aAddress)
+	{
+	LOGGSMU1("CEnhancedVoiceMailBoxInformation::SetAccessAddressL()");
+
+	TInt length=aAddress.Length();
+	NewBufferL(length);
+	iAccessAddress->Des().Copy(aAddress);
+
+	const TGsmSmsTypeOfNumber typeofnumber=length && (iAccessAddress->Des()[0]=='+')? EGsmSmsTONInternationalNumber: EGsmSmsTONUnknown;
+	iTypeOfAddress.SetTON(typeofnumber);
+	} // CEnhancedVoiceMailBoxInformation::SetAccessAddressL
+
+
+/**
+ *  @publishedAll
+ *  
+ *  Retrieves the voice mail box number.
+ *  
+ *  @return
+ *  A pointer to the voice mail box number.
+ *  
+ *  @capability None
+ */
+EXPORT_C TPtrC CEnhancedVoiceMailBoxInformation::AccessAddress() const
+	{
+	LOGGSMU1("CEnhancedVoiceMailBoxInformation::AccessAddress()");
+
+	TPtrC ptr;
+	if (iAccessAddress)
+	    ptr.Set(iAccessAddress->Des());
+	return ptr;
+	} // CEnhancedVoiceMailBoxInformation::AccessAddress
+
+
+/**
+ *  @publishedAll
+ *  
+ *  Used to set the voice mail box number as a parsed address
+ *  
+ *  @param aParsedAddress
+ *  The parsed address to be used as the voice mail box number.
+ *  
+ *  @capability None
+ */
+EXPORT_C void  CEnhancedVoiceMailBoxInformation::SetParsedAccessAddressL(const TGsmSmsTelNumber& aParsedAddress)
+	{
+	LOGGSMU1("CEnhancedVoiceMailBoxInformation::SetParsedAccessAddressL()");
+
+   	iTypeOfAddress=aParsedAddress.iTypeOfAddress;
+	DoSetParsedAddressL(aParsedAddress.iTelNumber);
+	} // CEnhancedVoiceMailBoxInformation::SetParsedAccessAddressL
+
+
+/**
+ *  @publishedAll
+ *  
+ *  Used to get the voice mail box number as a parsed address.
+ *  
+ *  @param aParsedAddress
+ *  An output parameter which is set to the parsed address.
+ *  
+ *  @capability None
+ */
+EXPORT_C void  CEnhancedVoiceMailBoxInformation::ParsedAccessAddress(TGsmSmsTelNumber& aParsedAddress) const
+	{
+	LOGGSMU1("CEnhancedVoiceMailBoxInformation::ParsedAccessAddress()");
+
+	aParsedAddress.iTypeOfAddress = iTypeOfAddress;
+
+	TInt maxparsedlength=aParsedAddress.iTelNumber.MaxLength();
+
+	if (iTypeOfAddress.TON()==EGsmSmsTONAlphaNumeric)
+		{
+		TInt parsedlength=AccessAddress().Length();
+		if (parsedlength>maxparsedlength)
+			parsedlength=maxparsedlength;
+		aParsedAddress.iTelNumber.Copy(AccessAddress().Mid(0,parsedlength));
+		}
+	else
+		{
+		aParsedAddress.iTelNumber.SetLength(maxparsedlength);
+
+		TInt length=iAccessAddress->Des().Length();
+		TInt parsedlength=0;
+		for (TInt i=0; (i<length) && (parsedlength<maxparsedlength); i++)
+			{
+			TText ch=iAccessAddress->Des()[i];
+			if ((ch>='0') && (ch<='9'))
+				{
+				aParsedAddress.iTelNumber[parsedlength]=(TUint8) ch;
+				parsedlength++;
+				}
+			}
+
+		aParsedAddress.iTelNumber.SetLength(parsedlength);
+		}
+	} // CEnhancedVoiceMailBoxInformation::ParsedAccessAddress
+
+
+void CEnhancedVoiceMailBoxInformation::DoSetParsedAddressL(const TDesC& aAddress)
+	{
+	LOGGSMU1("CEnhancedVoiceMailBoxInformation::DoSetParsedAddressL()");
+
+	TInt length=aAddress.Length();
+	if ((iTypeOfAddress.TON()==EGsmSmsTONInternationalNumber) &&
+	    (length && (aAddress[0]!='+')))
+		{
+		NewBufferL(length+1);
+		iAccessAddress->Des()[0]='+';
+		TPtr ptr((TText*) (iAccessAddress->Des().Ptr()+1),length,length);
+		ptr.Copy(aAddress);
+		}
+	else
+		{
+		NewBufferL(length);
+		iAccessAddress->Des().Copy(aAddress);
+		}
+	} // CEnhancedVoiceMailBoxInformation::DoSetParsedAddressL
+
+
+/**
+ *  @publishedAll
+ *  
+ *  Sets the number of voice messages to a value in the range 0 to 255.
+ *  
+ *  @param aNumber
+ *  The number of voice messages.
+ *  
+ *  @capability None
+ */
+EXPORT_C void   CEnhancedVoiceMailBoxInformation::SetNumberOfVoiceMessages(TUint8 aNumber)
+	{
+	LOGGSMU1("CEnhancedVoiceMailBoxInformation::SetNumberOfVoiceMessages()");
+
+	iNumberOfVoiceMessages=aNumber;
+	} // CEnhancedVoiceMailBoxInformation::SetNumberOfVoiceMessages
+
+
+/**
+ *  @publishedAll
+ *  
+ *  Retrieves the number of voice messages that are unread.
+ *  
+ *  @return
+ *  The number of unread voice messages.
+ *  
+ *  @capability None
+ */
+EXPORT_C TUint8 CEnhancedVoiceMailBoxInformation::NumberOfVoiceMessages() const
+	{
+	LOGGSMU1("CEnhancedVoiceMailBoxInformation::NumberOfVoiceMessages()");
+
+	return iNumberOfVoiceMessages;
+	} // CEnhancedVoiceMailBoxInformation::NumberOfVoiceMessages
+
+
+TUint8* CEnhancedVoiceMailBoxInformation::EncodeL(TUint8* aPtr, CCnvCharacterSetConverter& aCharacterSetConverter, RFs& aFs) const
+	{
+	*aPtr =  (((TUint8) iType)       & EMask1Bit )       +
+	        ((((TUint8) iProfile)    & EMask2Bits) << 2) +
+	        ((((TUint8) iStorage)    & EMask1Bit ) << 4) +
+	        ((((TUint8) iAlmostFull) & EMask1Bit ) << 5) +
+	        ((((TUint8) iFull)       & EMask1Bit ) << 6) +
+	         (((TUint8) iExtensionIndicator      ) << 7);
+
+	LOGGSMU2("CEnhancedVoiceMailBoxInformation::EncodeL 1st byte = %d",*aPtr);
+	aPtr++;
+
+	// Create an address object to encode the mail box access address into the
+	// format required by 23.040 v6.5.0 section 9.1.2.5.
+	CSmsAddress* address = CSmsAddress::NewL(aCharacterSetConverter,aFs);
+	CleanupStack::PushL(address);
+	TPtrC accessAddressPtr;
+	if (iAccessAddress)
+	    {
+		accessAddressPtr.Set(iAccessAddress->Des());
+	    }
+	address->SetRawAddressL(iTypeOfAddress,accessAddressPtr);
+	aPtr = address->EncodeL(aPtr);
+	CleanupStack::PopAndDestroy(address);
+
+	*aPtr = (TUint8) iNumberOfVoiceMessages;
+	aPtr++;
+
+	return aPtr;
+	} // CEnhancedVoiceMailBoxInformation::EncodeL
+
+
+void CEnhancedVoiceMailBoxInformation::DecodeL(TGsmuLex8& aVoiceMailInfo, CCnvCharacterSetConverter& aCharacterSetConverter, RFs& aFs)
+	{
+	TUint8 Byte1 = aVoiceMailInfo.GetL();
+
+	iType               = (TVoiceMailInfoType)       (Byte1       & EMask1Bit);
+	iProfile            = (TSmsMessageProfileType ) ((Byte1 >> 2) & EMask2Bits);
+	iStorage            = (TBool)                   ((Byte1 >> 4) & EMask1Bit);
+	iAlmostFull         = (TBool)                   ((Byte1 >> 5) & EMask1Bit);
+	iFull               = (TBool)                   ((Byte1 >> 6) & EMask1Bit);
+	iExtensionIndicator = (TBool)                   ((Byte1 >> 7) & EMask1Bit);
+
+	LOGGSMU2("CEnhancedVoiceMailBoxInformation::DecodeL 1st byte = %d", Byte1);
+
+	// Create an address object to deccode the mail box access address from the
+	// format required by 23.040 v6.5.0 section 9.1.2.5.
+	CSmsAddress* decodedAddress = CSmsAddress::NewL(aCharacterSetConverter,aFs);
+	CleanupStack::PushL(decodedAddress);
+
+	// CSmsAddress::DecodeL is also used to decode source and destination addresses.
+	// CSmsAddress::DecodeL expects internally that alphanumeric addresses will be size
+	// CSmsAddress::KSmsAddressMaxAddressValueLength=10.
+	// Need to add padding bytes to bring the address field up to the maximum size.
+	const TPtrC8 remainder(aVoiceMailInfo.Remainder());
+
+	if (remainder.Length() < CSmsAddress::KSmsAddressMaxAddressLength)
+	    {
+	    TBuf8<CSmsAddress::KSmsAddressMaxAddressLength> data;
+	    data = remainder;
+	    TInt actualLength = data.Length();
+	    data.SetLength(CSmsAddress::KSmsAddressMaxAddressLength);
+
+	    for (TUint8 j = actualLength; j < CSmsAddress::KSmsAddressMaxAddressLength; j++)
+	        {
+	        data[j] = 0;
+	        }
+
+	    TGsmuLex8 encodedAddress(data);
+	    decodedAddress->DecodeL(encodedAddress);
+	    // might want to check that aVoiceMailInfo can be incremented
+	    // by encodedAddress.Offset.
+	    aVoiceMailInfo.Inc(encodedAddress.Offset());
+	    }
+	else
+	    {
+	    decodedAddress->DecodeL(aVoiceMailInfo);
+	    }
+
+	TInt length=(decodedAddress->Address()).Length();
+	NewBufferL(length);
+	iAccessAddress->Des().Copy((decodedAddress->Address().Ptr()),length);
+
+	iTypeOfAddress = decodedAddress->TypeOfAddress();
+
+	CleanupStack::PopAndDestroy(decodedAddress);
+
+	iNumberOfVoiceMessages = aVoiceMailInfo.GetL();
+	LOGGSMU2("CEnhancedVoiceMailBoxInformation::DecodeL iNumberOfVoiceMessages = %d", iNumberOfVoiceMessages);
+	} // CEnhancedVoiceMailBoxInformation::DecodeL
+
+
+CEnhancedVoiceMailBoxInformation::CEnhancedVoiceMailBoxInformation()
+	{
+	LOGGSMU1("CEnhancedVoiceMailBoxInformation::CEnhancedVoiceMailBoxInformation()");
+
+	// Consider changing this over to a Panic.
+	iType               = EGsmSmsVoiceMailNotification;
+	iOctet1Bit1         = EFalse;
+	iProfile            = EGsmSmsProfileId1;
+	iStorage            = EFalse;
+	iAlmostFull         = EFalse;
+	iFull               = EFalse;
+	iExtensionIndicator = EFalse;
+	iTypeOfAddress      = 0;
+	} // CEnhancedVoiceMailBoxInformation::CEnhancedVoiceMailBoxInformation
+
+
+CEnhancedVoiceMailBoxInformation::CEnhancedVoiceMailBoxInformation(TVoiceMailInfoType aTVoiceMailInfoType)
+	{
+	LOGGSMU1("CEnhancedVoiceMailBoxInformation::CEnhancedVoiceMailBoxInformation()");
+
+	iType               = aTVoiceMailInfoType;
+	iOctet1Bit1         = EFalse;
+	iProfile            = EGsmSmsProfileId1;
+	iStorage            = EFalse;
+	iAlmostFull         = EFalse;
+	iFull               = EFalse;
+	iExtensionIndicator = EFalse;
+	iTypeOfAddress      = 0;
+	} // CEnhancedVoiceMailBoxInformation::CEnhancedVoiceMailBoxInformation
+
+
+/**
+ *  @internalComponent
+ *  
+ *  Prevent clients from using the copy constructor by including it in the class definition
+ *  but making it protected and not exporting it.
+ *  
+ *  @capability None
+ */
+CEnhancedVoiceMailBoxInformation::CEnhancedVoiceMailBoxInformation(const CEnhancedVoiceMailBoxInformation&)
+    {
+    // Ignore in code coverage - not intended to be used
+    BULLSEYE_OFF    
+    LOGGSMU1("CEnhancedVoiceMailBoxInformation::CEnhancedVoiceMailBoxInformation");
+    Panic(KGsmuPanicMethodBodyNotImplemented);
+    BULLSEYE_RESTORE
+    }
+
+/**
+ *  @internalComponent
+ *  
+ *  Prevent clients from using the equality operator by including it in the class definition
+ *  but making it protected and not exporting it.
+ *  
+ *  @capability None
+ */
+TBool CEnhancedVoiceMailBoxInformation::operator==(const CEnhancedVoiceMailBoxInformation&)
+    {
+    // Ignore in code coverage - not intended to be used
+    BULLSEYE_OFF    
+    LOGGSMU1("CEnhancedVoiceMailBoxInformation::operator==");
+    Panic(KGsmuPanicMethodBodyNotImplemented);
+    return EFalse;
+    BULLSEYE_RESTORE
+    }
+
+/**
+ *  @internalComponent
+ *  
+ *  Prevent clients from using the assignment operator by including it in the class definition
+ *  but making it protected and not exporting it.
+ *  
+ *  @capability None
+ */
+void CEnhancedVoiceMailBoxInformation::operator=(const CEnhancedVoiceMailBoxInformation&)
+    {
+    // Ignore in code coverage - not intended to be used
+    BULLSEYE_OFF    
+    LOGGSMU1("CEnhancedVoiceMailBoxInformation::operator=");
+    Panic(KGsmuPanicMethodBodyNotImplemented);
+    BULLSEYE_RESTORE
+    }
+
+void CEnhancedVoiceMailBoxInformation::ConstructL()
+	{
+	LOGGSMU1("CEnhancedVoiceMailBoxInformation::ConstructL()");
+
+	NewBufferL(0);
+	} // CEnhancedVoiceMailBoxInformation::ConstructL
+
+
+CEnhancedVoiceMailBoxInformation::~CEnhancedVoiceMailBoxInformation()
+	{
+	LOGGSMU1("CEnhancedVoiceMailBoxInformation::~CEnhancedVoiceMailBoxInformation");
+	delete iAccessAddress;
+	} // CEnhancedVoiceMailBoxInformation::ConstructL
+
+
+CEnhancedVoiceMailBoxInformation* CEnhancedVoiceMailBoxInformation::NewL()
+	{
+	LOGGSMU1("CEnhancedVoiceMailBoxInformation::NewL()");
+
+	CEnhancedVoiceMailBoxInformation* aCEnhancedVoiceMailBoxInformation=new(ELeave) CEnhancedVoiceMailBoxInformation();
+	CleanupStack::PushL(aCEnhancedVoiceMailBoxInformation);
+	aCEnhancedVoiceMailBoxInformation->ConstructL();
+	CleanupStack::Pop(aCEnhancedVoiceMailBoxInformation);
+	return aCEnhancedVoiceMailBoxInformation;
+	} // CEnhancedVoiceMailBoxInformation::NewL
+
+
+/**
+ *  @publishedAll
+ *  
+ *  Sets the message id to a value between 0 and 65535.
+ *  
+ *  @param aNumber
+ *  The message id
+ *  
+ *  @capability None
+ */
+EXPORT_C void CVoiceMailNotification::SetMessageId(TUint16 aMessageId)
+	{
+	LOGGSMU1("CVoiceMailNotification::SetMessageId()");
+
+	iMessageId = aMessageId;
+	} // CVoiceMailNotification::SetMessageId
+
+
+/**
+ *  @publishedAll
+ *  
+ *  Retrieves the message id, a value in the range 0 to 65535.
+ *  
+ *  @return
+ *  The message id,
+ *  
+ *  @capability None
+ */
+EXPORT_C TUint16 CVoiceMailNotification::MessageId() const
+	{
+	LOGGSMU1("CVoiceMailNotification::MessageId()");
+
+	return iMessageId;
+	} // CVoiceMailNotification::MessageId
+
+
+/**
+ *  @publishedAll
+ *  
+ *  Sets the voice mail message length to a value between 0 and 255
+ *  
+ *  @param aLength
+ *  The voice mail message length.
+ *  
+ *  @capability None
+ */
+EXPORT_C void CVoiceMailNotification::SetMessageLength(TUint8 aLength)
+	{
+	LOGGSMU1("CVoiceMailNotification::SetMessageLength()");
+
+	iMessageLength=aLength;
+	} // CVoiceMailNotification::SetMessageLength
+
+
+/**
+ *  @publishedAll
+ *  
+ *  Retrieves the voice mail message length, a value in the range 0 to 255.
+ *  
+ *  @return
+ *  The voice mail message length.
+ *  
+ *  @capability None
+ */
+EXPORT_C TUint8 CVoiceMailNotification::MessageLength() const
+	{
+	LOGGSMU1("CVoiceMailNotification::MessageLength()");
+
+	return iMessageLength;
+	} // CVoiceMailNotification::MessageLength
+
+
+/**
+ *  @publishedAll
+ *  
+ *  Sets the number of days that the voice message will be retained to
+ *  a value between 0 and 31. Values in excess of 31 will be capped at
+ *  31.
+ *  
+ *  @param aDays
+ *  The number of retention days.
+ *  
+ *  @capability None
+ */
+EXPORT_C void CVoiceMailNotification::SetRetentionDays(TUint8 aDays)
+	{
+	LOGGSMU1("CVoiceMailNotification::SetRetentionDays()");
+
+	if (aDays > 31)
+	    {
+	    iRetentionDays = 31;
+	    }
+	else
+	    {
+	    iRetentionDays = aDays;
+	    }
+	} // CVoiceMailNotification::SetRetentionDays
+
+
+/**
+ *  @publishedAll
+ *  
+ *  Retrieves the number of days the voice message will be retained.
+ *  
+ *  @return
+ *  The number of days the voice message will be retained.
+ *  
+ *  @capability None
+ */
+EXPORT_C TUint8 CVoiceMailNotification::RetentionDays() const
+	{
+	LOGGSMU1("CVoiceMailNotification::RetentionDays()");
+
+	return iRetentionDays;
+	} // CVoiceMailNotification::RetentionDays
+
+
+/**
+ *  @publishedAll
+ *  
+ *  Sets the message priority to urgent
+ *  
+ *  @param aPriority
+ *  Set to True if the priority is urgent,
+ *  Otherwise set to False.
+ *  
+ *  @capability None
+ */
+EXPORT_C void CVoiceMailNotification::SetPriorityIndication(TBool aPriority)
+	{
+	LOGGSMU1("CVoiceMailNotification::SetPriorityIndication()");
+
+	iPriorityIndication=aPriority;
+	} // CVoiceMailNotification::SetPriorityIndication
+
+
+/**
+ *  @publishedAll
+ *  
+ *  Retrieves the priority indication.
+ *  
+ *  @return
+ *  True if the priority is urgent,
+ *  False otherwise.
+ *  
+ *  @capability None
+ */
+EXPORT_C TBool CVoiceMailNotification::PriorityIndication() const
+	{
+	LOGGSMU1("CVoiceMailNotification::PriorityIndication()");
+
+	return iPriorityIndication;
+	} // CVoiceMailNotification::PriorityIndication
+
+
+/**
+ *  @publishedAll
+ *  
+ *  Indicates whether the voice mail notification contains extension bytes.
+ *  
+ *  @return
+ *  True if the voice mail notification contains extension bytes.
+ *  False otherwise.
+ *  
+ *  @capability None
+ */
+EXPORT_C TBool CVoiceMailNotification::MessageExtensionIndication() const
+	{
+	LOGGSMU1("CVoiceMailNotification::MessageExtensionIndication()");
+
+	return iMessageExtensionIndicator;
+	} // CVoiceMailNotification::MessageExtensionIndication
+
+
+void CVoiceMailNotification::NewBufferL(TInt aLength)
+	{
+	LOGGSMU1("CVoiceMailNotification::NewBufferL()");
+
+	HBufC* buffer=HBufC::NewL(aLength);
+	delete iCallingLineIdentity;
+	iCallingLineIdentity=buffer;
+	iCallingLineIdentity->Des().SetLength(aLength);
+	iCallingLineIdentity->Des().FillZ();
+	} // CVoiceMailNotification::NewBufferL
+
+
+/**
+ *  @publishedAll
+ *  
+ *  Used to set the calling line idenity
+ *  
+ *  @param aLineIdentity
+ *  
+ *  @capability None
+ */
+EXPORT_C void  CVoiceMailNotification::SetCallingLineIdentityL(TDesC& aLineIdentity)
+	{
+	LOGGSMU1("CVoiceMailNotification::SetCallingLineIdentityL()");
+
+	TInt length=aLineIdentity.Length();
+	NewBufferL(length);
+	iCallingLineIdentity->Des().Copy(aLineIdentity);
+
+	const TGsmSmsTypeOfNumber typeofnumber=length && (iCallingLineIdentity->Des()[0]=='+')? EGsmSmsTONInternationalNumber: EGsmSmsTONUnknown;
+	iTypeOfAddress.SetTON(typeofnumber);
+	} // CVoiceMailNotification::SetCallingLineIdentityL
+
+
+/**
+ *  @publishedAll
+ *  
+ *  Retrieves the Calling Line Identity
+ *  
+ *  @return
+ *  A pointer to the Calling Line Identity.
+ *  
+ *  @capability None
+ */
+EXPORT_C TPtrC CVoiceMailNotification::CallingLineIdentity() const
+	{
+	LOGGSMU1("CVoiceMailNotification::CallingLineIdentity()");
+
+	TPtrC ptr;
+	if (iCallingLineIdentity)
+	    ptr.Set(iCallingLineIdentity->Des());
+	return ptr;
+	} // CVoiceMailNotification::CallingLineIdentity
+
+
+/**
+ *  @publishedAll
+ *  
+ *  Set the Calling Line Id as a parsed address.
+ *  
+ *  @param aParsedAddress
+ *  The Calling Line Id as a parsed address.
+ *  
+ *  @capability None
+ */
+EXPORT_C void CVoiceMailNotification::SetParsedCallingLineIdentityL(TGsmSmsTelNumber& aParsedAddress)
+	{
+	LOGGSMU1("CVoiceMailNotification::SetParsedCallingLineIdentityL()");
+
+	iTypeOfAddress=aParsedAddress.iTypeOfAddress;
+	DoSetParsedAddressL(aParsedAddress.iTelNumber);
+	} // CVoiceMailNotification::SetParsedCallingLineIdentityL
+
+
+/**
+ *  @publishedAll
+ *  
+ *  Gets the Calling Line Id as a parsed address.
+ *  
+ *  @param aParsedAddress
+ *  An output parameter which is to be set to the parsed calling line ID.
+ *  
+ *  @capability None
+ */
+EXPORT_C void CVoiceMailNotification::ParsedCallingLineIdentity(TGsmSmsTelNumber& aParsedAddress) const
+	{
+	LOGGSMU1("CVoiceMailNotification::ParsedCallingLineIdentity()");
+
+	aParsedAddress.iTypeOfAddress = iTypeOfAddress;
+
+	TInt maxparsedlength=aParsedAddress.iTelNumber.MaxLength();
+
+	if (iTypeOfAddress.TON()==EGsmSmsTONAlphaNumeric)
+		{
+		TInt parsedlength=CallingLineIdentity().Length();
+		if (parsedlength>maxparsedlength)
+			parsedlength=maxparsedlength;
+		aParsedAddress.iTelNumber.Copy(CallingLineIdentity().Mid(0,parsedlength));
+		}
+	else
+		{
+		aParsedAddress.iTelNumber.SetLength(maxparsedlength);
+
+		TInt length=iCallingLineIdentity->Des().Length();
+		TInt parsedlength=0;
+		for (TInt i=0; (i<length) && (parsedlength<maxparsedlength); i++)
+			{
+			TText ch=iCallingLineIdentity->Des()[i];
+			if ((ch>='0') && (ch<='9'))
+				{
+				aParsedAddress.iTelNumber[parsedlength]=(TUint8) ch;
+				parsedlength++;
+				}
+			}
+
+		aParsedAddress.iTelNumber.SetLength(parsedlength);
+		}
+	} // CVoiceMailNotification::ParsedCallingLineIdentity
+
+
+void CVoiceMailNotification::NewExtensionL(TInt aLength)
+	{
+	LOGGSMU1("CVoiceMailNotification::NewExtensionL()");
+
+	HBufC* buffer=HBufC::NewL(aLength);
+	delete iExtension;
+	iExtension=buffer;
+	iExtension->Des().SetLength(aLength);
+	iExtension->Des().FillZ();
+	} // CVoiceMailNotification::NewExtensionL
+
+
+/*void CVoiceMailNotification::SetExtension(TDesC& aExtension)
+	{
+	LOGGSMU1("CVoiceMailNotification::SetExtension()");
+
+	TInt length=aExtension.Length();
+	NewExtensionL(length);
+	iExtension->Des().Copy(aExtension);
+	} // CVoiceMailNotification::SetExtension
+
+TPtrC CVoiceMailNotification::Extension() const
+	{
+	LOGGSMU1("CVoiceMailNotification::Extension()");
+
+	TPtrC ptr;
+	if (iExtension)
+	    ptr.Set(iExtension->Des());
+	return ptr;
+	}*/
+
+
+/**
+ *  @internalComponent
+ *  
+ *  Determines the size of the encoded Voice Mail Notification.
+ *  
+ *  @param aCharacterSetConverter  A reference to a character set converter.
+ *  @param aFs  A reference to the file server.
+ *  @return The size of the encoded Voice Mail Notification
+ *  
+ *  @capability None
+ */
+TUint8 CVoiceMailNotification::SizeL(CCnvCharacterSetConverter& aCharacterSetConverter, RFs& aFs)
+	{
+	LOGGSMU1("CVoiceMailNotification::SizeL()");
+
+	const TUint8 KTotalSizeOfFixedLengthAttributes = 4;
+	TUint8 size = KTotalSizeOfFixedLengthAttributes;
+
+	// need to find the size of the calling line ID.
+	CSmsAddress* address = CSmsAddress::NewL(aCharacterSetConverter,aFs);
+	CleanupStack::PushL(address);
+
+	TPtrC callingLineIdentityPtr;
+	if (iCallingLineIdentity)
+	    {
+		callingLineIdentityPtr.Set(iCallingLineIdentity->Des());
+	    }
+
+	address->SetRawAddressL(iTypeOfAddress,callingLineIdentityPtr);
+
+	size += address->SizeL();
+	CleanupStack::PopAndDestroy(address);
+
+	return size;
+	} // CVoiceMailNotification::SizeL
+
+
+TUint8* CVoiceMailNotification::EncodeL(TUint8* aPtr, CCnvCharacterSetConverter& aCharacterSetConverter, RFs& aFs) const
+	{
+	// When changes are made to this function that affect the
+	// number of bytes that are encoded, this should be reflected in
+	// CVoiceMailNotification::SizeL()
+	LOGGSMU1("CVoiceMailNotification::EncodeL");
+
+
+	*aPtr =   (TUint8)  (iMessageId                         >> 8);  // Message Id MSB
+	aPtr++;
+	*aPtr =   (TUint8)   iMessageId;                                // Message Id LSB
+	aPtr++;
+	*aPtr =   (TUint8)   iMessageLength;
+	aPtr++;
+	*aPtr =   ((TUint8)  (iRetentionDays & EMask5Bits))             +
+	         (((TUint8)   iPriorityIndication)               << 6)  +
+	         (((TUint8)   iMessageExtensionIndicator)        << 7);
+	aPtr++;
+
+	CSmsAddress* address = CSmsAddress::NewL(aCharacterSetConverter,aFs);
+	CleanupStack::PushL(address);
+
+	TPtrC callingLineIdentityPtr;
+	if (iCallingLineIdentity)
+	    {
+		callingLineIdentityPtr.Set(iCallingLineIdentity->Des());
+	    }
+
+	address->SetRawAddressL(iTypeOfAddress,callingLineIdentityPtr);
+
+	aPtr = address->EncodeL(aPtr);
+	CleanupStack::PopAndDestroy(address);
+
+	return aPtr;
+	} // CVoiceMailNotification::EncodeL
+
+
+void CVoiceMailNotification::DecodeL(TGsmuLex8& aVoiceMailInfo, CCnvCharacterSetConverter& aCharacterSetConverter, RFs& aFs)
+	{
+	LOGGSMU1("CVoiceMailNotification::DecodeL");
+
+	iMessageId = (((TUint16) aVoiceMailInfo.GetL()) << 8);
+	iMessageId += ((TUint16) aVoiceMailInfo.GetL());
+
+	iMessageLength=aVoiceMailInfo.GetL();
+
+	TUint8 currentByte = aVoiceMailInfo.GetL();
+
+	iRetentionDays             =   currentByte       & EMask5Bits;
+	iPriorityIndication        = ((currentByte >> 6) & EMask1Bit);
+	iMessageExtensionIndicator = ((currentByte >> 7) & EMask1Bit);
+
+	CSmsAddress* decodedAddress = CSmsAddress::NewL(aCharacterSetConverter,aFs);
+	CleanupStack::PushL(decodedAddress);
+
+	const TPtrC8 remainder(aVoiceMailInfo.Remainder());
+	// The address information element makes an assumption that aVoiceMail must
+	// be of size CSmsAddress::KSmsAddressMaxAddressLength
+	// Provide padding to ensure that this is the case.
+	if (remainder.Length() < CSmsAddress::KSmsAddressMaxAddressLength)
+	    {
+	    TBuf8<CSmsAddress::KSmsAddressMaxAddressLength> data;
+	    data = remainder;
+	    TInt actualLength = data.Length();
+	    data.SetLength(CSmsAddress::KSmsAddressMaxAddressLength);
+
+	    for (TUint8 j = actualLength; j < CSmsAddress::KSmsAddressMaxAddressLength; j++)
+	        {
+	        data[j] = 0;
+	        }
+
+	    TGsmuLex8 encodedAddress(data);
+	    decodedAddress->DecodeL(encodedAddress);
+	    // Should be the last piece of data to be decoded
+	    // The next line is included for completeness.
+	    aVoiceMailInfo.Inc(encodedAddress.Offset());
+	    }
+	else
+	    {
+	    decodedAddress->DecodeL(aVoiceMailInfo);
+	    }
+
+	TInt length=(decodedAddress->Address()).Length();
+	NewBufferL(length);
+	iCallingLineIdentity->Des().Copy((decodedAddress->Address().Ptr()),length);
+
+	iTypeOfAddress = decodedAddress->TypeOfAddress();
+
+	CleanupStack::PopAndDestroy(decodedAddress);
+
+	if (iMessageExtensionIndicator)
+	    {
+	    TUint8 extensionLength = aVoiceMailInfo.GetL();
+	    aVoiceMailInfo.Inc(extensionLength);
+	    }
+	} // CVoiceMailNotification::DecodeL
+
+
+/**
+ *  @internalComponent
+ *  
+ *  Prevent clients from using the copy constructor by including it in the class definition
+ *  but making it protected and not exporting it.
+ *  
+ *  @capability None
+ */
+CVoiceMailNotification::CVoiceMailNotification(const CVoiceMailNotification&)
+    {
+    // Ignore in code coverage - not intended to be used
+    BULLSEYE_OFF    
+    LOGGSMU1("CVoiceMailNotification::CVoiceMailNotification");
+    Panic(KGsmuPanicMethodBodyNotImplemented);
+    BULLSEYE_RESTORE
+    }
+
+/**
+ *  @internalComponent
+ *  
+ *  Prevent clients from using the equality operator by including it in the class definition
+ *  but making it protected and not exporting it.
+ *  
+ *  @capability None
+ */
+TBool CVoiceMailNotification::operator==(const CVoiceMailNotification&)
+    {
+    // Ignore in code coverage - not intended to be used
+    BULLSEYE_OFF    
+    LOGGSMU1("CVoiceMailNotification::operator==");
+    Panic(KGsmuPanicMethodBodyNotImplemented);
+    return EFalse;
+    BULLSEYE_RESTORE
+    }
+
+/**
+ *  @internalComponent
+ *  
+ *  Prevent clients from using the assignment operator by including it in the class definition
+ *  but making it protected and not exporting it.
+ *  
+ *  @capability None
+ */
+void CVoiceMailNotification::operator=(const CVoiceMailNotification&)
+    {
+    // Ignore in code coverage - not intended to be used
+    BULLSEYE_OFF    
+    LOGGSMU1("CVoiceMailNotification::operator=");
+    Panic(KGsmuPanicMethodBodyNotImplemented);
+    BULLSEYE_RESTORE
+    }
+
+CVoiceMailNotification::CVoiceMailNotification()
+	{
+	LOGGSMU1("CVoiceMailNotification::CVoiceMailNotification()");
+
+	iMessageId                 = 0;
+	iMessageLength             = 0;
+	iRetentionDays             = 0;
+	iOctetN8Bit1               = EFalse;
+	iPriorityIndication        = EFalse;
+	iMessageExtensionIndicator = EFalse;
+	iTypeOfAddress             = 0;
+	} // CVoiceMailNotification::CVoiceMailNotification
+
+
+/**
+ *  @publishedAll
+ *  
+ *  Class Destructor
+ *  
+ *  @capability None
+ */
+EXPORT_C CVoiceMailNotification::~CVoiceMailNotification()
+	{
+	LOGGSMU1("CVoiceMailNotification::~CVoiceMailNotification");
+	delete iCallingLineIdentity;
+	delete iExtension;
+	} // CVoiceMailNotification::CVoiceMailNotification
+
+
+void CVoiceMailNotification::ConstructL()
+	{
+	LOGGSMU1("CVoiceMailNotification::ConstructL()");
+
+	NewBufferL(0);
+	NewExtensionL(0);
+	} // CVoiceMailNotification::ConstructL
+
+
+/**
+ *  @publishedAll
+ *  
+ *  Class construction method.
+ *  
+ *  @capability None
+ */
+EXPORT_C CVoiceMailNotification* CVoiceMailNotification::NewL()
+	{
+	LOGGSMU1("CVoiceMailNotification::NewL()");
+
+	CVoiceMailNotification* aCVoiceMailNotification=new(ELeave) CVoiceMailNotification();
+	CleanupStack::PushL(aCVoiceMailNotification);
+	aCVoiceMailNotification->ConstructL();
+	CleanupStack::Pop(aCVoiceMailNotification);
+	return aCVoiceMailNotification;
+	} // CVoiceMailNotification::NewL
+
+
+void CVoiceMailNotification::DoSetParsedAddressL(const TDesC& aAddress)
+	{
+	LOGGSMU1("CVoiceMailNotification::DoSetParsedAddressL()");
+
+	TInt length=aAddress.Length();
+	if ((iTypeOfAddress.TON()==EGsmSmsTONInternationalNumber) &&
+	    (length && (aAddress[0]!='+')))
+		{
+		NewBufferL(length+1);
+		iCallingLineIdentity->Des()[0]='+';
+		TPtr ptr((TText*) (iCallingLineIdentity->Des().Ptr()+1),length,length);
+		ptr.Copy(aAddress);
+		}
+	else
+		{
+		NewBufferL(length);
+		iCallingLineIdentity->Des().Copy(aAddress);
+		}
+	} // CVoiceMailNotification::DoSetParsedAddressL
+
+
+/**
+ *  @publishedAll
+ *  
+ *  Retrieves the number of voice message notifications contained in
+ *  this information. The range is 0 to 15.
+ *  
+ *  @return
+ *  The number of voice message notifications in this information element.
+ *  
+ *  @capability None
+ */
+EXPORT_C TUint8 CEnhancedVoiceMailNotification::NumberOfVoiceMails()
+	{
+	LOGGSMU1("CEnhancedVoiceMailNotification::NumberOfVoiceMails()");
+
+	return (TUint8) iNotifications->Count();
+	} // CEnhancedVoiceMailNotification::NumberOfVoiceMails
+
+
+/*void CEnhancedVoiceMailNotification::SetExtension(TDesC& aExtension)
+	{
+	LOGGSMU1("CEnhancedVoiceMailNotification::SetExtension()");
+
+	TInt length=aExtension.Length();
+	NewExtensionL(length);
+	iExtension->Des().Copy(aExtension);
+	} // CEnhancedVoiceMailNotification::SetExtension
+
+TPtrC CEnhancedVoiceMailNotification::Extension() const
+	{
+	LOGGSMU1("CEnhancedVoiceMailNotification::Extension()");
+
+	TPtrC ptr;
+	if (iExtension)
+	    ptr.Set(iExtension->Des());
+	return ptr;
+	}*/
+
+
+/**
+ *  @publishedAll
+ *  
+ *  Provides a reference to the collection that is used to contain the Voice Mail Notifications.
+ *  A maximum of 15 voice mail confirmations is supported. If more that 15 voice mails notifications are added
+ *  the CEnhancedVoiceMailNotification will not be added to the CSmsMessage by the CSmsEnhancedVoiceMailOperations
+ *  class.
+ *  
+ *  @return
+ *  A reference to the collection that is used to contain the Voice Mail Notifications.
+ *  
+ *  @capability None
+ */
+EXPORT_C RPointerArray<CVoiceMailNotification>& CEnhancedVoiceMailNotification::GetVoiceMailNotifications()
+	{
+	LOGGSMU1("CEnhancedVoiceMailNotification::GetVoiceMailNotifications()");
+
+	return *iNotifications;
+	} // CEnhancedVoiceMailNotification::GetVoiceMailNotifications
+
+
+void CEnhancedVoiceMailNotification::NewExtensionL(TInt aLength)
+	{
+	LOGGSMU1("CEnhancedVoiceMailNotification::NewExtensionL()");
+
+	HBufC* buffer=HBufC::NewL(aLength);
+	delete iExtension;
+	iExtension=buffer;
+	iExtension->Des().SetLength(aLength);
+	iExtension->Des().FillZ();
+	} // CEnhancedVoiceMailNotification::NewExtensionL
+
+
+/**
+ *  @publishedAll
+ *  
+ *  Class construction method.
+ *  
+ *  @capability None
+ */
+EXPORT_C  CEnhancedVoiceMailNotification* CEnhancedVoiceMailNotification::NewL()
+	{
+	LOGGSMU1("CEnhancedVoiceMailNotification::NewL()");
+
+	CEnhancedVoiceMailNotification* aCEnhancedVoiceMailNotification=new(ELeave) CEnhancedVoiceMailNotification();
+	CleanupStack::PushL(aCEnhancedVoiceMailNotification);
+	aCEnhancedVoiceMailNotification->CEnhancedVoiceMailBoxInformation::ConstructL();
+	aCEnhancedVoiceMailNotification->ConstructL();
+	CleanupStack::Pop(aCEnhancedVoiceMailNotification);
+	return aCEnhancedVoiceMailNotification;
+	} // CEnhancedVoiceMailNotification::NewL
+
+
+CEnhancedVoiceMailNotification::CEnhancedVoiceMailNotification() : CEnhancedVoiceMailBoxInformation(EGsmSmsVoiceMailNotification)
+	{
+	} // CEnhancedVoiceMailNotification::CEnhancedVoiceMailNotification
+
+
+/**
+ *  @internalComponent
+ *  
+ *  Prevent clients from using the copy constructor by including it in the class definition
+ *  but making it protected and not exporting it.
+ *  
+ *  @capability None
+ */
+CEnhancedVoiceMailNotification::CEnhancedVoiceMailNotification(const CEnhancedVoiceMailNotification&)
+    {
+    // Ignore in code coverage - not intended to be used
+    BULLSEYE_OFF    
+    LOGGSMU1("CEnhancedVoiceMailNotification::CEnhancedVoiceMailNotification");
+    Panic(KGsmuPanicMethodBodyNotImplemented);
+    BULLSEYE_RESTORE
+    }
+
+/**
+ *  @internalComponent
+ *  
+ *  Prevent clients from using the equality operator by including it in the class definition
+ *  but making it protected and not exporting it.
+ *  
+ *  @capability None
+ */
+TBool CEnhancedVoiceMailNotification::operator==(const CEnhancedVoiceMailNotification&)
+    {
+    // Ignore in code coverage - not intended to be used
+    BULLSEYE_OFF    
+    LOGGSMU1("CEnhancedVoiceMailNotification::operator==");
+    Panic(KGsmuPanicMethodBodyNotImplemented);
+    return EFalse;
+    BULLSEYE_RESTORE
+    }
+
+/**
+ *  @internalComponent
+ *  
+ *  Prevent clients from using the assignment operator by including it in the class definition
+ *  but making it protected and not exporting it.
+ *  
+ *  @capability None
+ */
+void CEnhancedVoiceMailNotification::operator=(const CEnhancedVoiceMailNotification&)
+    {
+    // Ignore in code coverage - not intended to be used
+    BULLSEYE_OFF    
+    LOGGSMU1("CEnhancedVoiceMailNotification::operator=");
+    Panic(KGsmuPanicMethodBodyNotImplemented);
+    BULLSEYE_RESTORE
+    }
+
+/**
+ *  @publishedAll
+ *  
+ *  Class destructor.
+ *  
+ *  @capability None
+ */
+EXPORT_C  CEnhancedVoiceMailNotification::~CEnhancedVoiceMailNotification()
+	{
+	LOGGSMU1("CEnhancedVoiceMailNotification::~CEnhancedVoiceMailNotification");
+	delete iExtension;
+	iNotifications->ResetAndDestroy();
+	iNotifications->Close();
+	delete iNotifications;
+	} // CEnhancedVoiceMailNotification::operator
+
+
+void CEnhancedVoiceMailNotification::ConstructL()
+	{
+	LOGGSMU1("CEnhancedVoiceMailNotification::ConstructL()");
+
+	NewExtensionL(0);
+	iNotifications = new (ELeave) RPointerArray<CVoiceMailNotification>(KMaxNumberOfNotifications);
+	} // CEnhancedVoiceMailNotification::ConstructL
+
+
+TUint8* CEnhancedVoiceMailNotification::EncodeL(TUint8* aCurrentPtr, CCnvCharacterSetConverter& aCharacterSetConverter, RFs& aFs) const
+	{
+	LOGGSMU1("CEnhancedVoiceMailNotification::EncodeL");
+
+	TUint8* startPtr   = aCurrentPtr;
+
+	aCurrentPtr = CEnhancedVoiceMailBoxInformation::EncodeL(aCurrentPtr, aCharacterSetConverter, aFs);
+
+	TUint8 count = (TUint8)  iNotifications->Count();
+	if (count > KMaxNumberOfNotifications)
+	    {
+	    User::Leave(KErrArgument);
+	    }
+
+	*aCurrentPtr = (count & KSmsNotificationBitMask);
+	aCurrentPtr++;
+
+	TInt16 spaceAlreadyAllocated = 0; // handle architectures whose address space increments and whose address space decrements.
+	(aCurrentPtr > startPtr) ? (spaceAlreadyAllocated = aCurrentPtr - startPtr) : (spaceAlreadyAllocated = startPtr - aCurrentPtr);
+
+	TInt16 remainingSize = (TInt16)(CEnhancedVoiceMailNotification::KSmsMaxEnhancedVoiceMailSize - spaceAlreadyAllocated);
+	for (TUint i = 0; i < count; i++)
+	    {
+	    remainingSize -= (TInt16)(*iNotifications)[i]->SizeL(aCharacterSetConverter,aFs);
+	    if (remainingSize < 0)
+	        {
+	        User::Leave(KErrArgument);
+	        }
+
+	    aCurrentPtr = (*iNotifications)[i]->EncodeL(aCurrentPtr, aCharacterSetConverter, aFs);
+	    }
+
+	return aCurrentPtr;
+	} // CEnhancedVoiceMailNotification::EncodeL
+
+
+void CEnhancedVoiceMailNotification::DecodeL(TGsmuLex8& aVoiceMailInfo, CCnvCharacterSetConverter& aCharacterSetConverter, RFs& aFs)
+	{
+	LOGGSMU1("CEnhancedVoiceMailNotification::DecodeL");
+
+	CEnhancedVoiceMailBoxInformation::DecodeL(aVoiceMailInfo, aCharacterSetConverter, aFs);
+
+	TUint8 numberOfNotifications = (aVoiceMailInfo.GetL() & KSmsNotificationBitMask);
+
+	if (iExtensionIndicator)
+	    {
+	    TUint8 extensionLength = aVoiceMailInfo.GetL();
+	    aVoiceMailInfo.Inc(extensionLength);
+	    }
+
+	for (TUint8 i = 0; i < numberOfNotifications; i++)
+	    {
+	    CVoiceMailNotification* voiceMailNotification = CVoiceMailNotification::NewL();
+	    CleanupStack::PushL(voiceMailNotification);
+	    voiceMailNotification->DecodeL(aVoiceMailInfo, aCharacterSetConverter, aFs);
+	    iNotifications->AppendL(voiceMailNotification);
+	    CleanupStack::Pop(voiceMailNotification);
+	    }
+	} // CEnhancedVoiceMailNotification::DecodeL
+
+
+/**
+ *  @publishedAll
+ *  
+ *  Sets the message ID of the specific Voice Mail message
+ *  whose deletion is being confirmed.
+ *  
+ *  @param aMessageId
+ *  The message ID of the specific voice mail message whose deletion
+ *  is being confirmed.
+ *  
+ *  @capability None
+ */
+EXPORT_C void CVoiceMailDeletion::SetMessageId(TUint16 aMessageId)
+	{
+	LOGGSMU1("CVoiceMailDeletion::SetMessageId()");
+
+	iMessageId=aMessageId;
+	} // CVoiceMailDeletion::SetMessageId
+
+
+/**
+ *  @publishedAll
+ *  
+ *  Retrieves the message ID of the Voice Mail message
+ *  whose deletion is being confirmed, range 0 to 65535.
+ *  
+ *  @return
+ *  The message ID of the Voice Mail message whose deletion
+ *  is being confirmed, range 0 to 65535.
+ *  
+ *  @capability None
+ */
+EXPORT_C TUint16 CVoiceMailDeletion::MessageId() const
+	{
+	LOGGSMU1("CVoiceMailDeletion::MessageId()");
+
+	return iMessageId;
+	} // CVoiceMailDeletion::MessageId
+
+
+/**
+ *  @publishedAll
+ *  
+ *  Indicates whether the voice mail deletion contains extension bytes.
+ *  
+ *  @return
+ *  True if the voice mail deletion contains extension bytes.
+ *  False otherwise.
+ *  
+ *  @capability None
+ */
+EXPORT_C TBool CVoiceMailDeletion::MessageExtensionIndication() const
+	{
+	LOGGSMU1("CVoiceMailDeletion::MessageExtensionIndication()");
+
+	return iExtensionIndicator;
+	} // CVoiceMailDeletion::MessageExtensionIndication
+
+
+TUint8 CVoiceMailDeletion::SizeL()
+	{
+	LOGGSMU1("CVoiceMailDeletion::SizeL()");
+
+	const TUint8 KSizeOfVoiceMailDeletion = 3;
+	return KSizeOfVoiceMailDeletion;
+	} // CVoiceMailDeletion::SizeL
+
+
+TUint8* CVoiceMailDeletion::EncodeL(TUint8* aPtr) const
+	{
+	// When changes are made which affect the
+	// number of bytes encoded, this should be
+	// reflected in VoiceMailDeletion::SizeL()
+	LOGGSMU1("CVoiceMailDeletion::EncodeL");
+
+	*aPtr =  (TUint8) (iMessageId >> 8);
+	aPtr++;
+	*aPtr =  (TUint8) iMessageId;
+	aPtr++;
+	*aPtr = ((TUint8) iExtensionIndicator) << 7;
+	aPtr++;
+	return aPtr;
+	} // CVoiceMailDeletion::EncodeL
+
+
+void CVoiceMailDeletion::DecodeL(TGsmuLex8& aVoiceMailInfo)
+	{
+	LOGGSMU1("CVoiceMailDeletion::DecodeL");
+
+	iMessageId = (((TUint16) aVoiceMailInfo.GetL()) << 8) +
+	              ((TUint16) aVoiceMailInfo.GetL());
+	iExtensionIndicator =    (aVoiceMailInfo.GetL() >> 7);
+
+	if (iExtensionIndicator)
+	    {
+	    TUint8 extensionLength = aVoiceMailInfo.GetL();
+	    aVoiceMailInfo.Inc(extensionLength);
+	    }
+	} // CVoiceMailDeletion::DecodeL
+
+
+CVoiceMailDeletion::CVoiceMailDeletion()
+	{
+	iMessageId = 0;
+	iExtensionIndicator = EFalse;
+	} // CVoiceMailDeletion::CVoiceMailDeletion
+
+
+/**
+ *  @internalComponent
+ *  
+ *  Prevent clients from using the copy constructor by including it in the class definition
+ *  but making it protected and not exporting it.
+ *  
+ *  @capability None
+ */
+CVoiceMailDeletion::CVoiceMailDeletion(const CVoiceMailDeletion&)
+    {
+    // Ignore in code coverage - not intended to be used
+    BULLSEYE_OFF    
+    LOGGSMU1("CVoiceMailDeletion::CVoiceMailDeletion");
+    Panic(KGsmuPanicMethodBodyNotImplemented);
+    BULLSEYE_RESTORE
+    }
+
+/**
+ *  @internalComponent
+ *  
+ *  Prevent clients from using the equality operator by including it in the class definition
+ *  but making it protected and not exporting it.
+ *  
+ *  @capability None
+ */
+TBool CVoiceMailDeletion::operator==(const CVoiceMailDeletion&)
+    {
+    // Ignore in code coverage - not intended to be used
+    BULLSEYE_OFF    
+    LOGGSMU1("CVoiceMailDeletion::operator==");
+    Panic(KGsmuPanicMethodBodyNotImplemented);
+    return EFalse;
+    BULLSEYE_RESTORE
+    }
+
+/**
+ *  @internalComponent
+ *  
+ *  Prevent clients from using the assignment operator by including it in the class definition
+ *  but making it protected and not exporting it.
+ *  
+ *  @capability None
+ */
+void CVoiceMailDeletion::operator=(const CVoiceMailDeletion&)
+    {
+    // Ignore in code coverage - not intended to be used
+    BULLSEYE_OFF    
+    LOGGSMU1("CVoiceMailDeletion::operator=");
+    Panic(KGsmuPanicMethodBodyNotImplemented);
+    BULLSEYE_RESTORE
+    }
+
+/**
+ *  @publishedAll
+ *  
+ *  Class destructor.
+ *  
+ *  @capability None
+ */
+EXPORT_C CVoiceMailDeletion::~CVoiceMailDeletion()
+	{
+	LOGGSMU1("CVoiceMailDeletion::~CVoiceMailDeletion");
+
+	delete iExtension;
+	} // CVoiceMailDeletion::operator
+
+
+void CVoiceMailDeletion::ConstructL()
+	{
+	LOGGSMU1("CVoiceMailDeletion::ConstructL()");
+
+	NewBufferL(0);
+	} // CVoiceMailDeletion::ConstructL
+
+
+void CVoiceMailDeletion::NewBufferL(TInt aLength)
+	{
+	LOGGSMU1("CVoiceMailDeletion::NewBufferL()");
+
+	HBufC* buffer=HBufC::NewL(aLength);
+	delete iExtension;
+	iExtension=buffer;
+	iExtension->Des().SetLength(aLength);
+	iExtension->Des().FillZ();
+	} // CVoiceMailDeletion::NewBufferL
+
+
+/**
+ *  @publishedAll
+ *  
+ *  Class constructor
+ *  
+ *  @capability None
+ */
+EXPORT_C CVoiceMailDeletion* CVoiceMailDeletion::NewL()
+	{
+	LOGGSMU1("CVoiceMailDeletion::NewL()");
+
+	CVoiceMailDeletion* voiceMailDeletion=new(ELeave) CVoiceMailDeletion();
+	CleanupStack::PushL(voiceMailDeletion);
+	voiceMailDeletion->ConstructL();
+	CleanupStack::Pop(voiceMailDeletion);
+	return voiceMailDeletion;
+	} // CVoiceMailDeletion::NewL
+
+
+/*
+void CVoiceMailDeletion::SetExtension(TDesC& aExtension)
+	{
+	LOGGSMU1("CVoiceMailDeletion::SetExtension()");
+
+	TInt length=aExtension.Length();
+	NewBufferL(length);
+	iExtension->Des().Copy(aExtension);
+	} // CVoiceMailDeletion::SetExtension
+
+
+TPtrC CVoiceMailDeletion::Extension() const
+	{
+	LOGGSMU1("CVoiceMailDeletion::Extension()");
+
+	TPtrC ptr;
+	if (iExtension)
+	    ptr.Set(iExtension->Des());
+	return ptr;
+	}*/
+
+
+void CEnhancedVoiceMailDeleteConfirmations::NewExtensionL(TInt aLength)
+	{
+	LOGGSMU1("CEnhancedVoiceMailDeleteConfirmations::NewExtensionL()");
+
+	HBufC* buffer=HBufC::NewL(aLength);
+	delete iExtension;
+	iExtension=buffer;
+	iExtension->Des().SetLength(aLength);
+	iExtension->Des().FillZ();
+	} // CEnhancedVoiceMailDeleteConfirmations::NewExtensionL
+
+
+CEnhancedVoiceMailDeleteConfirmations::CEnhancedVoiceMailDeleteConfirmations() : CEnhancedVoiceMailBoxInformation(EGsmSmsVoiceMailDeleteConfirmation)
+	{
+	//NOP
+	} // CEnhancedVoiceMailDeleteConfirmations::CEnhancedVoiceMailDeleteConfirmations
+
+
+/**
+ *  @publishedAll
+ *  
+ *  Class destructor
+ *  
+ *  @capability None
+ */
+EXPORT_C  CEnhancedVoiceMailDeleteConfirmations::~CEnhancedVoiceMailDeleteConfirmations()
+	{
+	LOGGSMU1("CEnhancedVoiceMailDeleteConfirmations::~CEnhancedVoiceMailDeleteConfirmations");
+
+	delete iExtension;
+	iVoiceMailDeletions->ResetAndDestroy();
+	iVoiceMailDeletions->Close();
+	delete iVoiceMailDeletions;
+	} // CEnhancedVoiceMailDeleteConfirmations::CEnhancedVoiceMailDeleteConfirmations
+
+
+/**
+ *  @internalComponent
+ *  
+ *  Prevent clients from using the copy constructor by including it in the class definition
+ *  but making it protected and not exporting it.
+ *  
+ *  @capability None
+ */
+CEnhancedVoiceMailDeleteConfirmations::CEnhancedVoiceMailDeleteConfirmations(const CEnhancedVoiceMailDeleteConfirmations&)
+    {
+    // Ignore in code coverage - not intended to be used
+    BULLSEYE_OFF    
+    LOGGSMU1("CEnhancedVoiceMailDeleteConfirmations::CEnhancedVoiceMailDeleteConfirmations");
+    Panic(KGsmuPanicMethodBodyNotImplemented);
+    BULLSEYE_RESTORE
+    }
+
+/**
+ *  @internalComponent
+ *  
+ *  Prevent clients from using the equality operator by including it in the class definition
+ *  but making it protected and not exporting it.
+ *  
+ *  @capability None
+ */
+TBool CEnhancedVoiceMailDeleteConfirmations::operator==(const CEnhancedVoiceMailDeleteConfirmations&)
+    {
+    // Ignore in code coverage - not intended to be used
+    BULLSEYE_OFF    
+    LOGGSMU1("CEnhancedVoiceMailDeleteConfirmations::operator==");
+    Panic(KGsmuPanicMethodBodyNotImplemented);
+    return EFalse;
+    BULLSEYE_RESTORE
+    }
+
+/**
+ *  @internalComponent
+ *  
+ *  Prevent clients from using the assignment operator by including it in the class definition
+ *  but making it protected and not exporting it.
+ *  
+ *  @capability None
+ */
+void CEnhancedVoiceMailDeleteConfirmations::operator=(const CEnhancedVoiceMailDeleteConfirmations&)
+    {
+    // Ignore in code coverage - not intended to be used
+    BULLSEYE_OFF    
+    LOGGSMU1("CEnhancedVoiceMailDeleteConfirmations::operator=");
+    Panic(KGsmuPanicMethodBodyNotImplemented);
+    BULLSEYE_RESTORE
+    }
+
+void CEnhancedVoiceMailDeleteConfirmations::ConstructL()
+	{
+	LOGGSMU1("CEnhancedVoiceMailDeleteConfirmations::ConstructL()");
+
+	NewExtensionL(0);
+
+	iVoiceMailDeletions = new (ELeave) RPointerArray<CVoiceMailDeletion>(15);
+	} // CEnhancedVoiceMailDeleteConfirmations::ConstructL
+
+
+/**
+ *  @publishedAll
+ *  
+ *  Class constructor
+ *  
+ *  @capability None
+ */
+EXPORT_C  CEnhancedVoiceMailDeleteConfirmations* CEnhancedVoiceMailDeleteConfirmations::NewL()
+	{
+	LOGGSMU1("CEnhancedVoiceMailDeleteConfirmations::NewL()");
+
+	CEnhancedVoiceMailDeleteConfirmations* aCEnhancedVoiceMailDeleteConfirmations=new(ELeave) CEnhancedVoiceMailDeleteConfirmations();
+	CleanupStack::PushL(aCEnhancedVoiceMailDeleteConfirmations);
+	aCEnhancedVoiceMailDeleteConfirmations->CEnhancedVoiceMailBoxInformation::ConstructL();
+	aCEnhancedVoiceMailDeleteConfirmations->ConstructL();
+	CleanupStack::Pop(aCEnhancedVoiceMailDeleteConfirmations);
+	return aCEnhancedVoiceMailDeleteConfirmations;
+	} // CEnhancedVoiceMailDeleteConfirmations::NewL
+
+
+/**
+ *  @publishedAll
+ *  
+ *  Indicates the number of message IDs that follow in this IE.
+ *  
+ *  @return
+ *  The number of message IDs that follow.
+ *  
+ *  @capability None
+ */
+EXPORT_C TUint8  CEnhancedVoiceMailDeleteConfirmations::NumberOfDeletes()
+	{
+	LOGGSMU1("CEnhancedVoiceMailDeleteConfirmations::NumberOfDeletes()");
+
+	return iVoiceMailDeletions->Count();
+	} // CEnhancedVoiceMailDeleteConfirmations::NumberOfDeletes
+
+
+/**
+ *  @publishedAll
+ *  
+ *  Provides a reference to the collection that is used to contain the Voice Mail Deletion
+ *  notifications. Up to 31 instances of CVoiceMailDeletion can be stored. If more than
+ *  31 instances are added, the CEnhancedVoiceMailDeleteConfirmations will not be added to
+ *  the CSmsMessage.
+ *  
+ *  @return
+ *  A reference to the collection that is used to contain the Voice Mail Deletion
+ *  notifications.
+ *  
+ *  @capability None
+ */
+EXPORT_C RPointerArray<CVoiceMailDeletion>& CEnhancedVoiceMailDeleteConfirmations::GetVoiceMailDeletions()
+	{
+	LOGGSMU1("CEnhancedVoiceMailDeleteConfirmations::GetVoiceMailDeletions()");
+
+	return *iVoiceMailDeletions;
+	} // CEnhancedVoiceMailDeleteConfirmations::GetVoiceMailDeletions
+
+
+/*
+void CEnhancedVoiceMailDeleteConfirmations::SetExtension(TDesC& aExtension)
+	{
+	LOGGSMU1("CEnhancedVoiceMailDeleteConfirmations::SetExtension()");
+
+	TInt length=aExtension.Length();
+	NewBufferL(length);
+	iExtension->Des().Copy(aExtension);
+	} // CEnhancedVoiceMailDeleteConfirmations::SetExtension
+
+
+TPtrC CEnhancedVoiceMailDeleteConfirmations::Extension() const
+	{
+	LOGGSMU1("CEnhancedVoiceMailDeleteConfirmations::Extension()");
+
+	TPtrC ptr;
+	if (iExtension)
+		{
+		ptr.Set(iExtension->Des());
+		}
+	return ptr;
+	}*/
+
+
+TUint8* CEnhancedVoiceMailDeleteConfirmations::EncodeL(TUint8* aCurrentPtr, CCnvCharacterSetConverter& aCharacterSetConverter, RFs& aFs) const
+	{
+	LOGGSMU1("CEnhancedVoiceMailDeleteConfirmations::EncodeL");
+
+	TUint8* startPtr   = aCurrentPtr;
+
+	aCurrentPtr = CEnhancedVoiceMailBoxInformation::EncodeL(aCurrentPtr, aCharacterSetConverter, aFs);
+
+	TUint8 count = ((TUint8)iVoiceMailDeletions->Count());
+
+	if (count > KMaxNumberOfNotifications)
+	    {
+	    User::Leave(KErrArgument);
+	    }
+
+	*aCurrentPtr= (count & KSmsNotificationBitMask);
+	aCurrentPtr++;
+
+	TInt16 spaceAlreadyAllocated; // handle architectures whose address space increments and whose address space decrements.
+	(aCurrentPtr > startPtr) ? (spaceAlreadyAllocated = aCurrentPtr - startPtr) : (spaceAlreadyAllocated = startPtr - aCurrentPtr);
+
+	// allow space for id and length bytes
+	TInt16 remainingSize = (TInt16)(CEnhancedVoiceMailBoxInformation::KSmsMaxEnhancedVoiceMailSize - spaceAlreadyAllocated);
+
+	for (TUint i = 0; i < count; i++)
+	    {
+	    remainingSize -= (TInt16)(*iVoiceMailDeletions)[i]->SizeL();
+	    if (remainingSize < 0)
+	        {
+	        User::Leave(KErrArgument);
+	        }
+
+	    aCurrentPtr = (*iVoiceMailDeletions)[i]->EncodeL(aCurrentPtr);
+	    }
+
+	return aCurrentPtr;
+	} // CEnhancedVoiceMailDeleteConfirmations::EncodeL
+
+
+void CEnhancedVoiceMailDeleteConfirmations::DecodeL(TGsmuLex8& aVoiceMailInfo, CCnvCharacterSetConverter& aCharacterSetConverter, RFs& aFs)
+	{
+	LOGGSMU1("CEnhancedVoiceMailDeleteConfirmations::DecodeL");
+
+	CEnhancedVoiceMailBoxInformation::DecodeL(aVoiceMailInfo, aCharacterSetConverter, aFs);
+
+	TUint numberOfVMDeletions = (aVoiceMailInfo.GetL() & KSmsNotificationBitMask);
+
+	if (iExtensionIndicator)
+		{
+		TUint8 extensionLength = aVoiceMailInfo.GetL();
+		aVoiceMailInfo.Inc(extensionLength);
+		}
+
+	for (TUint8 i = 0; i < numberOfVMDeletions; i++)
+		{
+		// Create a Voice Mail Deletion
+		CVoiceMailDeletion* voiceMailDeletion = CVoiceMailDeletion::NewL();
+		CleanupStack::PushL(voiceMailDeletion);
+		voiceMailDeletion->DecodeL(aVoiceMailInfo);
+		CleanupStack::Pop(voiceMailDeletion);
+		iVoiceMailDeletions->Append(voiceMailDeletion);
+		}
+	} // CEnhancedVoiceMailDeleteConfirmations::DecodeL