smsprotocols/smsstack/gsmu/src/gsmuieoperations.cpp
branchopencode
changeset 24 6638e7f4bd8f
parent 0 3553901f7fa8
--- a/smsprotocols/smsstack/gsmu/src/gsmuieoperations.cpp	Mon May 03 13:37:20 2010 +0300
+++ b/smsprotocols/smsstack/gsmu/src/gsmuieoperations.cpp	Thu May 06 15:10:38 2010 +0100
@@ -1,1852 +1,1852 @@
-// 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:
-//
-
-#include "Gsmumain.h"
-#include "gsmuieoperations.h"
-#include "Gsmumsg.h"
-#include "gsmumsgadditionalattributes.h"
-#include "Gsmuelem.h"
-#include "smsstacklog.h"
-
-
-/**
- *  This is used by the CSmsMessage to create a CSmsIEOperation.
- *  Each instance is owned by the CSmsMessage which created it.
- *  Therefore only the CSmsMessage (GSMU component) is allowed to
- *  create and delete CSmsIEOperations.
- *  
- *  @param aId
- *  The ID for the CSmsInformationElement for whom an operation class needs to be created.
- *  @param aMessage
- *  The CSmsMessage that this operations class belongs to.
- *  @param aCharacterSetConverter
- *  A reference to a character set converter, needed by some derived operation classes.
- *  @param aFs
- *  A reference to the file server, needed by some derived operations classes.
- *  
- *  @internalComponent
- */
-CSmsIEOperation*  CSmsIEOperation::NewL(CSmsInformationElement::TSmsInformationElementIdentifier aId, CSmsMessage& aMessage, CCnvCharacterSetConverter& aCharacterSetConverter, RFs& aFs)
-	{
-	LOGGSMU1("CSmsIEOperation::NewL()");
-
-	CSmsIEOperation* iEOperation = NULL;
-
-	switch (aId)
-	    {
-	    case CSmsInformationElement::ESmsHyperLinkFormat:
-	        iEOperation = new (ELeave)  CSmsHyperLinkOperations(aId,aMessage);
-	        break;
-	    case CSmsInformationElement::ESmsReplyAddressFormat:
-	        iEOperation = new (ELeave) CSmsReplyAddressOperations(aId, aMessage, aCharacterSetConverter, aFs);
-	        break;
-	    case CSmsInformationElement::ESmsEnhanceVoiceMailInformation:
-	        iEOperation = new (ELeave) CSmsEnhancedVoiceMailOperations(aId, aMessage, aCharacterSetConverter, aFs);
-	        break;
-	    case CSmsInformationElement::ESmsIEISpecialSMSMessageIndication:
-	        iEOperation = new (ELeave)  CSmsSpecialSMSMessageOperations(aId,aMessage);
-	        break;
-	    case CSmsInformationElement::ESmsIEISMSCControlParameters:
-	        iEOperation = new (ELeave)  CSmsSMSCCtrlParameterOperations(aId,aMessage); 
-	        break;
-	    default:
-	        User::Leave(KErrArgument);
-	        break;
-	    }
-
-	iEOperation->ConstructL();
-
-	return iEOperation;
-	} // CSmsIEOperation::NewL
-
-
-/**
- *  @publishedAll
- *  
- *  Identifies the information element which is supported by this operations class.
- *  
- *  @return The information element ID supported by this operations class.
- *  @capability None
- */
-EXPORT_C CSmsInformationElement::TSmsInformationElementIdentifier CSmsIEOperation::Id() const
-	{
-	LOGGSMU1("CSmsIEOperation::Id()");
-
-	return iId;
-	} // CSmsInformationElement::TSmsInformationElementIdentifier
-
-
-/**
- *  @internalComponent
- *  
- *  Identifies whether the message type supports is supported
- *  
- *  @return True if the message type is supported. False otherwise.
- */
-TBool CSmsIEOperation::MessageTypeSupported() const
-	{
-	LOGGSMU1("CSmsIEOperation::MessageTypeSupported()");
-
-	CSmsPDU::TSmsPDUType type = iMessage.Type();
-
-    return ((type == CSmsPDU::ESmsDeliver) ||
-            (type == CSmsPDU::ESmsSubmit));
-	} // CSmsIEOperation::MessageTypeSupported
-
-
-CSmsIEOperation::CSmsIEOperation(CSmsInformationElement::TSmsInformationElementIdentifier aId, CSmsMessage& aMessage) : iId(aId), iMessage(aMessage)
-	{
-	//NOP
-	} // CSmsIEOperation::CSmsIEOperation
-
-
-/**
- *  @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 CSmsIEOperation::operator=(const CSmsIEOperation&)
-    {
-    // Ignore in code coverage - not intended to be used
-    BULLSEYE_OFF    
-    LOGGSMU1("CSmsIEOperation::operator=");
-    Panic(KGsmuPanicMethodBodyNotImplemented1);
-    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 CSmsIEOperation::operator==(const CSmsIEOperation&)
-    {
-    // Ignore in code coverage - not intended to be used
-    BULLSEYE_OFF    
-    LOGGSMU1("CSmsIEOperation::operator==");
-    Panic(KGsmuPanicMethodBodyNotImplemented1);
-    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 CSmsCtrlOperation::operator=(const CSmsCtrlOperation&)
-    {
-    // Ignore in code coverage - not intended to be used
-    BULLSEYE_OFF    
-    LOGGSMU1("CSmsCtrlOperation::operator=");
-    Panic(KGsmuPanicMethodBodyNotImplemented1);
-    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 CSmsCtrlOperation::operator==(const CSmsCtrlOperation&)
-    {
-    // Ignore in code coverage - not intended to be used
-    BULLSEYE_OFF    
-    LOGGSMU1("CSmsCtrlOperation::operator==");
-    Panic(KGsmuPanicMethodBodyNotImplemented1);
-    return EFalse;
-    BULLSEYE_RESTORE
-    }
-
-CSmsCtrlOperation::CSmsCtrlOperation(CSmsInformationElement::TSmsInformationElementIdentifier aId, CSmsMessage& aMessage) : CSmsIEOperation(aId, aMessage)
-	{
-	//NOP
-	} // CSmsCtrlOperation::CSmsCtrlOperation
-
-
-CSmsHyperLinkOperations::CSmsHyperLinkOperations(CSmsInformationElement::TSmsInformationElementIdentifier aId, CSmsMessage& aMessage) : CSmsCtrlOperation(aId, aMessage)
-	{
-	//NOP
-	} // CSmsHyperLinkOperations::CSmsHyperLinkOperations
-
-
-void CSmsIEOperation::ConstructL()
-	{
-	LOGGSMU1("CSmsIEOperation::ConstructL()");
-	} // CSmsIEOperation::ConstructL
-
-
-/**
- *  @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 CSmsHyperLinkOperations::operator=(const CSmsHyperLinkOperations&)
-    {
-    // Ignore in code coverage - not intended to be used
-    BULLSEYE_OFF    
-    LOGGSMU1("CSmsHyperLinkOperations::operator=");
-    Panic(KGsmuPanicMethodBodyNotImplemented1);
-    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 CSmsHyperLinkOperations::operator==(const CSmsHyperLinkOperations&)
-    {
-    // Ignore in code coverage - not intended to be used
-    BULLSEYE_OFF    
-    LOGGSMU1("CSmsHyperLinkOperations::operator==");
-    Panic(KGsmuPanicMethodBodyNotImplemented1);
-    return EFalse;
-    BULLSEYE_RESTORE
-    }
-
-/**
- *  @internalComponent
- *  
- *  Identifies whether the message type or version supports this operation
- *  
- *  @leave
- *  If the message type or version does not support this operation.
- */
-void CSmsHyperLinkOperations::ValidateOperationL() const
-	{
-	LOGGSMU1("CSmsHyperLinkOperations::ValidateOperationL()");
-
-	if (iMessage.Version() < CSmsMessage::ESmsMessageV1)
-	    {
-	    LOGGSMU2("CSmsHyperLinkOperations::AddHyperLinkL, Operation not supported, Msg Version %d", iMessage.Version());
-	    User::Leave(KErrNotSupported);
-	    }
-
-	if (!MessageTypeSupported())
-	    {
-	    LOGGSMU2("CSmsHyperLinkOperations::AddHyperLinkL, Operation not supported by this PDU type, type = %d", iMessage.Type());
-	    User::Leave(KErrNotSupported);
-	    }
-	} // CSmsHyperLinkOperations::ValidateOperationL
-
-
-/**
- *  @publishedAll
- *  
- *  This method adds a HyperLink to the CSmsMessage.
- *  
- *  @param aPosition
- *  The absolute character position within the message text.
- *  @param aTitle
- *  An integer representation of the number of characters in the hyperlink title.
- *  @param URL Length
- *  An integer representation of the number of characters in the URL.
- *  @leave KErrNotSupported
- *  If the message version or type does not support hyperlinks.
- *  @capability None
- */
-EXPORT_C void CSmsHyperLinkOperations::AddHyperLinkL(TUint aPosition, TUint8 aTitleLength,  TUint8  aURLLength) const
-	{
-	LOGGSMU1("CSmsHyperLinkOperations::AddHyperLinkL()");
-
-	ValidateOperationL();
-
-	CSmsMessageAdditionalAttributes& additionalAttributes = *((CSmsMessageAdditionalAttributes*) iMessage.AdditionalInfo());
-
-	TBuf8 <4> buffer;
-	buffer.SetLength(4);
-	buffer[0] = (TUint8) (aPosition >> 8); // lowest octet contains the
-	buffer[1] = (TUint8)  aPosition;       // most significant bits
-	buffer[2] = aTitleLength;
-	buffer[3] = aURLLength;
-
-	CSmsInformationElement* iE = CSmsInformationElement::NewL(CSmsInformationElement::ESmsHyperLinkFormat, buffer);
-	CleanupStack::PushL(iE);
-	additionalAttributes.AddControlInformationElementL(iE);
-	CleanupStack::Pop(iE);
-	} // CSmsHyperLinkOperations::AddHyperLinkL
-
-
-/**
- *  @publishedAll
- *  
- *  Returns the number of Hyper Link IEs contained in this message.
- *  @leave KErrNotSupported
- *  If this functionality is not supported by this version or type of message.
- *  @return
- *  The number of hyper links contained in this message.
- *  @capability None
- */
-EXPORT_C TUint CSmsHyperLinkOperations::NumberOfHyperLinksL() const
-	{
-	LOGGSMU1("CSmsHyperLinkOperations::NumberOfHyperLinks");
-
-	ValidateOperationL();
-
-	TUint numberOfHyperLinks = 0;
-
-	TSmsInformationElementCategories::TInformationElementCategory category;
-
-	if (TSmsInformationElementCategories::GetCategoryDefinition(CSmsInformationElement::ESmsHyperLinkFormat, category) == EFalse)
-			{
-		User::Leave(KErrArgument);
-		}
-
-	CSmsMessageAdditionalAttributes* additionalAttributes = (CSmsMessageAdditionalAttributes*) iMessage.AdditionalInfo();
-	TUint numberOfElements = additionalAttributes->NumberOfControlInformationElements(category);
-
-	for (TUint i = 0; i < numberOfElements; i++)
-	    {
-	    CSmsInformationElement::TSmsInformationElementIdentifier id = CSmsInformationElement::ESmsIEMaximum;
-	    
-	    // If function leaves, allow the error to propagate upwards
-	    id = additionalAttributes->GetControlInformationElementL(category, i).Identifier();
-
-	    if (id == CSmsInformationElement::ESmsHyperLinkFormat)
-	        {
-	        numberOfHyperLinks++;
-	        }
-	    }
-
-	return numberOfHyperLinks;
-	} // CSmsHyperLinkOperations::NumberOfHyperLinksL
-
-
-/**
- *  @publishedAll
- *  
- *  Copies the attributes of the specified hyperlink.
- *  aIndex has the range [0..[n-1]] where n is the
- *  value returned by NumberOfHyperLinks()
- *  
- *  @param aIndex
- *  Identifies the hyperlink to extract. Has the range [0..[n-1]]
- *  where n is the value returned by NumberOfHyperLinks().
- *  @param &aPosition
- *  The absolute character position within the message text.
- *  @param &aTitleLength
- *  An integer representation of the number of characters in the hyperlink title.
- *  @param &aURLLength
- *  An integer representation of the number of characters in the URL.
- *  @leave KErrNotSupported
- *  If the message version or type does not support hyperlinks.
- *  @leave KErrArgument
- *  If aIndex is out of range.
- *  @capability None
- */
-EXPORT_C void  CSmsHyperLinkOperations::CopyHyperLinkAtIndexL(TUint aIndex, TUint& aPosition, TUint8& aTitleLength,  TUint8&  aURLLength) const
-	{
-	LOGGSMU2("CSmsHyperLinkOperations::CopyHyperLinkAtIndexL(): aIndex=%d", aIndex);
-
-	ValidateOperationL();
-
-	TUint numberOfHyperLinks = 0;
-
-	TSmsInformationElementCategories::TInformationElementCategory category;
-	if (TSmsInformationElementCategories::GetCategoryDefinition(CSmsInformationElement::ESmsHyperLinkFormat, category) == EFalse)
-		{
-		User::Leave(KErrArgument);
-		}
-
-	CSmsMessageAdditionalAttributes* additionalAttributes = (CSmsMessageAdditionalAttributes*) iMessage.AdditionalInfo();
-	TUint numberOfElements = additionalAttributes->NumberOfControlInformationElements(category);
-
-	if (aIndex >= numberOfElements)
-	    {
-	    User::Leave(KErrArgument);
-	    }
-
-	for (TUint i = 0; i < numberOfElements; i++)
-	    {
-	    CSmsInformationElement::TSmsInformationElementIdentifier id = CSmsInformationElement::ESmsIEMaximum;
-	    
-	    // If function leaves, allow the error to propagate upwards
-	    id = additionalAttributes->GetControlInformationElementL(category, i).Identifier();
-
-	    if ((id == CSmsInformationElement::ESmsHyperLinkFormat) &&
-	        (numberOfHyperLinks++ == aIndex))
-	        {
-	        aPosition     = (additionalAttributes->GetControlInformationElementL(category, i).Data()[0] << 8);
-	        aPosition    +=  additionalAttributes->GetControlInformationElementL(category, i).Data()[1];
-
-	        aTitleLength = additionalAttributes->GetControlInformationElementL(category, i).Data()[2];
-	        aURLLength   = additionalAttributes->GetControlInformationElementL(category, i).Data()[3];
-	        break;
-	        }
-	    }
-	} // CSmsHyperLinkOperations::CopyHyperLinkAtIndexL
-
-
-/**
- *  @publishedAll
- *  
- *  Removes all hyper Link IEs contained in this message.
- *  
- *  @leave KErrNotSupported
- *  If the message version or type does not support hyperlinks.
- *  @capability None
- */
-EXPORT_C void  CSmsHyperLinkOperations::RemoveAllHyperLinksL() const
-	{
-	LOGGSMU1("CSmsHyperLinkOperations::RemoveAllHyperLinks");
-
-	ValidateOperationL();
-
-	TSmsInformationElementCategories::TInformationElementCategory category;
-
-	if (TSmsInformationElementCategories::GetCategoryDefinition(CSmsInformationElement::ESmsHyperLinkFormat, category) == EFalse)
-		{
-		User::Leave(KErrArgument);
-		}
-
-	CSmsMessageAdditionalAttributes* additionalAttributes = (CSmsMessageAdditionalAttributes*) iMessage.AdditionalInfo();
-	TUint i = additionalAttributes->NumberOfControlInformationElements(category);
-
-	while (i-- != 0)
-	    {
-	    CSmsInformationElement::TSmsInformationElementIdentifier id = CSmsInformationElement::ESmsIEMaximum;
-	    
-	    // If function leaves, allow the error to propagate upwards
-	    id = additionalAttributes->GetControlInformationElementL(category, i).Identifier();
-
-	    if (id == CSmsInformationElement::ESmsHyperLinkFormat)
-	        {
-	        additionalAttributes->DeleteControlInformationElement(category, i);
-	        }
-	    }
-	} // CSmsHyperLinkOperations::RemoveAllHyperLinksL
-
-
-/**
- *  @publishedAll
- *  
- *  Removes the indexed hyperlink from this message.
- *  
- *  @param aIndex
- *  aIndex has the range [0..[n-1]] where n is the
- *  value returned by NumberOfHyperLinks()
- *  @leave KErrNotSupported
- *  If the message version or type does not support hyperlinks.
- *  @leave KErrArgument
- *  If the index is out of range.
- *  @capability None
- */
-EXPORT_C void  CSmsHyperLinkOperations::RemoveHyperLinkL(TUint aIndex) const
-	{
-	LOGGSMU1("CSmsHyperLinkOperations::RemoveHyperLink");
-
-	ValidateOperationL();
-
-	TUint numberOfHyperLinks = 0;
-
-	TSmsInformationElementCategories::TInformationElementCategory category;
-
-	if (TSmsInformationElementCategories::GetCategoryDefinition(CSmsInformationElement::ESmsHyperLinkFormat, category) == EFalse)
-		{
-		User::Leave(KErrArgument);
-		}
-
-	CSmsMessageAdditionalAttributes* additionalAttributes = (CSmsMessageAdditionalAttributes*) iMessage.AdditionalInfo();
-	TUint numberOfElements = additionalAttributes->NumberOfControlInformationElements(category);
-
-	if (aIndex >= numberOfElements)
-	    {
-	    User::Leave(KErrArgument);
-	    }
-
-	for (TUint i = 0; i < numberOfElements; i++)
-	    {
-	    CSmsInformationElement::TSmsInformationElementIdentifier id = CSmsInformationElement::ESmsIEMaximum;
-
-	    // If function leaves, allow the error to propagate upwards
-	    id = additionalAttributes->GetControlInformationElementL(category, i).Identifier();
-
-	    if ((id == CSmsInformationElement::ESmsHyperLinkFormat) &&
-	        (numberOfHyperLinks++ == aIndex))
-	        {
-	        additionalAttributes->DeleteControlInformationElement(category, i);
-	        break;
-	        }
-	    }
-	} // CSmsHyperLinkOperations::RemoveHyperLinkL
-
-
-/**
- *  @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 CSmsReplyAddressOperations::operator=(const CSmsReplyAddressOperations&)
-    {
-    // Ignore in code coverage - not intended to be used
-    BULLSEYE_OFF    
-    LOGGSMU1("CSmsReplyAddressOperations::operator=");
-    Panic(KGsmuPanicMethodBodyNotImplemented1);
-    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 CSmsReplyAddressOperations::operator==(const CSmsReplyAddressOperations&)
-    {
-    // Ignore in code coverage - not intended to be used
-    BULLSEYE_OFF    
-    LOGGSMU1("CSmsReplyAddressOperations::operator==");
-    Panic(KGsmuPanicMethodBodyNotImplemented1);
-    return EFalse;
-    BULLSEYE_RESTORE
-    }
-
-/**
- *  @internalComponent
- *  
- *  Identifies whether the message type or version supports this operation
- *  
- *  @leave
- *  If the message type or version does not support this operation.
- */
-void CSmsReplyAddressOperations::ValidateOperationL() const
-	{
-	LOGGSMU1("CSmsReplyAddressOperations::ValidateOperationL()");
-
-	if (iMessage.Version() < CSmsMessage::ESmsMessageV1)
-	    {
-	    LOGGSMU2("CSmsReplyAddressOperations::AddReplyAddressL, Operation not supported, Msg Version %d", iMessage.Version());
-	    User::Leave(KErrNotSupported);
-	    }
-
-	if (!MessageTypeSupported())
-	    {
-	    LOGGSMU2("CSmsReplyAddressOperations::AddReplyAddressL, Operation not supported by this PDU type, type = %d", iMessage.Type());
-	    User::Leave(KErrNotSupported);
-	    }
-	} // CSmsReplyAddressOperations::ValidateOperationL
-
-
-/**
- *  @publishedAll
- *  
- *  Adds a reply address information element.
- *  
- *  @param aAddress
- *  The international number to be used in the reply address.
- *  @leave KErrNotSupported
- *  If the message version or type does not support a reply addresses.
- *  @leave KErrAlreadyExists
- *  If the message already contains a reply address.
- *  @capability None
- */
-EXPORT_C void  CSmsReplyAddressOperations::AddReplyAddressL(const TDesC& aAddress) const
-	{
-	LOGGSMU1("CSmsReplyAddressOperations::AddReplyAddressL()");
-
-	ValidateOperationL();
-
-	if (ContainsReplyAddressIEL())
-	    {
-	    LOGGSMU1("CSmsReplyAddressOperations::AddReplyAddressL, Already Exists");
-	    User::Leave(KErrAlreadyExists);
-	    }
-
-	CSmsMessageAdditionalAttributes& additionalAttributes = *((CSmsMessageAdditionalAttributes*) iMessage.AdditionalInfo());
-
-	CSmsAddress* address = CSmsAddress::NewL(iCharacterSetConverter,iFs); // needed for encoding the address into the IE.
-	CleanupStack::PushL(address);
-	address->SetAddressL(aAddress);
-	TBuf8<CSmsAddress::KSmsAddressMaxAddressLength> addressBuffer;
-	addressBuffer.SetLength(CSmsAddress::KSmsAddressMaxAddressLength);
-	TUint8* startPtr = &addressBuffer[0];
-	TUint8* endPtr = address->EncodeL(startPtr);
-	TInt length = 0;
-	(endPtr > startPtr) ? (length = endPtr - startPtr) : (length = startPtr - endPtr);
-	addressBuffer.SetLength(length);
-	CleanupStack::PopAndDestroy(address);
-
-	CSmsInformationElement* iE = CSmsInformationElement::NewL(CSmsInformationElement::ESmsReplyAddressFormat, addressBuffer);
-	CleanupStack::PushL(iE);
-	additionalAttributes.AddControlInformationElementL(iE);
-	CleanupStack::Pop(iE);
-	} // CSmsReplyAddressOperations::AddReplyAddressL
-
-
-/**
- *  @publishedAll
- *  
- *  Adds a reply address information element.
- *  
- *  @param aAddress
- *  Sets To and From addresses in ETSI format.
- *  @leave KErrNotSupported
- *  If the message version or type does not support a reply addresses.
- *  @leave KErrAlreadyExists
- *  If the message already contains a reply address.
- *  @capability None
- */
-EXPORT_C void  CSmsReplyAddressOperations::AddParsedReplyAddressL(const TGsmSmsTelNumber& aParsedAddress) const
-	{
-	LOGGSMU1("CSmsReplyAddressOperations::AddParsedReplyAddressL");
-
-	ValidateOperationL();
-
-	if (ContainsReplyAddressIEL())
-	    {
-	    LOGGSMU1("CSmsReplyAddressOperations::AddParsedReplyAddressL, Already Exists");
-	    User::Leave(KErrAlreadyExists);
-	    }
-
-	CSmsMessageAdditionalAttributes& additionalAttributes = *((CSmsMessageAdditionalAttributes*) iMessage.AdditionalInfo());
-
-	CSmsAddress* address = CSmsAddress::NewL(iCharacterSetConverter,iFs);
-	CleanupStack::PushL(address);
-	address->SetParsedAddressL(aParsedAddress);
-	TBuf8<CSmsAddress::KSmsAddressMaxAddressLength> addressBuffer;
-	addressBuffer.SetLength(CSmsAddress::KSmsAddressMaxAddressLength);
-	TUint8* startPtr = &addressBuffer[0];
-	TUint8* endPtr = address->EncodeL(startPtr);
-	TInt length = 0;
-	(endPtr > startPtr) ? (length = endPtr - startPtr) : (length = startPtr - endPtr);
-	addressBuffer.SetLength(length);
-	CleanupStack::PopAndDestroy(address);
-
-	CSmsInformationElement* iE = CSmsInformationElement::NewL(CSmsInformationElement::ESmsReplyAddressFormat, addressBuffer);
-	CleanupStack::PushL(iE);
-	additionalAttributes.AddControlInformationElementL(iE);
-	CleanupStack::Pop(iE);
-	} // CSmsReplyAddressOperations::AddParsedReplyAddressL
-
-
-/**
- *  @publishedAll
- *  
- *  Identifies whether a reply address has already been added to this
- *  CSmsMessage using the CSmsReplyAddressOperations interface.
- *  
- *  @return
- *  True if the reply address has already been added using this interface.
- *  @leave KErrNotSupported
- *  If the message version or type does not support this query.
- *  @capability None
- */
-EXPORT_C TBool CSmsReplyAddressOperations::ContainsReplyAddressIEL() const
-	{
-	LOGGSMU1("CSmsReplyAddressOperations::ContainsReplyAddressIEL()");
-
-	TBool rc = EFalse;
-
-	ValidateOperationL();
-
-	TSmsInformationElementCategories::TInformationElementCategory category;
-
-	if (TSmsInformationElementCategories::GetCategoryDefinition(CSmsInformationElement::ESmsReplyAddressFormat, category) == EFalse)
-		{
-		User::Leave(KErrArgument);
-		}
-
-	CSmsMessageAdditionalAttributes* additionalAttributes = (CSmsMessageAdditionalAttributes*) iMessage.AdditionalInfo();
-	TUint numberOfElements = additionalAttributes->NumberOfControlInformationElements(category);
-
-	for (TUint i = 0; i < numberOfElements; i++)
-	    {
-	    CSmsInformationElement::TSmsInformationElementIdentifier id = CSmsInformationElement::ESmsIEMaximum;
-	    
-	    // If function leaves, allow the error to propagate upwards
-	    id = additionalAttributes->GetControlInformationElementL(category, i).Identifier();
-
-	    if (id == CSmsInformationElement::ESmsReplyAddressFormat)
-	        {
-	        rc = ETrue;
-	        break;
-	        }
-	    }
-
-	return rc;
-	} // CSmsReplyAddressOperations::ContainsReplyAddressIEL
-
-
-/**
- *  @publishedAll
- *  
- *  Returns the reply address as an international number
- *  
- *  @return
- *  The reply address as an international number.
- *  @leave KErrNotSupported
- *  If the message version or type does not support this query.
- *  @leave KErrNotFound
- *  If the message does not contain a reply address information element.
- *  @leave KErrCorrupt
- *  If the reply address is corrupt
- *  @capability None
- */
-EXPORT_C HBufC* CSmsReplyAddressOperations::GetReplyAddressL() const
-	{
-	LOGGSMU1("CSmsReplyAddressOperations::GetReplyAddressL");
-
-	ValidateOperationL();
-
-	TBool found = EFalse;
-
-	CSmsAddress* address = CSmsAddress::NewL(iCharacterSetConverter,iFs);
-	CleanupStack::PushL(address);
-
-	TSmsInformationElementCategories::TInformationElementCategory category;
-
-	if (TSmsInformationElementCategories::GetCategoryDefinition(CSmsInformationElement::ESmsReplyAddressFormat, category) == EFalse)
-		{
-		User::Leave(KErrArgument);
-		}
-
-	CSmsMessageAdditionalAttributes* additionalAttributes = (CSmsMessageAdditionalAttributes*) iMessage.AdditionalInfo();
-	TUint numberOfElements = additionalAttributes->NumberOfControlInformationElements(category);
-
-	for (TUint i = 0; i < numberOfElements; i++)
-	    {
-	    CSmsInformationElement::TSmsInformationElementIdentifier id = CSmsInformationElement::ESmsIEMaximum;
-	    
-	    // If function leaves, allow the error to propagate upwards
-	    id = additionalAttributes->GetControlInformationElementL(category, i).Identifier();
-
-	    if (id == CSmsInformationElement::ESmsReplyAddressFormat)
-	        {
-	        TGsmuLex8 encodedAddress(additionalAttributes->GetControlInformationElementL(category, i).Data());
-	        TRAPD(err,address->DecodeL(encodedAddress));
-
-	        if (err == KErrNone)
-	            {
-	            found = ETrue;
-	            break;
-	            }
-	        else
-	            {
-	            User::Leave(KErrCorrupt);
-	            }
-	        }
-	    }
-
-	HBufC* buf = NULL;
-	if (found)
-	    {
-	    buf = HBufC::NewL(TGsmSmsTelNumberMaxLen); // 20 characters preceeded by '+'
-	    *buf = address->Address();
-	    }
-	else
-	    {
-	    User::Leave(KErrNotFound);
-	    }
-
-	CleanupStack::PopAndDestroy(address);
-
-	return buf;
-	} // CSmsReplyAddressOperations::GetReplyAddressL
-
-
-/**
- *  @publishedAll
- *  
- *  Returns the reply address in ETSI format.
- *  
- *  @return
- *  True, if the CSmsMessage contains a reply address.
- *  False, otherwise
- *  @leave KErrNotSupported
- *  If the message version or type does not support this query.
- *  @leave KErrCorrupt
- *  If the reply address is corrupt
- *  @capability None
- */
-EXPORT_C TInt  CSmsReplyAddressOperations::GetParsedReplyAddressL(TGsmSmsTelNumber& aParsedAddress) const
-	{
-	LOGGSMU1("CSmsReplyAddressOperations::GetParsedReplyAddressL");
-
-	ValidateOperationL();
-
-	TBool rc = EFalse;
-
-	CSmsAddress* address = CSmsAddress::NewL(iCharacterSetConverter,iFs);
-	CleanupStack::PushL(address);
-
-	TSmsInformationElementCategories::TInformationElementCategory category;
-
-	if (TSmsInformationElementCategories::GetCategoryDefinition(CSmsInformationElement::ESmsReplyAddressFormat, category) == EFalse)
-		{
-		User::Leave(KErrArgument);
-		}
-
-	CSmsMessageAdditionalAttributes* additionalAttributes = (CSmsMessageAdditionalAttributes*) iMessage.AdditionalInfo();
-	TUint numberOfElements = additionalAttributes->NumberOfControlInformationElements(category);
-
-	for (TUint i = 0; i < numberOfElements; i++)
-	    {
-	    CSmsInformationElement::TSmsInformationElementIdentifier id = CSmsInformationElement::ESmsIEMaximum;
-	    
-	    // If function leaves, allow the error to propagate upwards
-	    id = additionalAttributes->GetControlInformationElementL(category, i).Identifier();
-
-	    // CSmsAddress is used here for encoding the reply address into an IE.
-	    // It also used to encode the source / destination address in the CSmsMessage.
-	    // 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.
-	    if (id == CSmsInformationElement::ESmsReplyAddressFormat)
-	        {
-	        TBuf8<CSmsAddress::KSmsAddressMaxAddressLength> data;
-	        data = additionalAttributes->GetControlInformationElementL(category, i).Data();
-	        TUint8 actualDataLength = data.Length();
-	        data.SetLength(CSmsAddress::KSmsAddressMaxAddressLength);
-	        for (TUint8 j = actualDataLength; j < CSmsAddress::KSmsAddressMaxAddressLength; j++)
-	            {
-	            data[j] = 0;
-	            }
-
-	        TGsmuLex8 encodedAddress(data);
-	        TRAPD(err,address->DecodeL(encodedAddress));
-	        if (err==KErrNone)
-	            {
-	            address->ParsedAddress(aParsedAddress);
-	            rc = ETrue;
-	            break;
-	            }
-	        else
-	            {
-	            User::Leave(KErrCorrupt);
-	            }
-	        }
-	    }
-
-	CleanupStack::PopAndDestroy(address);
-
-	return rc;
-	} // CSmsReplyAddressOperations::GetParsedReplyAddressL
-
-
-/**
- *  @publishedAll
- *  
- *  Removes the reply address information element.
- *  
- *  @leave KErrNotSupported
- *  If the message version or type does not support this query.
- *  @capability None
- */
-EXPORT_C void  CSmsReplyAddressOperations::RemoveReplyAddressL() const
-	{
-	LOGGSMU1("CSmsReplyAddressOperations::RemoveReplyAddress");
-
-	ValidateOperationL();
-
-	TSmsInformationElementCategories::TInformationElementCategory category;
-
-	if (TSmsInformationElementCategories::GetCategoryDefinition(CSmsInformationElement::ESmsReplyAddressFormat, category) == EFalse)
-		{
-		User::Leave(KErrArgument);
-		}
-
-	CSmsMessageAdditionalAttributes* additionalAttributes = (CSmsMessageAdditionalAttributes*) iMessage.AdditionalInfo();
-	TUint numberOfElements = additionalAttributes->NumberOfControlInformationElements(category);
-
-	for (TInt i = 0; i < numberOfElements; i++)
-	    {
-	    CSmsInformationElement::TSmsInformationElementIdentifier id = CSmsInformationElement::ESmsIEMaximum;
-	    
-	    // If function leaves, allow the error to propagate upwards
-	    id = additionalAttributes->GetControlInformationElementL(category, i).Identifier();
-
-	    if (id == CSmsInformationElement::ESmsReplyAddressFormat)
-	        {
-	        additionalAttributes->DeleteControlInformationElement(category, i);
-	        break;
-	        }
-	    }
-	} // CSmsReplyAddressOperations::RemoveReplyAddressL
-
-
-CSmsReplyAddressOperations::CSmsReplyAddressOperations(CSmsInformationElement::TSmsInformationElementIdentifier aId,  CSmsMessage& aMessage,
-                                                       CCnvCharacterSetConverter& aCharacterSetConverter, RFs& aFs) : CSmsCtrlOperation(aId, aMessage),
-                                                       iCharacterSetConverter(aCharacterSetConverter), iFs(aFs)
-	{
-	//NOP
-	} // CSmsReplyAddressOperations::CSmsReplyAddressOperations
-
-
-/**
- *  @internalComponent
- *  
- *  Identifies whether the message type or version supports this operation
- *  
- *  @leave
- *  If the message type or version does not support this operation.
- */
-void CSmsSpecialSMSMessageOperations::ValidateOperationL() const
-	{
-	LOGGSMU1("CSmsSpecialSMSMessageOperations::ValidateOperationL()");
-
-	if (iMessage.Version() < CSmsMessage::ESmsMessageV1)
-	    {
-	    LOGGSMU2("CSmsSpecialSMSMessageOperations::AddSpecialMessageIndicationL, Operation not supported, version %d", iMessage.Version());
-	    User::Leave(KErrNotSupported);
-	    }
-
-	if (!MessageTypeSupported())
-	    {
-	    LOGGSMU2("CSmsSpecialSMSMessageOperations::AddSpecialMessageIndicationL, Operation not supported by this PDU type, type = %d", iMessage.Type());
-	    User::Leave(KErrNotSupported);
-	    }
-	} // CSmsSpecialSMSMessageOperations::ValidateOperationL
-
-
-/**
- *  @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 CSmsSpecialSMSMessageOperations::operator=(const CSmsSpecialSMSMessageOperations&)
-    {
-    // Ignore in code coverage - not intended to be used
-    BULLSEYE_OFF    
-    LOGGSMU1("CSmsSpecialSMSMessageOperations::operator=");
-    Panic(KGsmuPanicMethodBodyNotImplemented1);
-    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 CSmsSpecialSMSMessageOperations::operator==(const CSmsSpecialSMSMessageOperations&)
-	{
-	LOGGSMU1("CSmsSpecialSMSMessageOperations::operator==");
-	Panic(KGsmuPanicMethodBodyNotImplemented1);
-	return EFalse;
-	} // CSmsSpecialSMSMessageOperations::operator
-
-
-/**
- *  @publishedAll
- *  
- *  Either adds a new or updates an existing special message indication information element.
- *  
- *  @param aStore
- *  Indicates whether or not the message shall be stored.
- *  @param aMessageIndicationType
- *  Indicates the basic message type
- *  @param aExtendedType
- *  Indicates the extended message type
- *  @param aProfile
- *  Indicates the profile ID of the Multiple Subscriber Profile
- *  @param aMessageCount
- *  Indicates the number of messages of the type specified in Octet 1 that are waiting
- *  @leave KErrNotSupported
- *  If the message version or type does not support this query.
- *  @capability None
- */
-EXPORT_C void CSmsSpecialSMSMessageOperations::AddSpecialMessageIndicationL(TBool aStore,
-                                                                            TSmsMessageIndicationType aMessageIndicationType,
-                                                                            TExtendedSmsIndicationType aExtendedType,
-                                                                            TSmsMessageProfileType aProfile,
-                                                                            TUint8 aMessageCount) const
-	{
-	LOGGSMU1("CSmsSpecialSMSMessageOperations::AddSpecialMessageIndicationL");
-
-	ValidateOperationL();
-
-	CSmsUserData& userData = iMessage.SmsPDU().UserData();
-
-	TBuf8<2> data;
-	data.SetLength(2);
-
-	data[0] = ( ((TUint8) aMessageIndicationType) +
-	            ((TUint8) (aExtendedType << 2))   +
-	            ((TUint8) (aProfile      << 5))   +
-	            ((TUint8) (aStore        << 7)) );
-
-	data[1] = aMessageCount;
-
-	CArrayFixFlat<TInt>* indices = new(ELeave) CArrayFixFlat<TInt>(4);
-	CleanupStack::PushL(indices);
-	userData.InformationElementIndicesL(CSmsInformationElement::ESmsIEISpecialSMSMessageIndication, *indices);
-
-	TBool found = EFalse;
-	TInt count = indices->Count();
-	for (TInt i=0; ((i<count) && (found==EFalse)); i++)
-	    {
-		TUint index = indices->operator[](i);
-		CSmsInformationElement& ieAlreadyInWorkingPDU = userData.InformationElement(index);
-
-	    if (ieAlreadyInWorkingPDU.Data()[0] == data[0])
-	        {
-	        ieAlreadyInWorkingPDU.Data()[1] = data[1];
-	        found = ETrue;
-	        break;
-	        }
-	    }
-	CleanupStack::PopAndDestroy(indices);
-
-	if (found == EFalse)
-	    {
-	    userData.AddInformationElementL(CSmsInformationElement::ESmsIEISpecialSMSMessageIndication,data);
-	    }
-	} // CSmsSpecialSMSMessageOperations::AddSpecialMessageIndicationL
-
-
-/**
- *  @publishedAll
- *  
- *  Gets a count of the number of special message indication information elements which
- *  are stored inside the user data.
- *  
- *  @return The number of special message indication information elements which
- *  are stored inside the user data.
- *  @leave KErrNotSupported
- *  If the message version or type does not support this query.
- *  @capability None
- */
-EXPORT_C TUint CSmsSpecialSMSMessageOperations::GetCountOfSpecialMessageIndicationsL() const
-	{
-	LOGGSMU1("CSmsSpecialSMSMessageOperations::GetCountOfSpecialMessageIndicationsL()");
-
-	ValidateOperationL();
-
-	CSmsUserData& userData = iMessage.SmsPDU().UserData();
-
-	CArrayFixFlat<TInt>* indices = new (ELeave) CArrayFixFlat<TInt>(8);
-	CleanupStack::PushL(indices);
-	userData.InformationElementIndicesL(CSmsInformationElement::ESmsIEISpecialSMSMessageIndication,*indices);
-	TUint  count = indices->Count();
-	CleanupStack::PopAndDestroy(indices);
-
-	return count;
-	} // CSmsSpecialSMSMessageOperations::GetCountOfSpecialMessageIndicationsL
-
-
-/**
- *  @publishedAll
- *  
- *  Gets the attributes of the Special Message Indication specified by aIndex.
- *  
- *  @param aIndex
- *  aIndex is a value less than GetCountOfSpecialMessageIndications().
- *  @param aStore
- *  Indicates whether or not the message shall be stored.
- *  @param aMessageIndicationType
- *  Indicates the basic message type
- *  @param aExtendedType
- *  Indicates the extended message type
- *  @param aProfile
- *  Indicates the profile ID of the Multiple Subscriber Profile
- *  @param aMessageCount
- *  Indicates the number of messages of the type specified in Octet 1 that are waiting
- *  @leave KErrNotSupported
- *  If the message version or type does not support this query.
- *  @leave KErrArgument
- *  If aIndex is >= GetCountOfSpecialMessageIndications()
- *  @capability None
- */
-EXPORT_C void CSmsSpecialSMSMessageOperations::GetMessageIndicationIEL(TUint aIndex,
-                                                                       TBool& aStore,
-                                                                       TSmsMessageIndicationType& aMessageIndicationType,
-                                                                       TExtendedSmsIndicationType& aExtendedType,
-                                                                       TSmsMessageProfileType&  aProfile,
-                                                                       TUint8& aMessageCount) const
-	{
-	LOGGSMU1("CSmsSpecialSMSMessageOperations::GetMessageIndicationIEL()");
-
-	ValidateOperationL();
-
-	CSmsUserData& userData = iMessage.SmsPDU().UserData();
-
-	CArrayFixFlat<TInt>* indices = new (ELeave) CArrayFixFlat<TInt>(8);
-	CleanupStack::PushL(indices);
-	userData.InformationElementIndicesL(CSmsInformationElement::ESmsIEISpecialSMSMessageIndication,*indices);
-
-	if (aIndex < indices->Count())
-	    {
-	    CSmsInformationElement& informationElement = userData.InformationElement((*indices)[aIndex]);
-
-	    aMessageIndicationType =  (TSmsMessageIndicationType)   (informationElement.Data()[0]       & 0x03);
-	    aExtendedType          =  (TExtendedSmsIndicationType) ((informationElement.Data()[0] >> 2) & 0x07);
-	    aProfile               =  (TSmsMessageProfileType)     ((informationElement.Data()[0] >> 5) & 0x03);
-	    aStore                 =  (TBool)                      ((informationElement.Data()[0] >> 7) & 0x01);
-	    aMessageCount          =  (TUint8)                      (informationElement.Data()[1]);
-	    }
-	else
-	    {
-	    User::Leave(KErrArgument);
-	    }
-
-	CleanupStack::PopAndDestroy(indices);
-	} // CSmsSpecialSMSMessageOperations::GetMessageIndicationIEL
-
-
-/**
- *  @publishedAll
- *  
- *  Removes the Special Message Indication specified by the input attributes, provided it exists.
- *  
- *  @param aMessageIndicationType
- *  Indicates the basic message type
- *  @param aExtendedType
- *  Indicates the extended message type
- *  @leave KErrNotSupported
- *  If the message version or type does not support this query.
- *  @capability None
- */
-EXPORT_C void CSmsSpecialSMSMessageOperations::RemoveSpecialMessageIndicationL(TSmsMessageIndicationType aMessageIndicationType, TExtendedSmsIndicationType aExtendedType) const
-	{
-	LOGGSMU1("CSmsSpecialSMSMessageOperations::RemoveAllSpecialMessageIndications");
-
-	ValidateOperationL();
-
-	CSmsUserData& userData = iMessage.SmsPDU().UserData();
-
-	CArrayFixFlat<TInt>* indices = new (ELeave) CArrayFixFlat<TInt>(8);
-	CleanupStack::PushL(indices);
-	userData.InformationElementIndicesL(CSmsInformationElement::ESmsIEISpecialSMSMessageIndication,*indices);
-
-	TUint i = indices->Count();
-
-	while (i-- != 0)
-	    {
-	    CSmsInformationElement& informationElement = userData.InformationElement((*indices)[i]);
-
-	    TSmsMessageIndicationType          type = ((TSmsMessageIndicationType)   (informationElement.Data()[0]       & 0x03));
-	    TExtendedSmsIndicationType extendedType =  (TExtendedSmsIndicationType) ((informationElement.Data()[0] >> 2) & 0x07);
-
-	    if ( (aMessageIndicationType == type) &&
-	         (aExtendedType == extendedType) )
-	        {
-	        userData.RemoveInformationElement((*indices)[i]);
-	        break;
-	        }
-	    }
-
-	CleanupStack::PopAndDestroy(indices);
-	} // CSmsSpecialSMSMessageOperations::RemoveSpecialMessageIndicationL
-
-
-/**
- *  @publishedAll
- *  
- *  Removes all Special Message Indications Information Elements contained in the message.
- *  
- *  @leave KErrNotSupported
- *  If the message version or type does not support this query.
- *  @capability None
- */
-EXPORT_C void CSmsSpecialSMSMessageOperations::RemoveAllSpecialMessageIndicationsL() const
-	{
-	LOGGSMU1("CSmsSpecialSMSMessageOperations::RemoveAllSpecialMessageIndicationsL");
-
-	ValidateOperationL();
-
-	CSmsUserData& userData = iMessage.SmsPDU().UserData();
-
-	CArrayFixFlat<TInt>* indices = new (ELeave) CArrayFixFlat<TInt>(8);
-	CleanupStack::PushL(indices);
-	userData.InformationElementIndicesL(CSmsInformationElement::ESmsIEISpecialSMSMessageIndication,*indices);
-
-	TUint i = indices->Count();
-
-	while (i-- != 0)
-	   {
-	   userData.RemoveInformationElement((*indices)[i]);
-	   }
-
-	CleanupStack::PopAndDestroy(indices);
-	} // CSmsSpecialSMSMessageOperations::RemoveAllSpecialMessageIndicationsL
-
-
-CSmsSpecialSMSMessageOperations::CSmsSpecialSMSMessageOperations(CSmsInformationElement::TSmsInformationElementIdentifier aId, CSmsMessage& aMessage) : CSmsCtrlOperation(aId, aMessage)
-	{
-	//NOP
-	} // CSmsSpecialSMSMessageOperations::CSmsSpecialSMSMessageOperations
-
-
-/**
- *  @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 CSmsEnhancedVoiceMailOperations::operator=(const CSmsEnhancedVoiceMailOperations&)
-    {
-    // Ignore in code coverage - not intended to be used
-    BULLSEYE_OFF    
-    LOGGSMU1("CSmsEnhancedVoiceMailOperations::operator=");
-    Panic(KGsmuPanicMethodBodyNotImplemented1);
-    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 CSmsEnhancedVoiceMailOperations::operator==(const CSmsEnhancedVoiceMailOperations&)
-    {
-    // Ignore in code coverage - not intended to be used
-    BULLSEYE_OFF    
-    LOGGSMU1("CSmsEnhancedVoiceMailOperations::operator==");
-    Panic(KGsmuPanicMethodBodyNotImplemented1);
-    return EFalse;
-    BULLSEYE_RESTORE
-    }
-
-/**
- *  @internalComponent
- *  
- *  Identifies whether the message type or version supports this operation
- *  
- *  @leave
- *  If the message type or version does not support this operation.
- */
-void CSmsEnhancedVoiceMailOperations::ValidateOperationL() const
-	{
-	LOGGSMU1("CSmsEnhancedVoiceMailOperations::ValidateOperationL()");
-
-	if (iMessage.Version() < CSmsMessage::ESmsMessageV1)
-	    {
-	    LOGGSMU2("CSmsEnhancedVoiceMailInformation::AddEnhancedVoiceMailIEL, Operation not supported, Msg Version %d", iMessage.Version());
-	    User::Leave(KErrNotSupported);
-	    }
-
-	if (!MessageTypeSupported())
-	    {
-	    LOGGSMU2("CSmsSpecialSMSMessageOperations::AddEnhancedVoiceMailIEL, Operation not supported by this PDU type, type = %d", iMessage.Type());
-	    User::Leave(KErrNotSupported);
-	    }
-	} // CSmsEnhancedVoiceMailOperations::ValidateOperationL
-
-
-/**
- *  @publishedAll
- *  
- *  Adds an Enhanced Voice Mail Information Element to the CSmsMessage.
- *  The information element can be either an Enhanced Voice Mail Notification or
- *  an Enhanced Voice Mail Delete Confirmation. Enhanced Voice Mail Notifications
- *  and Enhanced Voice Mail Delete Confirmations are abstracted in classes derived
- *  from CEnhancedVoiceMailBoxInformation.
- *  @param aEVMI
- *  A pointer to the Enhanced Voice Mail Information Element.
- *  @leave KErrNotSupported
- *  If the message version or type does not support this query.
- *  @leave KErrAlreadyExists
- *  If an Enhanced Voice Mail Information Element has already been installed.
- *  @leave KErrArgument
- *  If the input parameter contains invalid parameters.
- *  @capability None
- */
-EXPORT_C void CSmsEnhancedVoiceMailOperations::AddEnhancedVoiceMailIEL(const CEnhancedVoiceMailBoxInformation& aEVMI) const
-	{
-	LOGGSMU1("CSmsEnhancedVoiceMailInformation::AddEnhancedVoiceMailIEL");
-
-	ValidateOperationL();
-
-	if (ContainsEnhancedVoiceMailIEL())
-	    {
-	    LOGGSMU1("CSmsEnhancedVoiceMailInformation::AddEnhancedVoiceMailIEL, Already Exists");
-	    User::Leave(KErrAlreadyExists);
-	    }
-
-	CSmsMessageAdditionalAttributes& additionalAttributes = *((CSmsMessageAdditionalAttributes*) iMessage.AdditionalInfo());
-
-	// The Enhanced Voice Mail Information Element must fit into a single PDU.
-	// The maximum size for its data field is therefore
-	// the maximum size of the user data minus user data header length, the ie identifier byte and
-	// ie length byte.
-	TBuf8<CEnhancedVoiceMailBoxInformation::KSmsMaxEnhancedVoiceMailSize> voiceMailInfo;
-	voiceMailInfo.SetLength(CEnhancedVoiceMailNotification::KSmsMaxEnhancedVoiceMailSize);
-	TUint8* startPtr = &voiceMailInfo[0];
-	TUint8* endPtr = aEVMI.EncodeL(startPtr, iCharacterSetConverter, iFs);
-	TInt length = (TInt) (endPtr - startPtr);
-	voiceMailInfo.SetLength(length);
-
-	CSmsInformationElement* iE = CSmsInformationElement::NewL(CSmsInformationElement::CSmsInformationElement::ESmsEnhanceVoiceMailInformation, voiceMailInfo);
-	CleanupStack::PushL(iE);
-
-	additionalAttributes.AddControlInformationElementL(iE);
-	CleanupStack::Pop();
-	} // CSmsEnhancedVoiceMailOperations::AddEnhancedVoiceMailIEL
-
-
-/**
- *  @publishedAll
- *  
- *  Removes the Enhanced Voice Mail Information Element from the CSmsMessage,
- *  provided it exists.
- *  @leave KErrNotSupported
- *  If the message version or type does not support this query.
- *  @leave KErrNotFound
- *  If the CSmsMessage does not contain an Enhanced Voice Mail Information Element
- *  @capability None
- */
-EXPORT_C CEnhancedVoiceMailBoxInformation* CSmsEnhancedVoiceMailOperations::RemoveEnhancedVoiceMailIEL() const
-	{
-	LOGGSMU1("CSmsEnhancedVoiceMailInformation::RemoveEnhancedVoiceMailIE");
-
-	ValidateOperationL();
-
-	CEnhancedVoiceMailBoxInformation* voiceMailBoxInfo = NULL;
-	TBool deleteInformationElement = ETrue;
-	
-	// If function leaves, allow the error to propagate upwards
-	voiceMailBoxInfo = GetEnhancedVoiceMailIEL(deleteInformationElement);
-
-	return voiceMailBoxInfo;
-	} // CSmsEnhancedVoiceMailOperations::RemoveEnhancedVoiceMailIEL
-
-
-/**
- *  @publishedAll
- *  
- *  Copies the Enhanced Voice Mail Information Element contained in the CSmsMessage,
- *  provided one exists.
- *  @leave KErrNotSupported
- *  If the message version or type does not support this query.
- *  @leave KErrNotFound
- *  If the CSmsMessage does not contain an Enhanced Voice Mail Information Element to copy.
- *  @capability None
- */
-EXPORT_C CEnhancedVoiceMailBoxInformation* CSmsEnhancedVoiceMailOperations::CopyEnhancedVoiceMailIEL() const
-	{
-	LOGGSMU1("CSmsEnhancedVoiceMailInformation::CopyEnhancedVoiceMailIEL");
-
-	ValidateOperationL();
-
-	CEnhancedVoiceMailBoxInformation* voiceMailBoxInfo = NULL;
-	TBool deleteInformationElement = EFalse;
-	
-	// If function leaves, allow the error to propagate upwards
-	voiceMailBoxInfo = GetEnhancedVoiceMailIEL(deleteInformationElement);
-
-	return voiceMailBoxInfo;
-	} // CSmsEnhancedVoiceMailOperations::CopyEnhancedVoiceMailIEL
-
-
-/**
- *  @internalComponent
- *  
- *  Returns a copy of the Enhanced Voice Mail Information Element contained in the CSmsMessage,
- *  provided one exists. Optionally deletes the information element.
- *  @param aRemove
- *  Indicates that the information element should be deleted once its contents have been copied.
- *  @leave KErrNotFound
- *  If the CSmsMessage does not contain an Enhanced Voice Mail Information Element to copy.
- */
-CEnhancedVoiceMailBoxInformation* CSmsEnhancedVoiceMailOperations::GetEnhancedVoiceMailIEL(TBool aRemove) const
-	{
-	LOGGSMU1("CSmsEnhancedVoiceMailOperations::GetEnhancedVoiceMailIEL()");
-
-	TBool found = EFalse;
-
-	CEnhancedVoiceMailBoxInformation* voiceMailBoxInfo = NULL;
-
-	TSmsInformationElementCategories::TInformationElementCategory category;
-
-	if (TSmsInformationElementCategories::GetCategoryDefinition(CSmsInformationElement::ESmsEnhanceVoiceMailInformation, category) == EFalse)
-		{
-		User::Leave(KErrArgument);
-		}
-
-	CSmsMessageAdditionalAttributes* additionalAttributes = (CSmsMessageAdditionalAttributes*) iMessage.AdditionalInfo();
-	TUint numberOfElements = additionalAttributes->NumberOfControlInformationElements(category);
-
-	for (TUint i = 0; i < numberOfElements; i++)
-	    {
-	    CSmsInformationElement::TSmsInformationElementIdentifier id = CSmsInformationElement::ESmsIEMaximum;
-	    id = additionalAttributes->GetControlInformationElementL(category, i).Identifier();
-
-	    if (id == CSmsInformationElement::CSmsInformationElement::ESmsEnhanceVoiceMailInformation)
-	        {
-	        if (additionalAttributes->GetControlInformationElementL(category, i).Data()[0] & 0x01)
-	            {
-	            voiceMailBoxInfo = CEnhancedVoiceMailDeleteConfirmations::NewL();
-	            }
-	        else
-	            {
-	            voiceMailBoxInfo = CEnhancedVoiceMailNotification::NewL();
-	            }
-
-	        CleanupStack::PushL(voiceMailBoxInfo);
-	        TGsmuLex8 encodedVoiceMailBox(additionalAttributes->GetControlInformationElementL(category, i).Data());
-	        voiceMailBoxInfo->DecodeL(encodedVoiceMailBox, iCharacterSetConverter, iFs);
-	        CleanupStack::Pop(voiceMailBoxInfo);
-
-	        if (aRemove)
-	            {
-	            additionalAttributes->DeleteControlInformationElement(category, i);
-	            }
-
-	        found = ETrue;
-
-	        break;
-	        }
-	    }
-
-	if (found == EFalse)
-	    {
-	    User::Leave(KErrNotFound);
-	    }
-
-	return voiceMailBoxInfo;
-	} // CSmsEnhancedVoiceMailOperations::GetEnhancedVoiceMailIEL
-
-
-/**
- *  @publishedAll
- *  
- *  Determines whether the CSmsMessage contains an Enhanced Voice Mail Information Element.
- *  @leave KErrNotSupported
- *  If the message version or type does not support this query.
- *  @return
- *  True if the CSmsMessage contains an Enhanced Voice Mail Information Element.
- *  @capability None
- */
-EXPORT_C TBool CSmsEnhancedVoiceMailOperations::ContainsEnhancedVoiceMailIEL() const
-	{
-	LOGGSMU1("CSmsEnhancedVoiceMailInformation::ContainsEnhancedVoiceMailIEL");
-
-	ValidateOperationL();
-
-	TBool rc = EFalse;
-
-	TSmsInformationElementCategories::TInformationElementCategory category;
-
-	if (TSmsInformationElementCategories::GetCategoryDefinition(CSmsInformationElement::ESmsEnhanceVoiceMailInformation, category) == EFalse)
-		{
-		User::Leave(KErrArgument);
-		}
-
-	CSmsMessageAdditionalAttributes* additionalAttributes = (CSmsMessageAdditionalAttributes*) iMessage.AdditionalInfo();
-	TUint numberOfElements = additionalAttributes->NumberOfControlInformationElements(category);
-
-	for (TUint i = 0; i < numberOfElements; i++)
-	    {
-	    CSmsInformationElement::TSmsInformationElementIdentifier id = CSmsInformationElement::ESmsIEMaximum;
-	    
-	    // If function leaves, allow the error to propagate upwards
-	    id = additionalAttributes->GetControlInformationElementL(category, i).Identifier();
-
-	    if (id == CSmsInformationElement::ESmsEnhanceVoiceMailInformation)
-	        {
-	        rc = ETrue;
-	        break;
-	        }
-	    }
-
-	return rc;
-	} // CSmsEnhancedVoiceMailOperations::ContainsEnhancedVoiceMailIEL
-
-
-/**
- *  Status Reporting.
- *  
- *  @note This should be the last thing that should be configured in CSmsMessage.
- *  If anything is changed after this then the number of PDUs might change which
- *  will affect status reporting.
- */
-CSmsEnhancedVoiceMailOperations::CSmsEnhancedVoiceMailOperations(CSmsInformationElement::TSmsInformationElementIdentifier aId,  CSmsMessage& aMessage,
-                                                                 CCnvCharacterSetConverter& aCharacterSetConverter, RFs& aFs) : CSmsCtrlOperation(aId, aMessage),
-                                                                 iCharacterSetConverter(aCharacterSetConverter), iFs(aFs)
-	{
-	// NOP
-	} // CSmsEnhancedVoiceMailOperations::CSmsEnhancedVoiceMailOperations
-
-
-CSmsSMSCCtrlParameterOperations::CSmsSMSCCtrlParameterOperations(CSmsInformationElement::TSmsInformationElementIdentifier aId, CSmsMessage& aMessage)
-: CSmsCtrlOperation(aId, aMessage)
-	{
-	
-	} // CSmsSMSCCtrlParameterOperations::CSmsSMSCCtrlParameterOperations
-	
-
-/**
- *  @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 CSmsSMSCCtrlParameterOperations::operator=(const CSmsSMSCCtrlParameterOperations&)
-    {
-    // Ignore in code coverage - not intended to be used
-    BULLSEYE_OFF    
-    LOGGSMU1("CSmsSMSCCtrlParameterOperations::operator=");
-    Panic(KGsmuPanicMethodBodyNotImplemented1);
-    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 CSmsSMSCCtrlParameterOperations::operator==(const CSmsSMSCCtrlParameterOperations&)
-    {
-    // Ignore in code coverage - not intended to be used
-    BULLSEYE_OFF    
-    LOGGSMU1("CSmsSMSCCtrlParameterOperations::operator==");
-    Panic(KGsmuPanicMethodBodyNotImplemented1);
-    return EFalse;
-    BULLSEYE_RESTORE
-    }
-
-/**
- *  @internalComponent
- *  
- *  Identifies whether the message type or version supports this operation
- *  
- *  @leave
- *  If the message type or version does not support this operation.
- */
-void CSmsSMSCCtrlParameterOperations::ValidateOperationL() const
-	{
-	if (iMessage.Version() < CSmsMessage::ESmsMessageV2)
-	    {
-	    LOGGSMU2("CSmsSMSCCtrlParameterOperations Operation not supported, Msg Version %d", iMessage.Version());
-	    User::Leave(KErrNotSupported); 
-	    }
-
-	if (!MessageTypeSupported())
-	    {
-	    LOGGSMU2("CSmsSMSCCtrlParameterOperations Operation not supported by this PDU type, type = %d", iMessage.Type());
-	    User::Leave(KErrNotSupported);
-	    }
-	} // CSmsSMSCCtrlParameterOperations::ValidateOperationL()
-
-
-/**
- *  @internalComponent
- *  
- *  Checks that the octet passed to it has the valid bits set in it. If the bits which 
- *  are not supported yet are set then reset it. 
- *  This method is called by SetStatusReportL.
- *  
- *  @param aSelectiveStatus
- *  The octet which needs to be set as the Selective Status for the report.
- *  @return
- *  ETrue if the selective status is valid.
- *  @leave KErrNotSupported
- *  If the last 4 bits are set as they are not supported.
- */
-TBool CSmsSMSCCtrlParameterOperations::ValidateControlParametersL(TUint8& aSelectiveStatus) const
-	{
-	if (aSelectiveStatus & ESmsStatusReportForFutureUse1)
-		{
-		User::Leave(KErrNotSupported);
-		}
-		
-	if (aSelectiveStatus & ESmsStatusReportForFutureUse2)
-		{
-		User::Leave(KErrNotSupported);	
-		}
-		
-	if (aSelectiveStatus & ESmsStatusReportCancelRestSRR)
-		{
-		User::Leave(KErrNotSupported);	
-		}
-		
-	if (aSelectiveStatus & ESmsStatusReportIncludeOriginalUDH)
-		{
-		User::Leave(KErrNotSupported);
-		}
-	
-	return ETrue;	
-	} // CSmsSMSCCtrlParameterOperations::ValidateControlParametersL
-
-
-/**
- *  @publishedAll
- *  
- *  Sets the status report for a PDU. First the scheme is obtained by calling the 
- *  GetStatusReportScheme and checked if it is the valid scheme. Then aSelectiveStatus is 
- *  checked to see if it is the default value. If it is then nothing is done. But if 
- *  aSelectiveStatus is non-default then it is appended to the array 
- *  iControlParametersStatusReport along with the aSegmentSequenceNum 
- *  
- *  @param aSegmentSequenceNum
- *  The segment sequence number of the PDU which needs to be updated.
- *  @param aSelectiveStatus
- *  The octet which needs to be set as the Selective Status for the report.
- *  @return KErrNone if the operation is successful.
- *  KErrNotFound if the Segment Sequence Number is out of range or the scheme is inavlid.
- *  KErrNotSupported if aSelectiveStatus is not valid.
- *  @leave
- *  If ValidateOperationL or AppendL leaves.
- *  @capability None
- */
-EXPORT_C TInt CSmsSMSCCtrlParameterOperations::SetStatusReportL(TUint aSegmentSequenceNum, TUint8 aSelectiveStatus)
-	{
-	ValidateOperationL();
-	TBool validateStatus = ValidateControlParametersL(aSelectiveStatus);
-	
-	if(validateStatus)
-		{
-		CSmsMessageAdditionalAttributes& additionalAttributes = *((CSmsMessageAdditionalAttributes*) iMessage.AdditionalInfo());
-		CSmsMessageAdditionalAttributes::CSmsStatusReportScheme& scheme = additionalAttributes.GetStatusReportScheme();
-		if (scheme.Id() == EControlParametersScheme)
-			{
-			CSmsMessageAdditionalAttributes::CControlParametersScheme& ctrlParamsScheme = (CSmsMessageAdditionalAttributes::CControlParametersScheme&)scheme;
-			if(aSegmentSequenceNum>=ctrlParamsScheme.iNumOfPDUs)
-				{
-				return KErrNotFound;	//	aSegmentSequenceNum out of range.
-				}
-			if (aSelectiveStatus == ctrlParamsScheme.iDefaultStatusReport)
-				{
-				return KErrNone;	// It's the same as default so need for any updation.
-				}
-			else
-				{
-				TInt count = (ctrlParamsScheme.iControlParametersStatusReport).Count();
-				TBool found(EFalse);
-				for (TInt ii=0; !found && ii<count; ii++)
-					{
-					if ((ctrlParamsScheme.iControlParametersStatusReport[ii]).iSegmentSequenceNum == aSegmentSequenceNum)
-						{
-						(ctrlParamsScheme.iControlParametersStatusReport[ii]).iSelectiveStatus = aSelectiveStatus;
-						found = ETrue;
-						break;
-						}
-					}
-					
-				if (!found)
-					{
-					CSmsMessageAdditionalAttributes::CControlParametersScheme::TSmsSMSCCtrlParameterStatus smscCtrlParameterStatus;
-					smscCtrlParameterStatus.iSegmentSequenceNum = aSegmentSequenceNum;
-					smscCtrlParameterStatus.iSelectiveStatus = aSelectiveStatus;
-					(ctrlParamsScheme.iControlParametersStatusReport).AppendL(smscCtrlParameterStatus);
-					}
-			
-				return KErrNone;	
-				}
-			}
-		else
-			{
-			return KErrNotFound;	//	Scheme not valid.
-			}
-		}
-	else
-		{
-		return KErrNotSupported;	//	Invalid aSlectiveStatus.
-		}
-	} // CSmsSMSCCtrlParameterOperations::SetStatusReportL
-
-
-/**
- *  @publishedAll
- *  
- *  Gets the selective status for a PDU if the scheme is set to the Control
- *  Parameters Scheme.
- *  
- *  @param aSegmentSequenceNum
- *  The segment sequence number of the PDU whose status report is required.
- *  @param aSelectiveStatus
- *  Returns the selective status octet for that PDU.
- *  
- *  @return KErrNotFound if the segment sequence number or the scheme is invalid.
- *  
- *  @capability None
- */
-EXPORT_C TInt CSmsSMSCCtrlParameterOperations::GetStatusReport(TUint aSegmentSequenceNum,
-															   TUint8& aSelectiveStatus) const
-	{
-	CSmsMessageAdditionalAttributes* additionalAttributes = (CSmsMessageAdditionalAttributes*) iMessage.AdditionalInfo();
-	CSmsMessageAdditionalAttributes::CSmsStatusReportScheme& scheme = additionalAttributes->GetStatusReportScheme();
-	if (scheme.Id() == EControlParametersScheme)
-		{
-		CSmsMessageAdditionalAttributes::CControlParametersScheme& ctrlParamsScheme = (CSmsMessageAdditionalAttributes::CControlParametersScheme&)scheme;
-		
-		if(aSegmentSequenceNum>=ctrlParamsScheme.iNumOfPDUs)
-			{
-			return KErrNotFound;	//	aSegmentSequenceNum out of range.
-			}
-
-		TInt count = (ctrlParamsScheme.iControlParametersStatusReport).Count();
-		
-		for (TInt ii=0; ii<count; ii++)
-			{
-			if (ctrlParamsScheme.iControlParametersStatusReport[ii].iSegmentSequenceNum == aSegmentSequenceNum)
-				{
-				aSelectiveStatus = ctrlParamsScheme.iControlParametersStatusReport[ii].iSelectiveStatus;
-				return KErrNone;
-				}
-			}
-			
-		aSelectiveStatus = ctrlParamsScheme.iDefaultStatusReport;
-		return KErrNone;
-		}
-
-	return KErrNotFound;
-	} // CSmsSMSCCtrlParameterOperations::GetStatusReport
-
-
-/**
- *  @publishedAll
- *  
- *  Sets the default value of the status report to aDefaultSelectiveStatus.
- *  
- *  @param aDefaultSelectiveStatus
- *  The selective status to be used as default.
- *  @leave KErrNotFound
- *  If the scheme is invalid.
- *  @capability None
- */
-EXPORT_C void CSmsSMSCCtrlParameterOperations::SetDefaultL(TUint8 aDefaultSelectiveStatus)
-	{
-	CSmsMessageAdditionalAttributes& additionalAttributes = *((CSmsMessageAdditionalAttributes*) iMessage.AdditionalInfo());
-	CSmsMessageAdditionalAttributes::CSmsStatusReportScheme& scheme = additionalAttributes.GetStatusReportScheme();
-	if (scheme.Id() == EControlParametersScheme)
-		{
-		CSmsMessageAdditionalAttributes::CControlParametersScheme& ctrlParamsScheme = (CSmsMessageAdditionalAttributes::CControlParametersScheme&)scheme;
-		if(aDefaultSelectiveStatus & ESmsSMSCControlParametersMask)
-			{
-			ctrlParamsScheme.iDefaultStatusReport = aDefaultSelectiveStatus;
-			}
-		else
-			{
-			ctrlParamsScheme.iDefaultStatusReport = 0x00;	
-			}
-		}
-	else
-		{
-		User::Leave(KErrNotFound);
-		}
-	} // CSmsSMSCCtrlParameterOperations::SetDefaultL
-
-
-/**
- *  @publishedAll
- *  
- *  This method is called to set the scheme to Control Parameters Scheme.
- *  First iStatusReportScheme, which is obtained by calling GetStatusReportScheme,
- *  is deleted and set to NULL. Then a new scheme is created and a default value is set.
- *  This should be the last method to be called in a message sending process as all the 
- *  operations in this interface depend on the number of PDUs being set.
- *  
- *  @leave
- *  If ValidateOperationL or NumMessagePDUsL leaves.
- *  @capability None
- */
-EXPORT_C void CSmsSMSCCtrlParameterOperations::SetSchemeL()
-	{
-	ValidateOperationL();
-	
-	CSmsMessageAdditionalAttributes& additionalAttributes = *((CSmsMessageAdditionalAttributes*) iMessage.AdditionalInfo());
-	additionalAttributes.SetStatusReportSchemeL(EControlParametersScheme);
-	
-	TBuf8 <1> buffer;
-	buffer.SetLength(1);
-	buffer[0] = 0;
-	
-	CSmsUserData& userData = iMessage.SmsPDU().UserData();
-
-	userData.AddInformationElementL(CSmsInformationElement::ESmsIEISMSCControlParameters,buffer);
-	
-	CSmsMessageAdditionalAttributes::CSmsStatusReportScheme& scheme = additionalAttributes.GetStatusReportScheme();
-	CSmsMessageAdditionalAttributes::CControlParametersScheme& ctrlParamsScheme = (CSmsMessageAdditionalAttributes::CControlParametersScheme&)scheme;
-	ctrlParamsScheme.iNumOfPDUs = iMessage.NumMessagePDUsL();
-
-	SetDefaultL(0);
-	} // CSmsSMSCCtrlParameterOperations::SetSchemeL
-
-
-/**
- *  @publishedAll
- *  
- *  Gets the current scheme being used.
- *  
- *  @return
- *  EControlParametrsScheme is returned when Control Parameters Scheme is being used.
- *  @capability None
- */
-EXPORT_C TSmsStatusReportScheme CSmsSMSCCtrlParameterOperations::GetScheme() const
-	{
-	CSmsMessageAdditionalAttributes* additionalAttributes = (CSmsMessageAdditionalAttributes*) iMessage.AdditionalInfo();
-		
-	return (additionalAttributes->GetStatusReportScheme()).Id();
-	} // CSmsSMSCCtrlParameterOperations::GetScheme
-
-
-/**
- *  @publishedAll
- *  
- *  This method re-sets the scheme to the Default Scheme.
- *  
- *  @capability None
- */
-EXPORT_C void CSmsSMSCCtrlParameterOperations::ResetSchemeL()
-	{
-	CSmsMessageAdditionalAttributes& additionalAttributes = *((CSmsMessageAdditionalAttributes*) iMessage.AdditionalInfo());
-	
-	CSmsUserData& userData = iMessage.SmsPDU().UserData();
-
-	CArrayFixFlat<TInt>* indices = new (ELeave) CArrayFixFlat<TInt>(8);
-	CleanupStack::PushL(indices);
-	userData.InformationElementIndicesL(CSmsInformationElement::ESmsIEISMSCControlParameters,*indices);
-
-	TUint i = indices->Count();
-
-	while (i-- != 0)
-	    {
-	    userData.RemoveInformationElement((*indices)[i]);
-	    }
-    
-    CleanupStack::PopAndDestroy(indices);
-    additionalAttributes.SetStatusReportSchemeL(EDefaultScheme);
-	} // CSmsSMSCCtrlParameterOperations::ResetSchemeL
-
+// 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:
+//
+
+#include "Gsmumain.h"
+#include "gsmuieoperations.h"
+#include "Gsmumsg.h"
+#include "gsmumsgadditionalattributes.h"
+#include "Gsmuelem.h"
+#include "smsstacklog.h"
+
+
+/**
+ *  This is used by the CSmsMessage to create a CSmsIEOperation.
+ *  Each instance is owned by the CSmsMessage which created it.
+ *  Therefore only the CSmsMessage (GSMU component) is allowed to
+ *  create and delete CSmsIEOperations.
+ *  
+ *  @param aId
+ *  The ID for the CSmsInformationElement for whom an operation class needs to be created.
+ *  @param aMessage
+ *  The CSmsMessage that this operations class belongs to.
+ *  @param aCharacterSetConverter
+ *  A reference to a character set converter, needed by some derived operation classes.
+ *  @param aFs
+ *  A reference to the file server, needed by some derived operations classes.
+ *  
+ *  @internalComponent
+ */
+CSmsIEOperation*  CSmsIEOperation::NewL(CSmsInformationElement::TSmsInformationElementIdentifier aId, CSmsMessage& aMessage, CCnvCharacterSetConverter& aCharacterSetConverter, RFs& aFs)
+	{
+	LOGGSMU1("CSmsIEOperation::NewL()");
+
+	CSmsIEOperation* iEOperation = NULL;
+
+	switch (aId)
+	    {
+	    case CSmsInformationElement::ESmsHyperLinkFormat:
+	        iEOperation = new (ELeave)  CSmsHyperLinkOperations(aId,aMessage);
+	        break;
+	    case CSmsInformationElement::ESmsReplyAddressFormat:
+	        iEOperation = new (ELeave) CSmsReplyAddressOperations(aId, aMessage, aCharacterSetConverter, aFs);
+	        break;
+	    case CSmsInformationElement::ESmsEnhanceVoiceMailInformation:
+	        iEOperation = new (ELeave) CSmsEnhancedVoiceMailOperations(aId, aMessage, aCharacterSetConverter, aFs);
+	        break;
+	    case CSmsInformationElement::ESmsIEISpecialSMSMessageIndication:
+	        iEOperation = new (ELeave)  CSmsSpecialSMSMessageOperations(aId,aMessage);
+	        break;
+	    case CSmsInformationElement::ESmsIEISMSCControlParameters:
+	        iEOperation = new (ELeave)  CSmsSMSCCtrlParameterOperations(aId,aMessage); 
+	        break;
+	    default:
+	        User::Leave(KErrArgument);
+	        break;
+	    }
+
+	iEOperation->ConstructL();
+
+	return iEOperation;
+	} // CSmsIEOperation::NewL
+
+
+/**
+ *  @publishedAll
+ *  
+ *  Identifies the information element which is supported by this operations class.
+ *  
+ *  @return The information element ID supported by this operations class.
+ *  @capability None
+ */
+EXPORT_C CSmsInformationElement::TSmsInformationElementIdentifier CSmsIEOperation::Id() const
+	{
+	LOGGSMU1("CSmsIEOperation::Id()");
+
+	return iId;
+	} // CSmsInformationElement::TSmsInformationElementIdentifier
+
+
+/**
+ *  @internalComponent
+ *  
+ *  Identifies whether the message type supports is supported
+ *  
+ *  @return True if the message type is supported. False otherwise.
+ */
+TBool CSmsIEOperation::MessageTypeSupported() const
+	{
+	LOGGSMU1("CSmsIEOperation::MessageTypeSupported()");
+
+	CSmsPDU::TSmsPDUType type = iMessage.Type();
+
+    return ((type == CSmsPDU::ESmsDeliver) ||
+            (type == CSmsPDU::ESmsSubmit));
+	} // CSmsIEOperation::MessageTypeSupported
+
+
+CSmsIEOperation::CSmsIEOperation(CSmsInformationElement::TSmsInformationElementIdentifier aId, CSmsMessage& aMessage) : iId(aId), iMessage(aMessage)
+	{
+	//NOP
+	} // CSmsIEOperation::CSmsIEOperation
+
+
+/**
+ *  @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 CSmsIEOperation::operator=(const CSmsIEOperation&)
+    {
+    // Ignore in code coverage - not intended to be used
+    BULLSEYE_OFF    
+    LOGGSMU1("CSmsIEOperation::operator=");
+    Panic(KGsmuPanicMethodBodyNotImplemented1);
+    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 CSmsIEOperation::operator==(const CSmsIEOperation&)
+    {
+    // Ignore in code coverage - not intended to be used
+    BULLSEYE_OFF    
+    LOGGSMU1("CSmsIEOperation::operator==");
+    Panic(KGsmuPanicMethodBodyNotImplemented1);
+    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 CSmsCtrlOperation::operator=(const CSmsCtrlOperation&)
+    {
+    // Ignore in code coverage - not intended to be used
+    BULLSEYE_OFF    
+    LOGGSMU1("CSmsCtrlOperation::operator=");
+    Panic(KGsmuPanicMethodBodyNotImplemented1);
+    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 CSmsCtrlOperation::operator==(const CSmsCtrlOperation&)
+    {
+    // Ignore in code coverage - not intended to be used
+    BULLSEYE_OFF    
+    LOGGSMU1("CSmsCtrlOperation::operator==");
+    Panic(KGsmuPanicMethodBodyNotImplemented1);
+    return EFalse;
+    BULLSEYE_RESTORE
+    }
+
+CSmsCtrlOperation::CSmsCtrlOperation(CSmsInformationElement::TSmsInformationElementIdentifier aId, CSmsMessage& aMessage) : CSmsIEOperation(aId, aMessage)
+	{
+	//NOP
+	} // CSmsCtrlOperation::CSmsCtrlOperation
+
+
+CSmsHyperLinkOperations::CSmsHyperLinkOperations(CSmsInformationElement::TSmsInformationElementIdentifier aId, CSmsMessage& aMessage) : CSmsCtrlOperation(aId, aMessage)
+	{
+	//NOP
+	} // CSmsHyperLinkOperations::CSmsHyperLinkOperations
+
+
+void CSmsIEOperation::ConstructL()
+	{
+	LOGGSMU1("CSmsIEOperation::ConstructL()");
+	} // CSmsIEOperation::ConstructL
+
+
+/**
+ *  @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 CSmsHyperLinkOperations::operator=(const CSmsHyperLinkOperations&)
+    {
+    // Ignore in code coverage - not intended to be used
+    BULLSEYE_OFF    
+    LOGGSMU1("CSmsHyperLinkOperations::operator=");
+    Panic(KGsmuPanicMethodBodyNotImplemented1);
+    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 CSmsHyperLinkOperations::operator==(const CSmsHyperLinkOperations&)
+    {
+    // Ignore in code coverage - not intended to be used
+    BULLSEYE_OFF    
+    LOGGSMU1("CSmsHyperLinkOperations::operator==");
+    Panic(KGsmuPanicMethodBodyNotImplemented1);
+    return EFalse;
+    BULLSEYE_RESTORE
+    }
+
+/**
+ *  @internalComponent
+ *  
+ *  Identifies whether the message type or version supports this operation
+ *  
+ *  @leave
+ *  If the message type or version does not support this operation.
+ */
+void CSmsHyperLinkOperations::ValidateOperationL() const
+	{
+	LOGGSMU1("CSmsHyperLinkOperations::ValidateOperationL()");
+
+	if (iMessage.Version() < CSmsMessage::ESmsMessageV1)
+	    {
+	    LOGGSMU2("CSmsHyperLinkOperations::AddHyperLinkL, Operation not supported, Msg Version %d", iMessage.Version());
+	    User::Leave(KErrNotSupported);
+	    }
+
+	if (!MessageTypeSupported())
+	    {
+	    LOGGSMU2("CSmsHyperLinkOperations::AddHyperLinkL, Operation not supported by this PDU type, type = %d", iMessage.Type());
+	    User::Leave(KErrNotSupported);
+	    }
+	} // CSmsHyperLinkOperations::ValidateOperationL
+
+
+/**
+ *  @publishedAll
+ *  
+ *  This method adds a HyperLink to the CSmsMessage.
+ *  
+ *  @param aPosition
+ *  The absolute character position within the message text.
+ *  @param aTitle
+ *  An integer representation of the number of characters in the hyperlink title.
+ *  @param URL Length
+ *  An integer representation of the number of characters in the URL.
+ *  @leave KErrNotSupported
+ *  If the message version or type does not support hyperlinks.
+ *  @capability None
+ */
+EXPORT_C void CSmsHyperLinkOperations::AddHyperLinkL(TUint aPosition, TUint8 aTitleLength,  TUint8  aURLLength) const
+	{
+	LOGGSMU1("CSmsHyperLinkOperations::AddHyperLinkL()");
+
+	ValidateOperationL();
+
+	CSmsMessageAdditionalAttributes& additionalAttributes = *((CSmsMessageAdditionalAttributes*) iMessage.AdditionalInfo());
+
+	TBuf8 <4> buffer;
+	buffer.SetLength(4);
+	buffer[0] = (TUint8) (aPosition >> 8); // lowest octet contains the
+	buffer[1] = (TUint8)  aPosition;       // most significant bits
+	buffer[2] = aTitleLength;
+	buffer[3] = aURLLength;
+
+	CSmsInformationElement* iE = CSmsInformationElement::NewL(CSmsInformationElement::ESmsHyperLinkFormat, buffer);
+	CleanupStack::PushL(iE);
+	additionalAttributes.AddControlInformationElementL(iE);
+	CleanupStack::Pop(iE);
+	} // CSmsHyperLinkOperations::AddHyperLinkL
+
+
+/**
+ *  @publishedAll
+ *  
+ *  Returns the number of Hyper Link IEs contained in this message.
+ *  @leave KErrNotSupported
+ *  If this functionality is not supported by this version or type of message.
+ *  @return
+ *  The number of hyper links contained in this message.
+ *  @capability None
+ */
+EXPORT_C TUint CSmsHyperLinkOperations::NumberOfHyperLinksL() const
+	{
+	LOGGSMU1("CSmsHyperLinkOperations::NumberOfHyperLinks");
+
+	ValidateOperationL();
+
+	TUint numberOfHyperLinks = 0;
+
+	TSmsInformationElementCategories::TInformationElementCategory category;
+
+	if (TSmsInformationElementCategories::GetCategoryDefinition(CSmsInformationElement::ESmsHyperLinkFormat, category) == EFalse)
+			{
+		User::Leave(KErrArgument);
+		}
+
+	CSmsMessageAdditionalAttributes* additionalAttributes = (CSmsMessageAdditionalAttributes*) iMessage.AdditionalInfo();
+	TUint numberOfElements = additionalAttributes->NumberOfControlInformationElements(category);
+
+	for (TUint i = 0; i < numberOfElements; i++)
+	    {
+	    CSmsInformationElement::TSmsInformationElementIdentifier id = CSmsInformationElement::ESmsIEMaximum;
+	    
+	    // If function leaves, allow the error to propagate upwards
+	    id = additionalAttributes->GetControlInformationElementL(category, i).Identifier();
+
+	    if (id == CSmsInformationElement::ESmsHyperLinkFormat)
+	        {
+	        numberOfHyperLinks++;
+	        }
+	    }
+
+	return numberOfHyperLinks;
+	} // CSmsHyperLinkOperations::NumberOfHyperLinksL
+
+
+/**
+ *  @publishedAll
+ *  
+ *  Copies the attributes of the specified hyperlink.
+ *  aIndex has the range [0..[n-1]] where n is the
+ *  value returned by NumberOfHyperLinks()
+ *  
+ *  @param aIndex
+ *  Identifies the hyperlink to extract. Has the range [0..[n-1]]
+ *  where n is the value returned by NumberOfHyperLinks().
+ *  @param &aPosition
+ *  The absolute character position within the message text.
+ *  @param &aTitleLength
+ *  An integer representation of the number of characters in the hyperlink title.
+ *  @param &aURLLength
+ *  An integer representation of the number of characters in the URL.
+ *  @leave KErrNotSupported
+ *  If the message version or type does not support hyperlinks.
+ *  @leave KErrArgument
+ *  If aIndex is out of range.
+ *  @capability None
+ */
+EXPORT_C void  CSmsHyperLinkOperations::CopyHyperLinkAtIndexL(TUint aIndex, TUint& aPosition, TUint8& aTitleLength,  TUint8&  aURLLength) const
+	{
+	LOGGSMU2("CSmsHyperLinkOperations::CopyHyperLinkAtIndexL(): aIndex=%d", aIndex);
+
+	ValidateOperationL();
+
+	TUint numberOfHyperLinks = 0;
+
+	TSmsInformationElementCategories::TInformationElementCategory category;
+	if (TSmsInformationElementCategories::GetCategoryDefinition(CSmsInformationElement::ESmsHyperLinkFormat, category) == EFalse)
+		{
+		User::Leave(KErrArgument);
+		}
+
+	CSmsMessageAdditionalAttributes* additionalAttributes = (CSmsMessageAdditionalAttributes*) iMessage.AdditionalInfo();
+	TUint numberOfElements = additionalAttributes->NumberOfControlInformationElements(category);
+
+	if (aIndex >= numberOfElements)
+	    {
+	    User::Leave(KErrArgument);
+	    }
+
+	for (TUint i = 0; i < numberOfElements; i++)
+	    {
+	    CSmsInformationElement::TSmsInformationElementIdentifier id = CSmsInformationElement::ESmsIEMaximum;
+	    
+	    // If function leaves, allow the error to propagate upwards
+	    id = additionalAttributes->GetControlInformationElementL(category, i).Identifier();
+
+	    if ((id == CSmsInformationElement::ESmsHyperLinkFormat) &&
+	        (numberOfHyperLinks++ == aIndex))
+	        {
+	        aPosition     = (additionalAttributes->GetControlInformationElementL(category, i).Data()[0] << 8);
+	        aPosition    +=  additionalAttributes->GetControlInformationElementL(category, i).Data()[1];
+
+	        aTitleLength = additionalAttributes->GetControlInformationElementL(category, i).Data()[2];
+	        aURLLength   = additionalAttributes->GetControlInformationElementL(category, i).Data()[3];
+	        break;
+	        }
+	    }
+	} // CSmsHyperLinkOperations::CopyHyperLinkAtIndexL
+
+
+/**
+ *  @publishedAll
+ *  
+ *  Removes all hyper Link IEs contained in this message.
+ *  
+ *  @leave KErrNotSupported
+ *  If the message version or type does not support hyperlinks.
+ *  @capability None
+ */
+EXPORT_C void  CSmsHyperLinkOperations::RemoveAllHyperLinksL() const
+	{
+	LOGGSMU1("CSmsHyperLinkOperations::RemoveAllHyperLinks");
+
+	ValidateOperationL();
+
+	TSmsInformationElementCategories::TInformationElementCategory category;
+
+	if (TSmsInformationElementCategories::GetCategoryDefinition(CSmsInformationElement::ESmsHyperLinkFormat, category) == EFalse)
+		{
+		User::Leave(KErrArgument);
+		}
+
+	CSmsMessageAdditionalAttributes* additionalAttributes = (CSmsMessageAdditionalAttributes*) iMessage.AdditionalInfo();
+	TUint i = additionalAttributes->NumberOfControlInformationElements(category);
+
+	while (i-- != 0)
+	    {
+	    CSmsInformationElement::TSmsInformationElementIdentifier id = CSmsInformationElement::ESmsIEMaximum;
+	    
+	    // If function leaves, allow the error to propagate upwards
+	    id = additionalAttributes->GetControlInformationElementL(category, i).Identifier();
+
+	    if (id == CSmsInformationElement::ESmsHyperLinkFormat)
+	        {
+	        additionalAttributes->DeleteControlInformationElement(category, i);
+	        }
+	    }
+	} // CSmsHyperLinkOperations::RemoveAllHyperLinksL
+
+
+/**
+ *  @publishedAll
+ *  
+ *  Removes the indexed hyperlink from this message.
+ *  
+ *  @param aIndex
+ *  aIndex has the range [0..[n-1]] where n is the
+ *  value returned by NumberOfHyperLinks()
+ *  @leave KErrNotSupported
+ *  If the message version or type does not support hyperlinks.
+ *  @leave KErrArgument
+ *  If the index is out of range.
+ *  @capability None
+ */
+EXPORT_C void  CSmsHyperLinkOperations::RemoveHyperLinkL(TUint aIndex) const
+	{
+	LOGGSMU1("CSmsHyperLinkOperations::RemoveHyperLink");
+
+	ValidateOperationL();
+
+	TUint numberOfHyperLinks = 0;
+
+	TSmsInformationElementCategories::TInformationElementCategory category;
+
+	if (TSmsInformationElementCategories::GetCategoryDefinition(CSmsInformationElement::ESmsHyperLinkFormat, category) == EFalse)
+		{
+		User::Leave(KErrArgument);
+		}
+
+	CSmsMessageAdditionalAttributes* additionalAttributes = (CSmsMessageAdditionalAttributes*) iMessage.AdditionalInfo();
+	TUint numberOfElements = additionalAttributes->NumberOfControlInformationElements(category);
+
+	if (aIndex >= numberOfElements)
+	    {
+	    User::Leave(KErrArgument);
+	    }
+
+	for (TUint i = 0; i < numberOfElements; i++)
+	    {
+	    CSmsInformationElement::TSmsInformationElementIdentifier id = CSmsInformationElement::ESmsIEMaximum;
+
+	    // If function leaves, allow the error to propagate upwards
+	    id = additionalAttributes->GetControlInformationElementL(category, i).Identifier();
+
+	    if ((id == CSmsInformationElement::ESmsHyperLinkFormat) &&
+	        (numberOfHyperLinks++ == aIndex))
+	        {
+	        additionalAttributes->DeleteControlInformationElement(category, i);
+	        break;
+	        }
+	    }
+	} // CSmsHyperLinkOperations::RemoveHyperLinkL
+
+
+/**
+ *  @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 CSmsReplyAddressOperations::operator=(const CSmsReplyAddressOperations&)
+    {
+    // Ignore in code coverage - not intended to be used
+    BULLSEYE_OFF    
+    LOGGSMU1("CSmsReplyAddressOperations::operator=");
+    Panic(KGsmuPanicMethodBodyNotImplemented1);
+    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 CSmsReplyAddressOperations::operator==(const CSmsReplyAddressOperations&)
+    {
+    // Ignore in code coverage - not intended to be used
+    BULLSEYE_OFF    
+    LOGGSMU1("CSmsReplyAddressOperations::operator==");
+    Panic(KGsmuPanicMethodBodyNotImplemented1);
+    return EFalse;
+    BULLSEYE_RESTORE
+    }
+
+/**
+ *  @internalComponent
+ *  
+ *  Identifies whether the message type or version supports this operation
+ *  
+ *  @leave
+ *  If the message type or version does not support this operation.
+ */
+void CSmsReplyAddressOperations::ValidateOperationL() const
+	{
+	LOGGSMU1("CSmsReplyAddressOperations::ValidateOperationL()");
+
+	if (iMessage.Version() < CSmsMessage::ESmsMessageV1)
+	    {
+	    LOGGSMU2("CSmsReplyAddressOperations::AddReplyAddressL, Operation not supported, Msg Version %d", iMessage.Version());
+	    User::Leave(KErrNotSupported);
+	    }
+
+	if (!MessageTypeSupported())
+	    {
+	    LOGGSMU2("CSmsReplyAddressOperations::AddReplyAddressL, Operation not supported by this PDU type, type = %d", iMessage.Type());
+	    User::Leave(KErrNotSupported);
+	    }
+	} // CSmsReplyAddressOperations::ValidateOperationL
+
+
+/**
+ *  @publishedAll
+ *  
+ *  Adds a reply address information element.
+ *  
+ *  @param aAddress
+ *  The international number to be used in the reply address.
+ *  @leave KErrNotSupported
+ *  If the message version or type does not support a reply addresses.
+ *  @leave KErrAlreadyExists
+ *  If the message already contains a reply address.
+ *  @capability None
+ */
+EXPORT_C void  CSmsReplyAddressOperations::AddReplyAddressL(const TDesC& aAddress) const
+	{
+	LOGGSMU1("CSmsReplyAddressOperations::AddReplyAddressL()");
+
+	ValidateOperationL();
+
+	if (ContainsReplyAddressIEL())
+	    {
+	    LOGGSMU1("CSmsReplyAddressOperations::AddReplyAddressL, Already Exists");
+	    User::Leave(KErrAlreadyExists);
+	    }
+
+	CSmsMessageAdditionalAttributes& additionalAttributes = *((CSmsMessageAdditionalAttributes*) iMessage.AdditionalInfo());
+
+	CSmsAddress* address = CSmsAddress::NewL(iCharacterSetConverter,iFs); // needed for encoding the address into the IE.
+	CleanupStack::PushL(address);
+	address->SetAddressL(aAddress);
+	TBuf8<CSmsAddress::KSmsAddressMaxAddressLength> addressBuffer;
+	addressBuffer.SetLength(CSmsAddress::KSmsAddressMaxAddressLength);
+	TUint8* startPtr = &addressBuffer[0];
+	TUint8* endPtr = address->EncodeL(startPtr);
+	TInt length = 0;
+	(endPtr > startPtr) ? (length = endPtr - startPtr) : (length = startPtr - endPtr);
+	addressBuffer.SetLength(length);
+	CleanupStack::PopAndDestroy(address);
+
+	CSmsInformationElement* iE = CSmsInformationElement::NewL(CSmsInformationElement::ESmsReplyAddressFormat, addressBuffer);
+	CleanupStack::PushL(iE);
+	additionalAttributes.AddControlInformationElementL(iE);
+	CleanupStack::Pop(iE);
+	} // CSmsReplyAddressOperations::AddReplyAddressL
+
+
+/**
+ *  @publishedAll
+ *  
+ *  Adds a reply address information element.
+ *  
+ *  @param aAddress
+ *  Sets To and From addresses in ETSI format.
+ *  @leave KErrNotSupported
+ *  If the message version or type does not support a reply addresses.
+ *  @leave KErrAlreadyExists
+ *  If the message already contains a reply address.
+ *  @capability None
+ */
+EXPORT_C void  CSmsReplyAddressOperations::AddParsedReplyAddressL(const TGsmSmsTelNumber& aParsedAddress) const
+	{
+	LOGGSMU1("CSmsReplyAddressOperations::AddParsedReplyAddressL");
+
+	ValidateOperationL();
+
+	if (ContainsReplyAddressIEL())
+	    {
+	    LOGGSMU1("CSmsReplyAddressOperations::AddParsedReplyAddressL, Already Exists");
+	    User::Leave(KErrAlreadyExists);
+	    }
+
+	CSmsMessageAdditionalAttributes& additionalAttributes = *((CSmsMessageAdditionalAttributes*) iMessage.AdditionalInfo());
+
+	CSmsAddress* address = CSmsAddress::NewL(iCharacterSetConverter,iFs);
+	CleanupStack::PushL(address);
+	address->SetParsedAddressL(aParsedAddress);
+	TBuf8<CSmsAddress::KSmsAddressMaxAddressLength> addressBuffer;
+	addressBuffer.SetLength(CSmsAddress::KSmsAddressMaxAddressLength);
+	TUint8* startPtr = &addressBuffer[0];
+	TUint8* endPtr = address->EncodeL(startPtr);
+	TInt length = 0;
+	(endPtr > startPtr) ? (length = endPtr - startPtr) : (length = startPtr - endPtr);
+	addressBuffer.SetLength(length);
+	CleanupStack::PopAndDestroy(address);
+
+	CSmsInformationElement* iE = CSmsInformationElement::NewL(CSmsInformationElement::ESmsReplyAddressFormat, addressBuffer);
+	CleanupStack::PushL(iE);
+	additionalAttributes.AddControlInformationElementL(iE);
+	CleanupStack::Pop(iE);
+	} // CSmsReplyAddressOperations::AddParsedReplyAddressL
+
+
+/**
+ *  @publishedAll
+ *  
+ *  Identifies whether a reply address has already been added to this
+ *  CSmsMessage using the CSmsReplyAddressOperations interface.
+ *  
+ *  @return
+ *  True if the reply address has already been added using this interface.
+ *  @leave KErrNotSupported
+ *  If the message version or type does not support this query.
+ *  @capability None
+ */
+EXPORT_C TBool CSmsReplyAddressOperations::ContainsReplyAddressIEL() const
+	{
+	LOGGSMU1("CSmsReplyAddressOperations::ContainsReplyAddressIEL()");
+
+	TBool rc = EFalse;
+
+	ValidateOperationL();
+
+	TSmsInformationElementCategories::TInformationElementCategory category;
+
+	if (TSmsInformationElementCategories::GetCategoryDefinition(CSmsInformationElement::ESmsReplyAddressFormat, category) == EFalse)
+		{
+		User::Leave(KErrArgument);
+		}
+
+	CSmsMessageAdditionalAttributes* additionalAttributes = (CSmsMessageAdditionalAttributes*) iMessage.AdditionalInfo();
+	TUint numberOfElements = additionalAttributes->NumberOfControlInformationElements(category);
+
+	for (TUint i = 0; i < numberOfElements; i++)
+	    {
+	    CSmsInformationElement::TSmsInformationElementIdentifier id = CSmsInformationElement::ESmsIEMaximum;
+	    
+	    // If function leaves, allow the error to propagate upwards
+	    id = additionalAttributes->GetControlInformationElementL(category, i).Identifier();
+
+	    if (id == CSmsInformationElement::ESmsReplyAddressFormat)
+	        {
+	        rc = ETrue;
+	        break;
+	        }
+	    }
+
+	return rc;
+	} // CSmsReplyAddressOperations::ContainsReplyAddressIEL
+
+
+/**
+ *  @publishedAll
+ *  
+ *  Returns the reply address as an international number
+ *  
+ *  @return
+ *  The reply address as an international number.
+ *  @leave KErrNotSupported
+ *  If the message version or type does not support this query.
+ *  @leave KErrNotFound
+ *  If the message does not contain a reply address information element.
+ *  @leave KErrCorrupt
+ *  If the reply address is corrupt
+ *  @capability None
+ */
+EXPORT_C HBufC* CSmsReplyAddressOperations::GetReplyAddressL() const
+	{
+	LOGGSMU1("CSmsReplyAddressOperations::GetReplyAddressL");
+
+	ValidateOperationL();
+
+	TBool found = EFalse;
+
+	CSmsAddress* address = CSmsAddress::NewL(iCharacterSetConverter,iFs);
+	CleanupStack::PushL(address);
+
+	TSmsInformationElementCategories::TInformationElementCategory category;
+
+	if (TSmsInformationElementCategories::GetCategoryDefinition(CSmsInformationElement::ESmsReplyAddressFormat, category) == EFalse)
+		{
+		User::Leave(KErrArgument);
+		}
+
+	CSmsMessageAdditionalAttributes* additionalAttributes = (CSmsMessageAdditionalAttributes*) iMessage.AdditionalInfo();
+	TUint numberOfElements = additionalAttributes->NumberOfControlInformationElements(category);
+
+	for (TUint i = 0; i < numberOfElements; i++)
+	    {
+	    CSmsInformationElement::TSmsInformationElementIdentifier id = CSmsInformationElement::ESmsIEMaximum;
+	    
+	    // If function leaves, allow the error to propagate upwards
+	    id = additionalAttributes->GetControlInformationElementL(category, i).Identifier();
+
+	    if (id == CSmsInformationElement::ESmsReplyAddressFormat)
+	        {
+	        TGsmuLex8 encodedAddress(additionalAttributes->GetControlInformationElementL(category, i).Data());
+	        TRAPD(err,address->DecodeL(encodedAddress));
+
+	        if (err == KErrNone)
+	            {
+	            found = ETrue;
+	            break;
+	            }
+	        else
+	            {
+	            User::Leave(KErrCorrupt);
+	            }
+	        }
+	    }
+
+	HBufC* buf = NULL;
+	if (found)
+	    {
+	    buf = HBufC::NewL(TGsmSmsTelNumberMaxLen); // 20 characters preceeded by '+'
+	    *buf = address->Address();
+	    }
+	else
+	    {
+	    User::Leave(KErrNotFound);
+	    }
+
+	CleanupStack::PopAndDestroy(address);
+
+	return buf;
+	} // CSmsReplyAddressOperations::GetReplyAddressL
+
+
+/**
+ *  @publishedAll
+ *  
+ *  Returns the reply address in ETSI format.
+ *  
+ *  @return
+ *  True, if the CSmsMessage contains a reply address.
+ *  False, otherwise
+ *  @leave KErrNotSupported
+ *  If the message version or type does not support this query.
+ *  @leave KErrCorrupt
+ *  If the reply address is corrupt
+ *  @capability None
+ */
+EXPORT_C TInt  CSmsReplyAddressOperations::GetParsedReplyAddressL(TGsmSmsTelNumber& aParsedAddress) const
+	{
+	LOGGSMU1("CSmsReplyAddressOperations::GetParsedReplyAddressL");
+
+	ValidateOperationL();
+
+	TBool rc = EFalse;
+
+	CSmsAddress* address = CSmsAddress::NewL(iCharacterSetConverter,iFs);
+	CleanupStack::PushL(address);
+
+	TSmsInformationElementCategories::TInformationElementCategory category;
+
+	if (TSmsInformationElementCategories::GetCategoryDefinition(CSmsInformationElement::ESmsReplyAddressFormat, category) == EFalse)
+		{
+		User::Leave(KErrArgument);
+		}
+
+	CSmsMessageAdditionalAttributes* additionalAttributes = (CSmsMessageAdditionalAttributes*) iMessage.AdditionalInfo();
+	TUint numberOfElements = additionalAttributes->NumberOfControlInformationElements(category);
+
+	for (TUint i = 0; i < numberOfElements; i++)
+	    {
+	    CSmsInformationElement::TSmsInformationElementIdentifier id = CSmsInformationElement::ESmsIEMaximum;
+	    
+	    // If function leaves, allow the error to propagate upwards
+	    id = additionalAttributes->GetControlInformationElementL(category, i).Identifier();
+
+	    // CSmsAddress is used here for encoding the reply address into an IE.
+	    // It also used to encode the source / destination address in the CSmsMessage.
+	    // 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.
+	    if (id == CSmsInformationElement::ESmsReplyAddressFormat)
+	        {
+	        TBuf8<CSmsAddress::KSmsAddressMaxAddressLength> data;
+	        data = additionalAttributes->GetControlInformationElementL(category, i).Data();
+	        TUint8 actualDataLength = data.Length();
+	        data.SetLength(CSmsAddress::KSmsAddressMaxAddressLength);
+	        for (TUint8 j = actualDataLength; j < CSmsAddress::KSmsAddressMaxAddressLength; j++)
+	            {
+	            data[j] = 0;
+	            }
+
+	        TGsmuLex8 encodedAddress(data);
+	        TRAPD(err,address->DecodeL(encodedAddress));
+	        if (err==KErrNone)
+	            {
+	            address->ParsedAddress(aParsedAddress);
+	            rc = ETrue;
+	            break;
+	            }
+	        else
+	            {
+	            User::Leave(KErrCorrupt);
+	            }
+	        }
+	    }
+
+	CleanupStack::PopAndDestroy(address);
+
+	return rc;
+	} // CSmsReplyAddressOperations::GetParsedReplyAddressL
+
+
+/**
+ *  @publishedAll
+ *  
+ *  Removes the reply address information element.
+ *  
+ *  @leave KErrNotSupported
+ *  If the message version or type does not support this query.
+ *  @capability None
+ */
+EXPORT_C void  CSmsReplyAddressOperations::RemoveReplyAddressL() const
+	{
+	LOGGSMU1("CSmsReplyAddressOperations::RemoveReplyAddress");
+
+	ValidateOperationL();
+
+	TSmsInformationElementCategories::TInformationElementCategory category;
+
+	if (TSmsInformationElementCategories::GetCategoryDefinition(CSmsInformationElement::ESmsReplyAddressFormat, category) == EFalse)
+		{
+		User::Leave(KErrArgument);
+		}
+
+	CSmsMessageAdditionalAttributes* additionalAttributes = (CSmsMessageAdditionalAttributes*) iMessage.AdditionalInfo();
+	TUint numberOfElements = additionalAttributes->NumberOfControlInformationElements(category);
+
+	for (TInt i = 0; i < numberOfElements; i++)
+	    {
+	    CSmsInformationElement::TSmsInformationElementIdentifier id = CSmsInformationElement::ESmsIEMaximum;
+	    
+	    // If function leaves, allow the error to propagate upwards
+	    id = additionalAttributes->GetControlInformationElementL(category, i).Identifier();
+
+	    if (id == CSmsInformationElement::ESmsReplyAddressFormat)
+	        {
+	        additionalAttributes->DeleteControlInformationElement(category, i);
+	        break;
+	        }
+	    }
+	} // CSmsReplyAddressOperations::RemoveReplyAddressL
+
+
+CSmsReplyAddressOperations::CSmsReplyAddressOperations(CSmsInformationElement::TSmsInformationElementIdentifier aId,  CSmsMessage& aMessage,
+                                                       CCnvCharacterSetConverter& aCharacterSetConverter, RFs& aFs) : CSmsCtrlOperation(aId, aMessage),
+                                                       iCharacterSetConverter(aCharacterSetConverter), iFs(aFs)
+	{
+	//NOP
+	} // CSmsReplyAddressOperations::CSmsReplyAddressOperations
+
+
+/**
+ *  @internalComponent
+ *  
+ *  Identifies whether the message type or version supports this operation
+ *  
+ *  @leave
+ *  If the message type or version does not support this operation.
+ */
+void CSmsSpecialSMSMessageOperations::ValidateOperationL() const
+	{
+	LOGGSMU1("CSmsSpecialSMSMessageOperations::ValidateOperationL()");
+
+	if (iMessage.Version() < CSmsMessage::ESmsMessageV1)
+	    {
+	    LOGGSMU2("CSmsSpecialSMSMessageOperations::AddSpecialMessageIndicationL, Operation not supported, version %d", iMessage.Version());
+	    User::Leave(KErrNotSupported);
+	    }
+
+	if (!MessageTypeSupported())
+	    {
+	    LOGGSMU2("CSmsSpecialSMSMessageOperations::AddSpecialMessageIndicationL, Operation not supported by this PDU type, type = %d", iMessage.Type());
+	    User::Leave(KErrNotSupported);
+	    }
+	} // CSmsSpecialSMSMessageOperations::ValidateOperationL
+
+
+/**
+ *  @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 CSmsSpecialSMSMessageOperations::operator=(const CSmsSpecialSMSMessageOperations&)
+    {
+    // Ignore in code coverage - not intended to be used
+    BULLSEYE_OFF    
+    LOGGSMU1("CSmsSpecialSMSMessageOperations::operator=");
+    Panic(KGsmuPanicMethodBodyNotImplemented1);
+    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 CSmsSpecialSMSMessageOperations::operator==(const CSmsSpecialSMSMessageOperations&)
+	{
+	LOGGSMU1("CSmsSpecialSMSMessageOperations::operator==");
+	Panic(KGsmuPanicMethodBodyNotImplemented1);
+	return EFalse;
+	} // CSmsSpecialSMSMessageOperations::operator
+
+
+/**
+ *  @publishedAll
+ *  
+ *  Either adds a new or updates an existing special message indication information element.
+ *  
+ *  @param aStore
+ *  Indicates whether or not the message shall be stored.
+ *  @param aMessageIndicationType
+ *  Indicates the basic message type
+ *  @param aExtendedType
+ *  Indicates the extended message type
+ *  @param aProfile
+ *  Indicates the profile ID of the Multiple Subscriber Profile
+ *  @param aMessageCount
+ *  Indicates the number of messages of the type specified in Octet 1 that are waiting
+ *  @leave KErrNotSupported
+ *  If the message version or type does not support this query.
+ *  @capability None
+ */
+EXPORT_C void CSmsSpecialSMSMessageOperations::AddSpecialMessageIndicationL(TBool aStore,
+                                                                            TSmsMessageIndicationType aMessageIndicationType,
+                                                                            TExtendedSmsIndicationType aExtendedType,
+                                                                            TSmsMessageProfileType aProfile,
+                                                                            TUint8 aMessageCount) const
+	{
+	LOGGSMU1("CSmsSpecialSMSMessageOperations::AddSpecialMessageIndicationL");
+
+	ValidateOperationL();
+
+	CSmsUserData& userData = iMessage.SmsPDU().UserData();
+
+	TBuf8<2> data;
+	data.SetLength(2);
+
+	data[0] = ( ((TUint8) aMessageIndicationType) +
+	            ((TUint8) (aExtendedType << 2))   +
+	            ((TUint8) (aProfile      << 5))   +
+	            ((TUint8) (aStore        << 7)) );
+
+	data[1] = aMessageCount;
+
+	CArrayFixFlat<TInt>* indices = new(ELeave) CArrayFixFlat<TInt>(4);
+	CleanupStack::PushL(indices);
+	userData.InformationElementIndicesL(CSmsInformationElement::ESmsIEISpecialSMSMessageIndication, *indices);
+
+	TBool found = EFalse;
+	TInt count = indices->Count();
+	for (TInt i=0; ((i<count) && (found==EFalse)); i++)
+	    {
+		TUint index = indices->operator[](i);
+		CSmsInformationElement& ieAlreadyInWorkingPDU = userData.InformationElement(index);
+
+	    if (ieAlreadyInWorkingPDU.Data()[0] == data[0])
+	        {
+	        ieAlreadyInWorkingPDU.Data()[1] = data[1];
+	        found = ETrue;
+	        break;
+	        }
+	    }
+	CleanupStack::PopAndDestroy(indices);
+
+	if (found == EFalse)
+	    {
+	    userData.AddInformationElementL(CSmsInformationElement::ESmsIEISpecialSMSMessageIndication,data);
+	    }
+	} // CSmsSpecialSMSMessageOperations::AddSpecialMessageIndicationL
+
+
+/**
+ *  @publishedAll
+ *  
+ *  Gets a count of the number of special message indication information elements which
+ *  are stored inside the user data.
+ *  
+ *  @return The number of special message indication information elements which
+ *  are stored inside the user data.
+ *  @leave KErrNotSupported
+ *  If the message version or type does not support this query.
+ *  @capability None
+ */
+EXPORT_C TUint CSmsSpecialSMSMessageOperations::GetCountOfSpecialMessageIndicationsL() const
+	{
+	LOGGSMU1("CSmsSpecialSMSMessageOperations::GetCountOfSpecialMessageIndicationsL()");
+
+	ValidateOperationL();
+
+	CSmsUserData& userData = iMessage.SmsPDU().UserData();
+
+	CArrayFixFlat<TInt>* indices = new (ELeave) CArrayFixFlat<TInt>(8);
+	CleanupStack::PushL(indices);
+	userData.InformationElementIndicesL(CSmsInformationElement::ESmsIEISpecialSMSMessageIndication,*indices);
+	TUint  count = indices->Count();
+	CleanupStack::PopAndDestroy(indices);
+
+	return count;
+	} // CSmsSpecialSMSMessageOperations::GetCountOfSpecialMessageIndicationsL
+
+
+/**
+ *  @publishedAll
+ *  
+ *  Gets the attributes of the Special Message Indication specified by aIndex.
+ *  
+ *  @param aIndex
+ *  aIndex is a value less than GetCountOfSpecialMessageIndications().
+ *  @param aStore
+ *  Indicates whether or not the message shall be stored.
+ *  @param aMessageIndicationType
+ *  Indicates the basic message type
+ *  @param aExtendedType
+ *  Indicates the extended message type
+ *  @param aProfile
+ *  Indicates the profile ID of the Multiple Subscriber Profile
+ *  @param aMessageCount
+ *  Indicates the number of messages of the type specified in Octet 1 that are waiting
+ *  @leave KErrNotSupported
+ *  If the message version or type does not support this query.
+ *  @leave KErrArgument
+ *  If aIndex is >= GetCountOfSpecialMessageIndications()
+ *  @capability None
+ */
+EXPORT_C void CSmsSpecialSMSMessageOperations::GetMessageIndicationIEL(TUint aIndex,
+                                                                       TBool& aStore,
+                                                                       TSmsMessageIndicationType& aMessageIndicationType,
+                                                                       TExtendedSmsIndicationType& aExtendedType,
+                                                                       TSmsMessageProfileType&  aProfile,
+                                                                       TUint8& aMessageCount) const
+	{
+	LOGGSMU1("CSmsSpecialSMSMessageOperations::GetMessageIndicationIEL()");
+
+	ValidateOperationL();
+
+	CSmsUserData& userData = iMessage.SmsPDU().UserData();
+
+	CArrayFixFlat<TInt>* indices = new (ELeave) CArrayFixFlat<TInt>(8);
+	CleanupStack::PushL(indices);
+	userData.InformationElementIndicesL(CSmsInformationElement::ESmsIEISpecialSMSMessageIndication,*indices);
+
+	if (aIndex < indices->Count())
+	    {
+	    CSmsInformationElement& informationElement = userData.InformationElement((*indices)[aIndex]);
+
+	    aMessageIndicationType =  (TSmsMessageIndicationType)   (informationElement.Data()[0]       & 0x03);
+	    aExtendedType          =  (TExtendedSmsIndicationType) ((informationElement.Data()[0] >> 2) & 0x07);
+	    aProfile               =  (TSmsMessageProfileType)     ((informationElement.Data()[0] >> 5) & 0x03);
+	    aStore                 =  (TBool)                      ((informationElement.Data()[0] >> 7) & 0x01);
+	    aMessageCount          =  (TUint8)                      (informationElement.Data()[1]);
+	    }
+	else
+	    {
+	    User::Leave(KErrArgument);
+	    }
+
+	CleanupStack::PopAndDestroy(indices);
+	} // CSmsSpecialSMSMessageOperations::GetMessageIndicationIEL
+
+
+/**
+ *  @publishedAll
+ *  
+ *  Removes the Special Message Indication specified by the input attributes, provided it exists.
+ *  
+ *  @param aMessageIndicationType
+ *  Indicates the basic message type
+ *  @param aExtendedType
+ *  Indicates the extended message type
+ *  @leave KErrNotSupported
+ *  If the message version or type does not support this query.
+ *  @capability None
+ */
+EXPORT_C void CSmsSpecialSMSMessageOperations::RemoveSpecialMessageIndicationL(TSmsMessageIndicationType aMessageIndicationType, TExtendedSmsIndicationType aExtendedType) const
+	{
+	LOGGSMU1("CSmsSpecialSMSMessageOperations::RemoveAllSpecialMessageIndications");
+
+	ValidateOperationL();
+
+	CSmsUserData& userData = iMessage.SmsPDU().UserData();
+
+	CArrayFixFlat<TInt>* indices = new (ELeave) CArrayFixFlat<TInt>(8);
+	CleanupStack::PushL(indices);
+	userData.InformationElementIndicesL(CSmsInformationElement::ESmsIEISpecialSMSMessageIndication,*indices);
+
+	TUint i = indices->Count();
+
+	while (i-- != 0)
+	    {
+	    CSmsInformationElement& informationElement = userData.InformationElement((*indices)[i]);
+
+	    TSmsMessageIndicationType          type = ((TSmsMessageIndicationType)   (informationElement.Data()[0]       & 0x03));
+	    TExtendedSmsIndicationType extendedType =  (TExtendedSmsIndicationType) ((informationElement.Data()[0] >> 2) & 0x07);
+
+	    if ( (aMessageIndicationType == type) &&
+	         (aExtendedType == extendedType) )
+	        {
+	        userData.RemoveInformationElement((*indices)[i]);
+	        break;
+	        }
+	    }
+
+	CleanupStack::PopAndDestroy(indices);
+	} // CSmsSpecialSMSMessageOperations::RemoveSpecialMessageIndicationL
+
+
+/**
+ *  @publishedAll
+ *  
+ *  Removes all Special Message Indications Information Elements contained in the message.
+ *  
+ *  @leave KErrNotSupported
+ *  If the message version or type does not support this query.
+ *  @capability None
+ */
+EXPORT_C void CSmsSpecialSMSMessageOperations::RemoveAllSpecialMessageIndicationsL() const
+	{
+	LOGGSMU1("CSmsSpecialSMSMessageOperations::RemoveAllSpecialMessageIndicationsL");
+
+	ValidateOperationL();
+
+	CSmsUserData& userData = iMessage.SmsPDU().UserData();
+
+	CArrayFixFlat<TInt>* indices = new (ELeave) CArrayFixFlat<TInt>(8);
+	CleanupStack::PushL(indices);
+	userData.InformationElementIndicesL(CSmsInformationElement::ESmsIEISpecialSMSMessageIndication,*indices);
+
+	TUint i = indices->Count();
+
+	while (i-- != 0)
+	   {
+	   userData.RemoveInformationElement((*indices)[i]);
+	   }
+
+	CleanupStack::PopAndDestroy(indices);
+	} // CSmsSpecialSMSMessageOperations::RemoveAllSpecialMessageIndicationsL
+
+
+CSmsSpecialSMSMessageOperations::CSmsSpecialSMSMessageOperations(CSmsInformationElement::TSmsInformationElementIdentifier aId, CSmsMessage& aMessage) : CSmsCtrlOperation(aId, aMessage)
+	{
+	//NOP
+	} // CSmsSpecialSMSMessageOperations::CSmsSpecialSMSMessageOperations
+
+
+/**
+ *  @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 CSmsEnhancedVoiceMailOperations::operator=(const CSmsEnhancedVoiceMailOperations&)
+    {
+    // Ignore in code coverage - not intended to be used
+    BULLSEYE_OFF    
+    LOGGSMU1("CSmsEnhancedVoiceMailOperations::operator=");
+    Panic(KGsmuPanicMethodBodyNotImplemented1);
+    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 CSmsEnhancedVoiceMailOperations::operator==(const CSmsEnhancedVoiceMailOperations&)
+    {
+    // Ignore in code coverage - not intended to be used
+    BULLSEYE_OFF    
+    LOGGSMU1("CSmsEnhancedVoiceMailOperations::operator==");
+    Panic(KGsmuPanicMethodBodyNotImplemented1);
+    return EFalse;
+    BULLSEYE_RESTORE
+    }
+
+/**
+ *  @internalComponent
+ *  
+ *  Identifies whether the message type or version supports this operation
+ *  
+ *  @leave
+ *  If the message type or version does not support this operation.
+ */
+void CSmsEnhancedVoiceMailOperations::ValidateOperationL() const
+	{
+	LOGGSMU1("CSmsEnhancedVoiceMailOperations::ValidateOperationL()");
+
+	if (iMessage.Version() < CSmsMessage::ESmsMessageV1)
+	    {
+	    LOGGSMU2("CSmsEnhancedVoiceMailInformation::AddEnhancedVoiceMailIEL, Operation not supported, Msg Version %d", iMessage.Version());
+	    User::Leave(KErrNotSupported);
+	    }
+
+	if (!MessageTypeSupported())
+	    {
+	    LOGGSMU2("CSmsSpecialSMSMessageOperations::AddEnhancedVoiceMailIEL, Operation not supported by this PDU type, type = %d", iMessage.Type());
+	    User::Leave(KErrNotSupported);
+	    }
+	} // CSmsEnhancedVoiceMailOperations::ValidateOperationL
+
+
+/**
+ *  @publishedAll
+ *  
+ *  Adds an Enhanced Voice Mail Information Element to the CSmsMessage.
+ *  The information element can be either an Enhanced Voice Mail Notification or
+ *  an Enhanced Voice Mail Delete Confirmation. Enhanced Voice Mail Notifications
+ *  and Enhanced Voice Mail Delete Confirmations are abstracted in classes derived
+ *  from CEnhancedVoiceMailBoxInformation.
+ *  @param aEVMI
+ *  A pointer to the Enhanced Voice Mail Information Element.
+ *  @leave KErrNotSupported
+ *  If the message version or type does not support this query.
+ *  @leave KErrAlreadyExists
+ *  If an Enhanced Voice Mail Information Element has already been installed.
+ *  @leave KErrArgument
+ *  If the input parameter contains invalid parameters.
+ *  @capability None
+ */
+EXPORT_C void CSmsEnhancedVoiceMailOperations::AddEnhancedVoiceMailIEL(const CEnhancedVoiceMailBoxInformation& aEVMI) const
+	{
+	LOGGSMU1("CSmsEnhancedVoiceMailInformation::AddEnhancedVoiceMailIEL");
+
+	ValidateOperationL();
+
+	if (ContainsEnhancedVoiceMailIEL())
+	    {
+	    LOGGSMU1("CSmsEnhancedVoiceMailInformation::AddEnhancedVoiceMailIEL, Already Exists");
+	    User::Leave(KErrAlreadyExists);
+	    }
+
+	CSmsMessageAdditionalAttributes& additionalAttributes = *((CSmsMessageAdditionalAttributes*) iMessage.AdditionalInfo());
+
+	// The Enhanced Voice Mail Information Element must fit into a single PDU.
+	// The maximum size for its data field is therefore
+	// the maximum size of the user data minus user data header length, the ie identifier byte and
+	// ie length byte.
+	TBuf8<CEnhancedVoiceMailBoxInformation::KSmsMaxEnhancedVoiceMailSize> voiceMailInfo;
+	voiceMailInfo.SetLength(CEnhancedVoiceMailNotification::KSmsMaxEnhancedVoiceMailSize);
+	TUint8* startPtr = &voiceMailInfo[0];
+	TUint8* endPtr = aEVMI.EncodeL(startPtr, iCharacterSetConverter, iFs);
+	TInt length = (TInt) (endPtr - startPtr);
+	voiceMailInfo.SetLength(length);
+
+	CSmsInformationElement* iE = CSmsInformationElement::NewL(CSmsInformationElement::CSmsInformationElement::ESmsEnhanceVoiceMailInformation, voiceMailInfo);
+	CleanupStack::PushL(iE);
+
+	additionalAttributes.AddControlInformationElementL(iE);
+	CleanupStack::Pop();
+	} // CSmsEnhancedVoiceMailOperations::AddEnhancedVoiceMailIEL
+
+
+/**
+ *  @publishedAll
+ *  
+ *  Removes the Enhanced Voice Mail Information Element from the CSmsMessage,
+ *  provided it exists.
+ *  @leave KErrNotSupported
+ *  If the message version or type does not support this query.
+ *  @leave KErrNotFound
+ *  If the CSmsMessage does not contain an Enhanced Voice Mail Information Element
+ *  @capability None
+ */
+EXPORT_C CEnhancedVoiceMailBoxInformation* CSmsEnhancedVoiceMailOperations::RemoveEnhancedVoiceMailIEL() const
+	{
+	LOGGSMU1("CSmsEnhancedVoiceMailInformation::RemoveEnhancedVoiceMailIE");
+
+	ValidateOperationL();
+
+	CEnhancedVoiceMailBoxInformation* voiceMailBoxInfo = NULL;
+	TBool deleteInformationElement = ETrue;
+	
+	// If function leaves, allow the error to propagate upwards
+	voiceMailBoxInfo = GetEnhancedVoiceMailIEL(deleteInformationElement);
+
+	return voiceMailBoxInfo;
+	} // CSmsEnhancedVoiceMailOperations::RemoveEnhancedVoiceMailIEL
+
+
+/**
+ *  @publishedAll
+ *  
+ *  Copies the Enhanced Voice Mail Information Element contained in the CSmsMessage,
+ *  provided one exists.
+ *  @leave KErrNotSupported
+ *  If the message version or type does not support this query.
+ *  @leave KErrNotFound
+ *  If the CSmsMessage does not contain an Enhanced Voice Mail Information Element to copy.
+ *  @capability None
+ */
+EXPORT_C CEnhancedVoiceMailBoxInformation* CSmsEnhancedVoiceMailOperations::CopyEnhancedVoiceMailIEL() const
+	{
+	LOGGSMU1("CSmsEnhancedVoiceMailInformation::CopyEnhancedVoiceMailIEL");
+
+	ValidateOperationL();
+
+	CEnhancedVoiceMailBoxInformation* voiceMailBoxInfo = NULL;
+	TBool deleteInformationElement = EFalse;
+	
+	// If function leaves, allow the error to propagate upwards
+	voiceMailBoxInfo = GetEnhancedVoiceMailIEL(deleteInformationElement);
+
+	return voiceMailBoxInfo;
+	} // CSmsEnhancedVoiceMailOperations::CopyEnhancedVoiceMailIEL
+
+
+/**
+ *  @internalComponent
+ *  
+ *  Returns a copy of the Enhanced Voice Mail Information Element contained in the CSmsMessage,
+ *  provided one exists. Optionally deletes the information element.
+ *  @param aRemove
+ *  Indicates that the information element should be deleted once its contents have been copied.
+ *  @leave KErrNotFound
+ *  If the CSmsMessage does not contain an Enhanced Voice Mail Information Element to copy.
+ */
+CEnhancedVoiceMailBoxInformation* CSmsEnhancedVoiceMailOperations::GetEnhancedVoiceMailIEL(TBool aRemove) const
+	{
+	LOGGSMU1("CSmsEnhancedVoiceMailOperations::GetEnhancedVoiceMailIEL()");
+
+	TBool found = EFalse;
+
+	CEnhancedVoiceMailBoxInformation* voiceMailBoxInfo = NULL;
+
+	TSmsInformationElementCategories::TInformationElementCategory category;
+
+	if (TSmsInformationElementCategories::GetCategoryDefinition(CSmsInformationElement::ESmsEnhanceVoiceMailInformation, category) == EFalse)
+		{
+		User::Leave(KErrArgument);
+		}
+
+	CSmsMessageAdditionalAttributes* additionalAttributes = (CSmsMessageAdditionalAttributes*) iMessage.AdditionalInfo();
+	TUint numberOfElements = additionalAttributes->NumberOfControlInformationElements(category);
+
+	for (TUint i = 0; i < numberOfElements; i++)
+	    {
+	    CSmsInformationElement::TSmsInformationElementIdentifier id = CSmsInformationElement::ESmsIEMaximum;
+	    id = additionalAttributes->GetControlInformationElementL(category, i).Identifier();
+
+	    if (id == CSmsInformationElement::CSmsInformationElement::ESmsEnhanceVoiceMailInformation)
+	        {
+	        if (additionalAttributes->GetControlInformationElementL(category, i).Data()[0] & 0x01)
+	            {
+	            voiceMailBoxInfo = CEnhancedVoiceMailDeleteConfirmations::NewL();
+	            }
+	        else
+	            {
+	            voiceMailBoxInfo = CEnhancedVoiceMailNotification::NewL();
+	            }
+
+	        CleanupStack::PushL(voiceMailBoxInfo);
+	        TGsmuLex8 encodedVoiceMailBox(additionalAttributes->GetControlInformationElementL(category, i).Data());
+	        voiceMailBoxInfo->DecodeL(encodedVoiceMailBox, iCharacterSetConverter, iFs);
+	        CleanupStack::Pop(voiceMailBoxInfo);
+
+	        if (aRemove)
+	            {
+	            additionalAttributes->DeleteControlInformationElement(category, i);
+	            }
+
+	        found = ETrue;
+
+	        break;
+	        }
+	    }
+
+	if (found == EFalse)
+	    {
+	    User::Leave(KErrNotFound);
+	    }
+
+	return voiceMailBoxInfo;
+	} // CSmsEnhancedVoiceMailOperations::GetEnhancedVoiceMailIEL
+
+
+/**
+ *  @publishedAll
+ *  
+ *  Determines whether the CSmsMessage contains an Enhanced Voice Mail Information Element.
+ *  @leave KErrNotSupported
+ *  If the message version or type does not support this query.
+ *  @return
+ *  True if the CSmsMessage contains an Enhanced Voice Mail Information Element.
+ *  @capability None
+ */
+EXPORT_C TBool CSmsEnhancedVoiceMailOperations::ContainsEnhancedVoiceMailIEL() const
+	{
+	LOGGSMU1("CSmsEnhancedVoiceMailInformation::ContainsEnhancedVoiceMailIEL");
+
+	ValidateOperationL();
+
+	TBool rc = EFalse;
+
+	TSmsInformationElementCategories::TInformationElementCategory category;
+
+	if (TSmsInformationElementCategories::GetCategoryDefinition(CSmsInformationElement::ESmsEnhanceVoiceMailInformation, category) == EFalse)
+		{
+		User::Leave(KErrArgument);
+		}
+
+	CSmsMessageAdditionalAttributes* additionalAttributes = (CSmsMessageAdditionalAttributes*) iMessage.AdditionalInfo();
+	TUint numberOfElements = additionalAttributes->NumberOfControlInformationElements(category);
+
+	for (TUint i = 0; i < numberOfElements; i++)
+	    {
+	    CSmsInformationElement::TSmsInformationElementIdentifier id = CSmsInformationElement::ESmsIEMaximum;
+	    
+	    // If function leaves, allow the error to propagate upwards
+	    id = additionalAttributes->GetControlInformationElementL(category, i).Identifier();
+
+	    if (id == CSmsInformationElement::ESmsEnhanceVoiceMailInformation)
+	        {
+	        rc = ETrue;
+	        break;
+	        }
+	    }
+
+	return rc;
+	} // CSmsEnhancedVoiceMailOperations::ContainsEnhancedVoiceMailIEL
+
+
+/**
+ *  Status Reporting.
+ *  
+ *  @note This should be the last thing that should be configured in CSmsMessage.
+ *  If anything is changed after this then the number of PDUs might change which
+ *  will affect status reporting.
+ */
+CSmsEnhancedVoiceMailOperations::CSmsEnhancedVoiceMailOperations(CSmsInformationElement::TSmsInformationElementIdentifier aId,  CSmsMessage& aMessage,
+                                                                 CCnvCharacterSetConverter& aCharacterSetConverter, RFs& aFs) : CSmsCtrlOperation(aId, aMessage),
+                                                                 iCharacterSetConverter(aCharacterSetConverter), iFs(aFs)
+	{
+	// NOP
+	} // CSmsEnhancedVoiceMailOperations::CSmsEnhancedVoiceMailOperations
+
+
+CSmsSMSCCtrlParameterOperations::CSmsSMSCCtrlParameterOperations(CSmsInformationElement::TSmsInformationElementIdentifier aId, CSmsMessage& aMessage)
+: CSmsCtrlOperation(aId, aMessage)
+	{
+	
+	} // CSmsSMSCCtrlParameterOperations::CSmsSMSCCtrlParameterOperations
+	
+
+/**
+ *  @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 CSmsSMSCCtrlParameterOperations::operator=(const CSmsSMSCCtrlParameterOperations&)
+    {
+    // Ignore in code coverage - not intended to be used
+    BULLSEYE_OFF    
+    LOGGSMU1("CSmsSMSCCtrlParameterOperations::operator=");
+    Panic(KGsmuPanicMethodBodyNotImplemented1);
+    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 CSmsSMSCCtrlParameterOperations::operator==(const CSmsSMSCCtrlParameterOperations&)
+    {
+    // Ignore in code coverage - not intended to be used
+    BULLSEYE_OFF    
+    LOGGSMU1("CSmsSMSCCtrlParameterOperations::operator==");
+    Panic(KGsmuPanicMethodBodyNotImplemented1);
+    return EFalse;
+    BULLSEYE_RESTORE
+    }
+
+/**
+ *  @internalComponent
+ *  
+ *  Identifies whether the message type or version supports this operation
+ *  
+ *  @leave
+ *  If the message type or version does not support this operation.
+ */
+void CSmsSMSCCtrlParameterOperations::ValidateOperationL() const
+	{
+	if (iMessage.Version() < CSmsMessage::ESmsMessageV2)
+	    {
+	    LOGGSMU2("CSmsSMSCCtrlParameterOperations Operation not supported, Msg Version %d", iMessage.Version());
+	    User::Leave(KErrNotSupported); 
+	    }
+
+	if (!MessageTypeSupported())
+	    {
+	    LOGGSMU2("CSmsSMSCCtrlParameterOperations Operation not supported by this PDU type, type = %d", iMessage.Type());
+	    User::Leave(KErrNotSupported);
+	    }
+	} // CSmsSMSCCtrlParameterOperations::ValidateOperationL()
+
+
+/**
+ *  @internalComponent
+ *  
+ *  Checks that the octet passed to it has the valid bits set in it. If the bits which 
+ *  are not supported yet are set then reset it. 
+ *  This method is called by SetStatusReportL.
+ *  
+ *  @param aSelectiveStatus
+ *  The octet which needs to be set as the Selective Status for the report.
+ *  @return
+ *  ETrue if the selective status is valid.
+ *  @leave KErrNotSupported
+ *  If the last 4 bits are set as they are not supported.
+ */
+TBool CSmsSMSCCtrlParameterOperations::ValidateControlParametersL(TUint8& aSelectiveStatus) const
+	{
+	if (aSelectiveStatus & ESmsStatusReportForFutureUse1)
+		{
+		User::Leave(KErrNotSupported);
+		}
+		
+	if (aSelectiveStatus & ESmsStatusReportForFutureUse2)
+		{
+		User::Leave(KErrNotSupported);	
+		}
+		
+	if (aSelectiveStatus & ESmsStatusReportCancelRestSRR)
+		{
+		User::Leave(KErrNotSupported);	
+		}
+		
+	if (aSelectiveStatus & ESmsStatusReportIncludeOriginalUDH)
+		{
+		User::Leave(KErrNotSupported);
+		}
+	
+	return ETrue;	
+	} // CSmsSMSCCtrlParameterOperations::ValidateControlParametersL
+
+
+/**
+ *  @publishedAll
+ *  
+ *  Sets the status report for a PDU. First the scheme is obtained by calling the 
+ *  GetStatusReportScheme and checked if it is the valid scheme. Then aSelectiveStatus is 
+ *  checked to see if it is the default value. If it is then nothing is done. But if 
+ *  aSelectiveStatus is non-default then it is appended to the array 
+ *  iControlParametersStatusReport along with the aSegmentSequenceNum 
+ *  
+ *  @param aSegmentSequenceNum
+ *  The segment sequence number of the PDU which needs to be updated.
+ *  @param aSelectiveStatus
+ *  The octet which needs to be set as the Selective Status for the report.
+ *  @return KErrNone if the operation is successful.
+ *  KErrNotFound if the Segment Sequence Number is out of range or the scheme is inavlid.
+ *  KErrNotSupported if aSelectiveStatus is not valid.
+ *  @leave
+ *  If ValidateOperationL or AppendL leaves.
+ *  @capability None
+ */
+EXPORT_C TInt CSmsSMSCCtrlParameterOperations::SetStatusReportL(TUint aSegmentSequenceNum, TUint8 aSelectiveStatus)
+	{
+	ValidateOperationL();
+	TBool validateStatus = ValidateControlParametersL(aSelectiveStatus);
+	
+	if(validateStatus)
+		{
+		CSmsMessageAdditionalAttributes& additionalAttributes = *((CSmsMessageAdditionalAttributes*) iMessage.AdditionalInfo());
+		CSmsMessageAdditionalAttributes::CSmsStatusReportScheme& scheme = additionalAttributes.GetStatusReportScheme();
+		if (scheme.Id() == EControlParametersScheme)
+			{
+			CSmsMessageAdditionalAttributes::CControlParametersScheme& ctrlParamsScheme = (CSmsMessageAdditionalAttributes::CControlParametersScheme&)scheme;
+			if(aSegmentSequenceNum>=ctrlParamsScheme.iNumOfPDUs)
+				{
+				return KErrNotFound;	//	aSegmentSequenceNum out of range.
+				}
+			if (aSelectiveStatus == ctrlParamsScheme.iDefaultStatusReport)
+				{
+				return KErrNone;	// It's the same as default so need for any updation.
+				}
+			else
+				{
+				TInt count = (ctrlParamsScheme.iControlParametersStatusReport).Count();
+				TBool found(EFalse);
+				for (TInt ii=0; !found && ii<count; ii++)
+					{
+					if ((ctrlParamsScheme.iControlParametersStatusReport[ii]).iSegmentSequenceNum == aSegmentSequenceNum)
+						{
+						(ctrlParamsScheme.iControlParametersStatusReport[ii]).iSelectiveStatus = aSelectiveStatus;
+						found = ETrue;
+						break;
+						}
+					}
+					
+				if (!found)
+					{
+					CSmsMessageAdditionalAttributes::CControlParametersScheme::TSmsSMSCCtrlParameterStatus smscCtrlParameterStatus;
+					smscCtrlParameterStatus.iSegmentSequenceNum = aSegmentSequenceNum;
+					smscCtrlParameterStatus.iSelectiveStatus = aSelectiveStatus;
+					(ctrlParamsScheme.iControlParametersStatusReport).AppendL(smscCtrlParameterStatus);
+					}
+			
+				return KErrNone;	
+				}
+			}
+		else
+			{
+			return KErrNotFound;	//	Scheme not valid.
+			}
+		}
+	else
+		{
+		return KErrNotSupported;	//	Invalid aSlectiveStatus.
+		}
+	} // CSmsSMSCCtrlParameterOperations::SetStatusReportL
+
+
+/**
+ *  @publishedAll
+ *  
+ *  Gets the selective status for a PDU if the scheme is set to the Control
+ *  Parameters Scheme.
+ *  
+ *  @param aSegmentSequenceNum
+ *  The segment sequence number of the PDU whose status report is required.
+ *  @param aSelectiveStatus
+ *  Returns the selective status octet for that PDU.
+ *  
+ *  @return KErrNotFound if the segment sequence number or the scheme is invalid.
+ *  
+ *  @capability None
+ */
+EXPORT_C TInt CSmsSMSCCtrlParameterOperations::GetStatusReport(TUint aSegmentSequenceNum,
+															   TUint8& aSelectiveStatus) const
+	{
+	CSmsMessageAdditionalAttributes* additionalAttributes = (CSmsMessageAdditionalAttributes*) iMessage.AdditionalInfo();
+	CSmsMessageAdditionalAttributes::CSmsStatusReportScheme& scheme = additionalAttributes->GetStatusReportScheme();
+	if (scheme.Id() == EControlParametersScheme)
+		{
+		CSmsMessageAdditionalAttributes::CControlParametersScheme& ctrlParamsScheme = (CSmsMessageAdditionalAttributes::CControlParametersScheme&)scheme;
+		
+		if(aSegmentSequenceNum>=ctrlParamsScheme.iNumOfPDUs)
+			{
+			return KErrNotFound;	//	aSegmentSequenceNum out of range.
+			}
+
+		TInt count = (ctrlParamsScheme.iControlParametersStatusReport).Count();
+		
+		for (TInt ii=0; ii<count; ii++)
+			{
+			if (ctrlParamsScheme.iControlParametersStatusReport[ii].iSegmentSequenceNum == aSegmentSequenceNum)
+				{
+				aSelectiveStatus = ctrlParamsScheme.iControlParametersStatusReport[ii].iSelectiveStatus;
+				return KErrNone;
+				}
+			}
+			
+		aSelectiveStatus = ctrlParamsScheme.iDefaultStatusReport;
+		return KErrNone;
+		}
+
+	return KErrNotFound;
+	} // CSmsSMSCCtrlParameterOperations::GetStatusReport
+
+
+/**
+ *  @publishedAll
+ *  
+ *  Sets the default value of the status report to aDefaultSelectiveStatus.
+ *  
+ *  @param aDefaultSelectiveStatus
+ *  The selective status to be used as default.
+ *  @leave KErrNotFound
+ *  If the scheme is invalid.
+ *  @capability None
+ */
+EXPORT_C void CSmsSMSCCtrlParameterOperations::SetDefaultL(TUint8 aDefaultSelectiveStatus)
+	{
+	CSmsMessageAdditionalAttributes& additionalAttributes = *((CSmsMessageAdditionalAttributes*) iMessage.AdditionalInfo());
+	CSmsMessageAdditionalAttributes::CSmsStatusReportScheme& scheme = additionalAttributes.GetStatusReportScheme();
+	if (scheme.Id() == EControlParametersScheme)
+		{
+		CSmsMessageAdditionalAttributes::CControlParametersScheme& ctrlParamsScheme = (CSmsMessageAdditionalAttributes::CControlParametersScheme&)scheme;
+		if(aDefaultSelectiveStatus & ESmsSMSCControlParametersMask)
+			{
+			ctrlParamsScheme.iDefaultStatusReport = aDefaultSelectiveStatus;
+			}
+		else
+			{
+			ctrlParamsScheme.iDefaultStatusReport = 0x00;	
+			}
+		}
+	else
+		{
+		User::Leave(KErrNotFound);
+		}
+	} // CSmsSMSCCtrlParameterOperations::SetDefaultL
+
+
+/**
+ *  @publishedAll
+ *  
+ *  This method is called to set the scheme to Control Parameters Scheme.
+ *  First iStatusReportScheme, which is obtained by calling GetStatusReportScheme,
+ *  is deleted and set to NULL. Then a new scheme is created and a default value is set.
+ *  This should be the last method to be called in a message sending process as all the 
+ *  operations in this interface depend on the number of PDUs being set.
+ *  
+ *  @leave
+ *  If ValidateOperationL or NumMessagePDUsL leaves.
+ *  @capability None
+ */
+EXPORT_C void CSmsSMSCCtrlParameterOperations::SetSchemeL()
+	{
+	ValidateOperationL();
+	
+	CSmsMessageAdditionalAttributes& additionalAttributes = *((CSmsMessageAdditionalAttributes*) iMessage.AdditionalInfo());
+	additionalAttributes.SetStatusReportSchemeL(EControlParametersScheme);
+	
+	TBuf8 <1> buffer;
+	buffer.SetLength(1);
+	buffer[0] = 0;
+	
+	CSmsUserData& userData = iMessage.SmsPDU().UserData();
+
+	userData.AddInformationElementL(CSmsInformationElement::ESmsIEISMSCControlParameters,buffer);
+	
+	CSmsMessageAdditionalAttributes::CSmsStatusReportScheme& scheme = additionalAttributes.GetStatusReportScheme();
+	CSmsMessageAdditionalAttributes::CControlParametersScheme& ctrlParamsScheme = (CSmsMessageAdditionalAttributes::CControlParametersScheme&)scheme;
+	ctrlParamsScheme.iNumOfPDUs = iMessage.NumMessagePDUsL();
+
+	SetDefaultL(0);
+	} // CSmsSMSCCtrlParameterOperations::SetSchemeL
+
+
+/**
+ *  @publishedAll
+ *  
+ *  Gets the current scheme being used.
+ *  
+ *  @return
+ *  EControlParametrsScheme is returned when Control Parameters Scheme is being used.
+ *  @capability None
+ */
+EXPORT_C TSmsStatusReportScheme CSmsSMSCCtrlParameterOperations::GetScheme() const
+	{
+	CSmsMessageAdditionalAttributes* additionalAttributes = (CSmsMessageAdditionalAttributes*) iMessage.AdditionalInfo();
+		
+	return (additionalAttributes->GetStatusReportScheme()).Id();
+	} // CSmsSMSCCtrlParameterOperations::GetScheme
+
+
+/**
+ *  @publishedAll
+ *  
+ *  This method re-sets the scheme to the Default Scheme.
+ *  
+ *  @capability None
+ */
+EXPORT_C void CSmsSMSCCtrlParameterOperations::ResetSchemeL()
+	{
+	CSmsMessageAdditionalAttributes& additionalAttributes = *((CSmsMessageAdditionalAttributes*) iMessage.AdditionalInfo());
+	
+	CSmsUserData& userData = iMessage.SmsPDU().UserData();
+
+	CArrayFixFlat<TInt>* indices = new (ELeave) CArrayFixFlat<TInt>(8);
+	CleanupStack::PushL(indices);
+	userData.InformationElementIndicesL(CSmsInformationElement::ESmsIEISMSCControlParameters,*indices);
+
+	TUint i = indices->Count();
+
+	while (i-- != 0)
+	    {
+	    userData.RemoveInformationElement((*indices)[i]);
+	    }
+    
+    CleanupStack::PopAndDestroy(indices);
+    additionalAttributes.SetStatusReportSchemeL(EDefaultScheme);
+	} // CSmsSMSCCtrlParameterOperations::ResetSchemeL
+