webservices/wsxml/src/senxmlelement.cpp
changeset 0 62f9d29f7211
child 29 5743aa3a72c3
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/webservices/wsxml/src/senxmlelement.cpp	Thu Jan 07 16:19:19 2010 +0200
@@ -0,0 +1,1615 @@
+/*
+* Copyright (c) 2005 Nokia Corporation and/or its subsidiary(-ies). 
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:      
+*
+*/
+
+
+
+
+
+
+
+
+// INCLUDE FILES
+#include "SenXmlElement.h"
+#include "SenXmlConstants.h" // KSenColon, ++
+#include "SenXmlUtils.h"
+
+#include "senxmldebug.h"
+
+#ifdef SYMBIAN_SECURE_ECOM 
+    // for 2.8, 3.0 or newer:
+    #include <xml/attribute.h> // needed for RAttributeArray
+#else // for 2.6 or older
+    #include "Attribute.h"
+#endif
+
+using namespace Xml;
+
+namespace
+    {
+
+//    _LIT8(KColon,            ":");
+//    _LIT8(KLessThan,         "<");
+//    _LIT8(KGreaterThan,      ">");
+//    _LIT8(KSpace,            " ");
+//    _LIT8(KDblQuot,          "\"");
+//    _LIT8(KEqualsDblQuot,    "=\"");
+//    _LIT8(KSlashGreaterThan, "/>");
+//    _LIT8(KSenLessThanSlash,    "</");
+//    _LIT8(KSpaceXmlns,       " xmlns");
+//    _LIT8(KXmlns,            "xmlns");
+//    _LIT8(KXmlNsAttNamePlusColon, "xmlns:"); 
+    const TInt KFlatBufSize        = 64;
+    }
+
+
+EXPORT_C CSenXmlElement* CSenXmlElement::NewL(const TDesC8& aLocalName)
+    {
+    CSenXmlElement* pNew = new (ELeave) CSenXmlElement;
+    CleanupStack::PushL(pNew);
+    pNew->BaseConstructL(aLocalName);
+    CleanupStack::Pop(); // pNew;
+    return pNew;
+    }
+
+EXPORT_C CSenXmlElement* CSenXmlElement::NewL(const TDesC8& aNsUri,
+                                                const TDesC8& aLocalName)
+    {
+    CSenXmlElement* pNew = new (ELeave) CSenXmlElement;
+    CleanupStack::PushL(pNew);
+    pNew->BaseConstructL(aNsUri, aLocalName);
+    CleanupStack::Pop(); // pNew;
+    return pNew;
+    }
+
+EXPORT_C CSenXmlElement* CSenXmlElement::NewL(const TDesC8& aNsUri,
+                                                const TDesC8& aLocalName,
+                                                const TDesC8& aQName)
+    {
+    CSenXmlElement* pNew = new (ELeave) CSenXmlElement;
+    CleanupStack::PushL(pNew);
+    pNew->BaseConstructL(aNsUri, aLocalName, aQName);
+    CleanupStack::Pop(); // pNew;
+    return pNew;
+    }
+
+EXPORT_C CSenXmlElement* CSenXmlElement::NewL(const TDesC8& aNsUri,
+                                                const TDesC8& aLocalName,
+                                                const TDesC8& aQName,
+                                                const RAttributeArray& apAttrs)
+    {
+    CSenXmlElement* pNew = new (ELeave) CSenXmlElement;
+    CleanupStack::PushL(pNew);
+    pNew->BaseConstructL(aNsUri, aLocalName, aQName, apAttrs);
+    CleanupStack::Pop(); // pNew;
+    return pNew;
+    }
+
+
+EXPORT_C CSenXmlElement* CSenXmlElement::NewL(const TDesC8& aNsUri,
+                                                const TDesC8& aLocalName,
+                                                const TDesC8& aQName,
+                                                const RAttributeArray& apAttrs,
+                                                CSenElement& aParent)
+    {
+    CSenXmlElement* pNew = new (ELeave) CSenXmlElement;
+    CleanupStack::PushL(pNew);
+    pNew->BaseConstructL(aNsUri, aLocalName, aQName, apAttrs, aParent);
+    CleanupStack::Pop(); // pNew;
+    return pNew;
+    }
+
+EXPORT_C CSenXmlElement::CSenXmlElement()
+: ipLocalName(NULL),
+  ipContentBuf(NULL),
+  ipParent(NULL),
+  ipNamespace(NULL)
+    {
+    }
+
+EXPORT_C CSenXmlElement::~CSenXmlElement()
+    {
+    if(ipContentWriteStream)
+        {
+        ipContentWriteStream->Close();
+        delete ipContentWriteStream;
+        ipContentWriteStream = NULL;
+        }
+
+    if(ipAttrs)
+        {
+        ipAttrs->ResetAndDestroy();
+        delete ipAttrs;
+        ipAttrs = NULL; // not required
+        }
+    if(ipElements)
+        {
+        ipElements->ResetAndDestroy();
+        delete ipElements;
+        ipElements = NULL; // not required
+        }
+    if(ipNamespaces)
+        {
+        ipNamespaces->ResetAndDestroy();
+        delete ipNamespaces;
+        ipNamespaces = NULL; // not required
+        }
+
+    delete ipLocalName;
+    ipLocalName = NULL; // not required
+
+
+    delete ipContentBuf;
+    ipContentBuf = NULL; // not required
+
+    }
+
+
+
+EXPORT_C void CSenXmlElement::BaseConstructL(const TDesC8& aLocalName)
+    {
+    SenXmlUtils::LeaveOnInvalidElementNameL(aLocalName);
+    ipLocalName = aLocalName.AllocL();
+    }
+
+EXPORT_C void CSenXmlElement::BaseConstructL(const TDesC8& aNsUri,
+                                              const TDesC8& aLocalName)
+    {
+    SenXmlUtils::LeaveOnInvalidElementNameL(aLocalName);
+    if(aNsUri.Length()>0)
+        {
+        SetNamespaceL(aNsUri);
+        }
+    ipLocalName = aLocalName.AllocL();
+    }
+
+EXPORT_C void CSenXmlElement::BaseConstructL(   const TDesC8& aNsUri,
+                                                const TDesC8& aLocalName,
+                                                const TDesC8& aQName)
+    {
+    SenXmlUtils::LeaveOnInvalidElementNameL(aLocalName);
+    SenXmlUtils::LeaveOnInvalidElementNameL(aQName);
+    ipLocalName = aLocalName.AllocL();
+    TPtrC8 ptrPrefix(KNullDesC8);
+
+    if (aQName.Length() > 0 )
+        {
+        TInt colon = aQName.Locate(':');
+        if (colon > 0) // Note: 0 also treated as no prefix
+            {
+            ptrPrefix.Set(aQName.Ptr(),colon);
+            }
+        }
+
+    SetNamespaceL(ptrPrefix, aNsUri);
+    }
+
+EXPORT_C void CSenXmlElement::BaseConstructL(   const TDesC8& aNsUri,
+                                                const TDesC8& aLocalName,
+                                                const TDesC8& aQName,
+                                                const RAttributeArray& apAttrs)
+    {
+    BaseConstructL(aNsUri, aLocalName, aQName);
+    SetAttributesL(apAttrs);
+    }
+
+EXPORT_C void CSenXmlElement::BaseConstructL(   const TDesC8& aNsUri,
+                                                const TDesC8& aLocalName,
+                                                const TDesC8& aQName,
+                                                const RAttributeArray& apAttrs,
+                                                CSenElement& aParent    )
+    {
+    // parent must be set here at first line, because
+    // namespace setting dependends of it(!)
+    ipParent = &aParent;
+
+    BaseConstructL(aNsUri, aLocalName, aQName);
+    SetAttributesL(apAttrs);
+    }
+
+EXPORT_C void CSenXmlElement::SetAttributesL(const RAttributeArray& apAttrs)
+    {
+    AddAttributesL(apAttrs);
+    }
+
+
+EXPORT_C void CSenXmlElement::AddAttributesL(const RAttributeArray& apAttrs)
+    {
+    TInt count(apAttrs.Count());
+    HBufC8* qName = NULL;
+    for(TInt i=0; i<count; i++)
+        {
+        const TPtrC8 localname = apAttrs[i].Attribute().LocalName().DesC();
+        const TPtrC8 prefix = apAttrs[i].Attribute().Prefix().DesC();
+        const TPtrC8 value = apAttrs[i].Value().DesC();
+
+        SenXmlUtils::BuildQNameL(prefix, localname, qName);
+
+        CleanupStack::PushL(qName);
+
+        HBufC8* encodedValue = NULL;
+        TBool encoded = 
+            SenXmlUtils::EncodeHttpCharactersL(value, encodedValue);
+
+        if (encoded)
+            {
+            CleanupStack::PushL(encodedValue);
+            AddAttributeL(*qName, localname, *encodedValue); 
+            // note: this intentionally
+            // skips the 2 param 
+            // AddAttributeL() function
+
+            CleanupStack::PopAndDestroy(); // encodedValue
+            }
+        else
+            {
+            AddAttributeL(*qName, localname, value); 
+            // note: this intentionally
+            // skips the 2 param 
+            // AddAttributeL() function
+            }
+
+        CleanupStack::PopAndDestroy(); // qName
+        }
+    }
+
+EXPORT_C const TDesC8& CSenXmlElement::AddAttributeL(const TDesC8& aQName,
+                                                     const TDesC8& aLocalName,
+                                                     const TDesC8& aValue)
+    {
+    const TDesC8& nsPrefix = NsPrefix();
+    // first we check for possible namespace declarations...
+    if ( aQName == KSenXmlns || aLocalName == KSenXmlns)
+        {
+            if(nsPrefix.Length() > 0)
+                {
+                // we have an additional namespace declaration
+                AddNamespaceL(KNullDesC8(), aValue);
+                }
+            else
+                {
+                // this is a default name space declaration
+                SetNamespaceL(aValue);                
+                }
+                
+        }
+    else if (aLocalName == NsPrefix())
+        {
+        //we have a new declaration for the namespace of this element
+        SetNamespaceL(aLocalName, aValue);
+        }
+    else if(aQName.Find(KSenXmlNsAttNamePlusColon) == 0)
+        {
+        // we have an additional namespace declaration
+        AddNamespaceL(aLocalName, aValue);
+        }
+    else
+        {
+        // we have a real attribute!
+        CSenBaseAttribute* pAttribute = CSenBaseAttribute::NewL(aQName,
+                                                                aLocalName,
+                                                                aValue);
+        AddAttributeL(pAttribute);
+        }
+    return aValue;
+    }
+
+
+
+EXPORT_C const TDesC8& CSenXmlElement::AddAttributeL(const TDesC8& aAttrName,
+                                                      const TDesC8& aValue)
+    {
+    // note, the aAttrName may be a qualified name or simply localname
+    // strip off the possible prefix from possible qualified name:
+    TPtrC8 localName = SenXmlUtils::LocalName(aAttrName);
+    return AddAttributeL(aAttrName, localName, aValue);
+    }
+
+// takes the ownership of aAttribute
+EXPORT_C const TDesC8& CSenXmlElement::AddAttributeL(
+                                                CSenBaseAttribute* apAttribute)
+    {
+    CSenBaseAttribute* pOldAtt = FindAttr(apAttribute->Name());
+
+    // if attribute array is not yet allocated, instantiate here
+    if(!ipAttrs)
+        {
+        ipAttrs = new (ELeave) RPointerArray<CSenBaseAttribute>;
+        }
+
+    if(!pOldAtt)
+        {
+        // transfrer the ownership to this class:
+        ipAttrs->Append(apAttribute);
+        return apAttribute->Value();
+        }
+    else
+        {
+        pOldAtt->SetValueL(apAttribute->Value());
+        delete apAttribute;
+        apAttribute = NULL;
+        return pOldAtt->Value();
+        }
+    }
+
+
+EXPORT_C CSenBaseAttribute* CSenXmlElement::FindAttr(const TDesC8& aName)
+    {
+    if(ipAttrs)
+        {
+        TInt count(ipAttrs->Count());
+        for (TInt i = 0; i < count; i++)
+            {
+            CSenBaseAttribute* pAttribute = (*ipAttrs)[i];
+            if(pAttribute->Name() == aName)
+                {
+                return pAttribute;
+                }
+            }
+        }
+    return NULL;
+    }
+
+
+EXPORT_C TInt CSenXmlElement::IndexOfElement(const TDesC8& aNsUri,
+                                              const TDesC8& aLocalName) const
+    {
+    if(ipElements)
+        {
+        TInt count(ipElements->Count());
+
+        for (TInt i = 0; i < count; i++)
+            {
+            CSenElement* pElement = (*ipElements)[i];
+            const TDesC8& nsUri = pElement->NamespaceURI();
+            const TDesC8& localName = pElement->LocalName();
+            if ((nsUri == aNsUri) && (localName == aLocalName))
+                {
+                return i;
+                }
+            }
+        }
+    return KErrNotFound;
+    }
+
+EXPORT_C const TDesC8& CSenXmlElement::LocalName() const
+    {
+    if (ipLocalName == NULL)
+        {
+        return KNullDesC8();
+        }
+    else
+        {
+        return *ipLocalName;
+        }
+    }
+
+EXPORT_C const TDesC8& CSenXmlElement::NamespaceURI() const
+    {
+    if (ipNamespace)
+        {
+        return ipNamespace->URI();
+        }
+    else
+        {
+        return KNullDesC8();
+        }
+    }
+
+EXPORT_C const TDesC8& CSenXmlElement::NsPrefix() const
+    {
+    if (!ipNamespace)
+        {
+        return KNullDesC8();
+        }
+    else
+        {
+        return ipNamespace->Prefix();
+        }
+    }
+
+EXPORT_C TBool CSenXmlElement::HasContent() const
+    {
+    if (!ipContentBuf)
+        {
+        return EFalse;
+        }
+    else
+        {
+        return (ipContentBuf->Size() > 0);
+        }
+    }
+
+EXPORT_C TPtrC8 CSenXmlElement::Content() const
+    {
+    if (!ipContentBuf)
+        {
+        return KNullDesC8();
+        }
+    else
+        {
+        TPtrC8 p8 = ipContentBuf->Ptr(0);
+        return p8;
+        }
+    }
+
+
+EXPORT_C HBufC* CSenXmlElement::ContentUnicodeL() const
+    {
+    HBufC* pRet = SenXmlUtils::ToUnicodeLC(Content());
+    CleanupStack::Pop(); // pRet;
+    return pRet;
+    }
+
+EXPORT_C TPtrC8 CSenXmlElement::SetContentL(const TDesC8& aContent)
+    {
+    AllocContentBufL(); 
+	if(ipContentBuf)
+		{
+		ipContentBuf->ResizeL(aContent.Size());
+		ipContentBuf->Write(0,
+        TPtrC8(REINTERPRET_CAST(const TUint8*, aContent.Ptr()),
+                                                aContent.Size())
+        );
+		if(ipContentWriteStream)
+			{
+			// Reset stream
+			ipContentWriteStream->Open(*ipContentBuf);
+			}
+		}
+    return Content();
+    }
+
+EXPORT_C RWriteStream& CSenXmlElement::ContentWriteStreamL()
+    {
+    AllocContentBufL();
+    // Allocate stream
+    if(!ipContentWriteStream)
+        {
+        ipContentWriteStream = new (ELeave) RBufWriteStream;
+        }
+    ipContentWriteStream->Open(*ipContentBuf);
+    return *ipContentWriteStream;
+    }
+
+// NOTE: assumes(!) that the namespace is same(!)
+// Optimization 
+// RPointerArray<CSenElement>* or NULL if no elements have been added!
+EXPORT_C RPointerArray<CSenElement>& CSenXmlElement::ElementsL()
+    {
+    if(!ipElements)
+        {
+        ipElements = new (ELeave) RPointerArray<CSenElement>;
+        }
+    return *ipElements;
+    }
+
+EXPORT_C TInt CSenXmlElement::ElementsL(
+                                    RPointerArray<CSenElement>& aElementArray,
+                                    const TDesC8& aNsUri,
+                                    const TDesC8& aLocalName)
+    {
+    TInt retVal(KErrNotFound);
+
+    if(ipElements) // return KErrNotFound, if zero elements have been added
+        {
+        TInt count(ipElements->Count());
+
+        if (count > 0) // return KErrNotFound, if owned array is empty
+            {
+            CSenElement* pElement = NULL;
+            for (TInt i=0; i<count; i++)
+                {
+                pElement = (*ipElements)[i];
+                if ( (aLocalName == pElement->LocalName()) &&
+                     (aNsUri == pElement->NamespaceURI()) )
+                    {
+                    aElementArray.Append(pElement);
+                    }
+                }
+            retVal = KErrNone;
+            }
+        }
+    return retVal;
+    }
+
+EXPORT_C TInt CSenXmlElement::ElementsL(
+                                    RPointerArray<CSenElement>& aElementArray,
+                                    const TDesC8& aLocalName)
+    {
+    return ElementsL(aElementArray,NamespaceURI(),aLocalName);
+    }
+
+EXPORT_C const TDesC8* CSenXmlElement::AttrValue(const TDesC8& aName)
+    {
+    CSenBaseAttribute* pAttr = FindAttr(aName);
+    if (pAttr == NULL)
+        {
+        return NULL;
+        }
+    else
+        {
+        return &(pAttr->Value());
+        }
+    }
+
+EXPORT_C void CSenXmlElement::AddAttrL(const TDesC8& aName,
+                                        const TDesC8& aValue)
+    {
+    CSenBaseAttribute* pAttr = FindAttr(aName);
+    if (!pAttr)
+        {
+        if(!ipAttrs)
+            {
+            ipAttrs = new (ELeave) RPointerArray<CSenBaseAttribute>;
+            }
+
+        User::LeaveIfError(ipAttrs->Append(CSenBaseAttribute::NewL(aName,
+                                                                 aValue)));
+        }
+    else
+        {
+        pAttr->SetValueL(aValue);
+        }
+    }
+
+EXPORT_C CSenElement* CSenXmlElement::Parent()
+    {
+    return ipParent;
+    }
+
+EXPORT_C CSenElement* CSenXmlElement::SetParent(CSenElement* apParent)  // IOP
+    {
+    if (apParent && ipParent != apParent)
+        {
+        ipParent = apParent;
+        if (!ipNamespace)
+            {
+            // check if there is a default namespace declared in the scope of
+            // the parent
+            const CSenNamespace* pParentNamespace =
+                ((CSenXmlElement*) ipParent)->Namespace(KNullDesC8,ETrue);
+            if (pParentNamespace && pParentNamespace->Prefix() == KNullDesC8)
+                {
+                ipNamespace = (CSenNamespace*)pParentNamespace;
+                }
+            }
+        else
+            {
+            //check if the parent already has a namespace for this element
+            // if so remove it from the local namespace table
+            const CSenNamespace* pNs = ipParent->Namespace(KNullDesC8,
+                                                    ipNamespace->URI());
+            if (pNs && pNs != ipNamespace)
+                {
+                if (ipNamespace->Compare(*pNs) ||
+                    ipNamespace->Prefix().Length() == 0)
+                    {
+                    //prefix is also identical or this element has no prefix
+                    if(ipNamespaces)
+                        {
+                        TInt nsIndex = ipNamespaces->Find(ipNamespace);
+                        if ( nsIndex != KErrNotFound)
+                            {
+                            ipNamespaces->Remove(nsIndex);
+                            }
+                        }
+                    delete ipNamespace;
+                    ipNamespace = NULL;
+                    ipNamespace = (CSenNamespace*)pNs;
+                    }
+                }
+
+            }
+        }
+    return apParent;
+    }
+
+EXPORT_C MSenElement& CSenXmlElement::Root()
+    {
+    if (ipParent == NULL)
+        {
+        return *this;
+        }
+    else
+        {
+        return ipParent->Root();
+        }
+    }
+
+EXPORT_C CSenElement* CSenXmlElement::Element(const TDesC8& aLocalName)
+    {
+    return Element(NamespaceURI(), aLocalName);
+    }
+
+EXPORT_C CSenElement* CSenXmlElement::Element(const TDesC8& aNsUri,
+                                               const TDesC8& aLocalName)
+    {
+    if(ipElements)
+        {
+        TInt idx = IndexOfElement(aNsUri, aLocalName);
+        if (idx < 0)
+            {
+            return NULL;
+            }
+        else
+            {
+            return (*ipElements)[idx];
+            }
+        }
+    return NULL;
+    }
+
+EXPORT_C CSenElement* CSenXmlElement::CreateElementL(const TDesC8& aNsPrefix,
+                                                      const TDesC8& aLocalName)
+    {
+    CSenElement* pNewElement = NULL;
+
+    if (aNsPrefix.Length() > 0)
+        {
+        CSenNamespace* pNamespace = (CSenNamespace*)Namespace(aNsPrefix);
+        if (pNamespace)
+            {
+            HBufC8 *pQName =
+                HBufC8::NewLC(aNsPrefix.Length() + aLocalName.Length() +5);
+            TPtr8 ptr = pQName->Des();
+            ptr.Append(aNsPrefix);
+            ptr.Append(':');
+            ptr.Append(aLocalName);
+            pNewElement =
+                CSenXmlElement::NewL(pNamespace->URI(), aLocalName, *pQName);
+            CleanupStack::PopAndDestroy(); // pQName
+            }
+        }
+    else
+        {
+        pNewElement = CSenXmlElement::NewL(aLocalName);
+        }
+
+    return pNewElement; // Returns NULL if required namespace can not be found!
+    }
+
+EXPORT_C CSenElement& CSenXmlElement::InsertElementL(
+                                          CSenElement& aElement,
+                                          const CSenElement& aBeforeElement)
+    {
+    TInt index(KErrNotFound);
+
+    // allocate element array, if not already reserved
+    if(!ipElements)
+        {
+        ipElements = new (ELeave) RPointerArray<CSenElement>;
+        }
+    else
+        {
+        // search only if array is not brand new
+        index = ipElements->Find(&aBeforeElement);
+        }
+
+    if (index != KErrNotFound)
+        {
+        // repleace element
+        User::LeaveIfError(ipElements->Insert(&aElement,index));
+        }
+    else
+        {
+        // add new element
+        User::LeaveIfError(ipElements->Append(&aElement));
+        }
+    aElement.SetParent(this);
+    return aElement;
+    }
+
+EXPORT_C CSenElement& CSenXmlElement::AddElementL(CSenElement& aElement)
+    {
+    // allocate element array, if not already reserved
+    if(!ipElements)
+        {
+        ipElements = new (ELeave) RPointerArray<CSenElement>;
+        }
+
+    User::LeaveIfError(ipElements->Append(&aElement));
+    aElement.SetParent(this);
+    return aElement;
+    }
+
+EXPORT_C CSenElement& CSenXmlElement::AddElementL(const TDesC8& aNsUri,
+                                                   const TDesC8& aLocalName)
+    {
+    return AddElementL(*CSenXmlElement::NewL(aNsUri, aLocalName));
+    }
+
+EXPORT_C CSenElement& CSenXmlElement::AddElementL(
+    const TDesC8& aNsUri,
+    const TDesC8& aLocalName,
+    const TDesC8& aQName
+    )
+    {
+    return AddElementL(*CSenXmlElement::NewL(aNsUri, aLocalName, aQName));
+    }
+
+EXPORT_C CSenElement& CSenXmlElement::AddElementL(const TDesC8& aLocalName)
+    {
+    return AddElementL(*CSenXmlElement::NewL(aLocalName));
+    }
+
+EXPORT_C CSenElement* CSenXmlElement::RemoveElement(CSenElement& aElement)
+    {
+    CSenElement* pElement = NULL;
+
+    if(ipElements)
+        {
+        TInt idx = ipElements->Find(&aElement);
+        if (idx >= 0)
+            {
+            pElement = (*ipElements)[idx];
+            ipElements->Remove(idx);
+            pElement->SetParent(NULL);
+            return pElement;
+            }
+        }
+    return pElement;
+    }
+
+EXPORT_C CSenElement* CSenXmlElement::RemoveElement(const TDesC8& aNsUri,
+                                                     const TDesC8& aLocalName)
+    {
+    TInt idx = IndexOfElement(aNsUri, aLocalName);
+    if (idx >= 0)
+        {
+        CSenElement* pElement = (*ipElements)[idx];
+        ipElements->Remove(idx);
+        pElement->SetParent(NULL);
+        return pElement;
+        }
+    else
+        {
+        return NULL;
+        }
+    }
+
+EXPORT_C CSenElement* CSenXmlElement::RemoveElement(const TDesC8& aLocalName)
+    {
+    return RemoveElement(NamespaceURI(), aLocalName);
+    }
+
+EXPORT_C CSenElement* CSenXmlElement::ReplaceElementL(CSenElement& aElement)
+    {
+    CSenElement* pOldElement =
+                RemoveElement(aElement.NamespaceURI(), aElement.LocalName());
+    CleanupStack::PushL(pOldElement);
+    AddElementL(aElement);
+    CleanupStack::Pop(); // pOldElement;
+    return pOldElement;
+    }
+
+EXPORT_C HBufC8* CSenXmlElement::AsXmlL()
+    {
+    CBufFlat *pBuf = CBufFlat::NewL(KFlatBufSize);
+    CleanupStack::PushL(pBuf);
+    TPtrC8 p = WriteToBufL(*pBuf);
+    HBufC8* pRet = p.AllocL();
+    CleanupStack::PopAndDestroy(); // pBuf;
+    return pRet;
+
+    }
+
+EXPORT_C HBufC* CSenXmlElement::AsXmlUnicodeL()
+    {
+    CBufFlat *pBuf = CBufFlat::NewL(KFlatBufSize);
+    CleanupStack::PushL(pBuf);
+    TPtrC8 p8 = WriteToBufL(*pBuf);
+    HBufC* pRet = SenXmlUtils::ToUnicodeLC(p8);
+    CleanupStack::Pop(); // pop pRet;
+    CleanupStack::PopAndDestroy(); // pBuf;
+    return pRet;
+    }
+
+EXPORT_C TPtrC8 CSenXmlElement::WriteToBufL(CBufBase& aBuf)
+    {
+    RBufWriteStream bufWs(aBuf);
+    CleanupClosePushL(bufWs);
+    this->WriteAsXMLToL(bufWs);
+    CleanupStack::PopAndDestroy(); // bufWs.Close();
+    return aBuf.Ptr(0);
+    }
+
+EXPORT_C void CSenXmlElement::WriteAsXMLToL(RWriteStream& aWriteStream)
+    {
+    // Find out whether we should declare the namespace
+    TPtrC8 nsPrefix = NsPrefix();
+
+    // Element name
+    aWriteStream.WriteL(KSenLessThan);
+    if (nsPrefix.Length() > 0)
+        {
+        aWriteStream.WriteL(nsPrefix);
+        aWriteStream.WriteL(KSenColon);
+        }
+    aWriteStream.WriteL(*ipLocalName);
+
+    
+    if ((ipAttrs && ipAttrs->Count() > 0) || 
+         (ipNamespaces && ipNamespaces->Count() > 0))
+        {
+        WriteNamespacesToL(aWriteStream);
+        WriteAttrsToL(aWriteStream);
+        }
+
+    // Elements and content
+    if ((ipElements && ipElements->Count() > 0) || HasContent())
+        {
+        aWriteStream.WriteL(KSenGreaterThan);
+
+        // Body
+        WriteElementsToL(aWriteStream);
+        WriteContentToL(aWriteStream);
+
+        // Closing element
+        aWriteStream.WriteL(KSenLessThanSlash);
+        if (nsPrefix.Length() > 0)
+            {
+            aWriteStream.WriteL(nsPrefix);
+            aWriteStream.WriteL(KSenColon);
+            }
+        aWriteStream.WriteL(*ipLocalName);
+        aWriteStream.WriteL(KSenGreaterThan);
+        }
+    else
+        {
+        aWriteStream.WriteL(KSenSlashGreaterThan);
+        }
+    }
+
+EXPORT_C void CSenXmlElement::WriteAttrToL(RWriteStream& aWriteStream,
+                                            const TDesC8& aName,
+                                            const TDesC8& aValue)
+    {
+    aWriteStream.WriteL(KSenSpace);
+    aWriteStream.WriteL(aName);
+    aWriteStream.WriteL(KSenEqualsDblQuot);
+    aWriteStream.WriteL(aValue);
+    aWriteStream.WriteL(KSenDblQuot);
+    }
+
+EXPORT_C void CSenXmlElement::WriteAttrsToL(RWriteStream& aWriteStream)
+    {
+    if(ipAttrs)
+        {
+        TInt count(ipAttrs->Count());
+        for (TInt i = 0; i < count; i++)
+            {
+            WriteAttrToL(aWriteStream, (*ipAttrs)[i]->Name(), (*ipAttrs)[i]->Value());
+            }
+        }
+    }
+
+EXPORT_C void CSenXmlElement::WriteNamespacesToL(RWriteStream& aWriteStream)
+    {
+    if(ipNamespaces)
+        {
+        CSenNamespace* ns = NULL;
+        TInt count = ipNamespaces->Count();
+        for (TInt i=0; i < count; i++)
+            {
+            ns = (*ipNamespaces)[i];
+            if (ns)
+                {
+                aWriteStream.WriteL(KSenSpaceXmlns);
+                if (ns->Prefix().Length() > 0)
+                    {
+                    aWriteStream.WriteL(KSenColon);
+                    aWriteStream.WriteL(ns->Prefix());
+                    }
+                aWriteStream.WriteL(KSenEqualsDblQuot);
+                aWriteStream.WriteL(ns->URI());
+                aWriteStream.WriteL(KSenDblQuot);
+                }
+            }
+        }
+    }
+
+EXPORT_C void CSenXmlElement::WriteElementsToL(RWriteStream& aWriteStream)
+    {
+    if(ipElements)
+        {
+        TInt elementCount(ipElements->Count());
+        for (TInt i=0; i<elementCount; i++)
+            {
+            (*ipElements)[i]->WriteAsXMLToL(aWriteStream);
+            }
+        }
+    }
+
+EXPORT_C void CSenXmlElement::WriteContentToL(RWriteStream& aWriteStream)
+    {
+    aWriteStream.WriteL(Content());
+    }
+
+EXPORT_C MSenElement* CSenXmlElement::AsElement()
+    {
+    return this;
+    }
+
+EXPORT_C void CSenXmlElement::AllocContentBufL()
+    {
+    if(!ipContentBuf)
+        {
+        ipContentBuf = CBufFlat::NewL(KFlatBufSize);
+        }
+    }
+
+EXPORT_C void CSenXmlElement::SetNamespaceL(const TDesC8& aNsUri)
+    {
+    SetNamespaceL(KNullDesC8, aNsUri);
+    }
+
+EXPORT_C void CSenXmlElement::SetNamespaceL(const TDesC8& aNsPrefix,
+                                            const TDesC8& aNsUri)
+    {
+    if (aNsUri.Length() > 0)
+        {
+        ipNamespace = (CSenNamespace*) Namespace(aNsPrefix, aNsUri);
+        if (!ipNamespace) // not already defined
+            {
+            // allocate array if not already reserved
+            if(!ipNamespaces)
+                {
+                ipNamespaces = new (ELeave) RPointerArray<CSenNamespace>;
+                }
+            ipNamespace = CSenNamespace::NewL(aNsPrefix, aNsUri);
+            ipNamespaces->Append(ipNamespace);
+            }
+        }
+    }
+
+EXPORT_C const CSenNamespace* CSenXmlElement::Namespace()
+    {
+    return ipNamespace;
+    }
+
+EXPORT_C const CSenNamespace* CSenXmlElement::Namespace(
+                                                    const TDesC8& aNsPrefix)
+    {
+    return Namespace(aNsPrefix,ETrue);
+    }
+
+EXPORT_C const CSenNamespace* CSenXmlElement::Namespace(
+                                                    const TDesC8& aNsPrefix,
+                                                    const TBool aCheckInParent)
+    {
+    if (aNsPrefix.Length() == 0) return NULL;
+
+    const CSenNamespace* pNamespace = NULL;
+
+    if(ipNamespaces)
+        {
+        TInt count(ipNamespaces->Count());
+        for (TInt i=0; i<count && pNamespace == NULL; i++)
+            {
+            pNamespace = (*ipNamespaces)[i];
+            if (pNamespace)
+                {
+                if (pNamespace->Prefix() != aNsPrefix) pNamespace = NULL;
+                }
+            }
+        }
+
+    if (pNamespace == NULL && ipParent && aCheckInParent)
+        {
+        pNamespace = ipParent->Namespace(aNsPrefix);
+        }
+
+    return pNamespace;
+    }
+
+
+EXPORT_C const CSenNamespace* CSenXmlElement::Namespace(
+                                                    const TDesC8& aNsPrefix,
+                                                    const TDesC8& aUri)
+    {
+    // If prefix == NULL, then any prefix is ok
+    const CSenNamespace* pNs = NULL;
+    // Check if the namespace has already been declared
+    
+    if(ipNamespaces)
+        {
+        TInt count = ipNamespaces->Count();
+        if (count != 0)
+            {
+            for (TInt i=0; i<count; i++)
+                {
+                pNs = (*ipNamespaces)[i];
+                if (!pNs->Compare(aNsPrefix, aUri))
+                    {
+                    pNs = NULL; // not equal
+                    }
+                else
+                    {
+                    break;
+                    }
+                }
+            }
+        }
+    if (pNs == NULL && ipParent != NULL)
+        {
+        // if no namespace defined, but there is a parent, ask its namespace
+        pNs = ipParent->Namespace(aNsPrefix, aUri);
+        }
+    return pNs;
+    }
+
+EXPORT_C RPointerArray<CSenBaseAttribute>& CSenXmlElement::AttributesL()
+    {
+    // if attribute array is not yet allocated, instantiate here
+    if(!ipAttrs)
+        {
+        ipAttrs = new (ELeave) RPointerArray<CSenBaseAttribute>;
+        }
+    return *ipAttrs;
+    }
+
+EXPORT_C RPointerArray<CSenNamespace>& CSenXmlElement::NamespacesL()
+    {
+    if(!ipNamespaces)
+        {
+        ipNamespaces = new (ELeave) RPointerArray<CSenNamespace>;
+        }
+    return *ipNamespaces;
+    }
+
+EXPORT_C void CSenXmlElement::CopyFromL(CSenElement& aSource)
+    {
+    TPtrC8 sourceContent = aSource.Content();
+    if (sourceContent.Length() > 0)
+        {
+        if (ipContentBuf == NULL)
+            {
+            SetContentL(sourceContent);
+            }
+        else
+            {
+            RBufWriteStream bufWs(*ipContentBuf);
+            CleanupClosePushL(bufWs);
+            bufWs.WriteL(sourceContent);
+            CleanupStack::PopAndDestroy(); // close bufWs
+            }
+        }
+
+    RPointerArray<CSenNamespace> sourceNamespaces = aSource.NamespacesL();
+    if (sourceNamespaces.Count() > 0)
+        {
+        for (TInt i=0;i<sourceNamespaces.Count(); i++)
+            {
+            CSenNamespace* pNamespace = sourceNamespaces[i];
+            CSenNamespace* pNewNamespace =
+                CSenNamespace::NewL(pNamespace->Prefix(),pNamespace->URI());
+            CleanupStack::PushL(pNewNamespace);
+
+            // allocate array if not already reserved
+            if(!ipNamespaces)
+                {
+                ipNamespaces = new (ELeave) RPointerArray<CSenNamespace>;
+                }
+            
+#ifdef EKA2
+            ipNamespaces->AppendL(pNewNamespace);
+#else
+            User::LeaveIfError(ipNamespaces->Append(pNewNamespace));
+#endif
+            CleanupStack::Pop(pNewNamespace);
+            }
+        }
+    SetNamespaceL(aSource.NsPrefix(), aSource.NamespaceURI());
+
+    RPointerArray<CSenBaseAttribute> sourceAttributes = aSource.AttributesL();
+    if (sourceAttributes.Count() > 0)
+        {
+        for (TInt i=0;i<sourceAttributes.Count(); i++)
+            {
+            CSenBaseAttribute* pBaseAttribute = sourceAttributes[i];
+
+            // 2005-04-28: check for duplicate and override existing value if
+            // attribute already exists.
+            CSenBaseAttribute* pOriginal = FindAttr(pBaseAttribute->Name());
+            if (pOriginal)
+                {
+                pOriginal->SetValueL(pBaseAttribute->Value());
+                continue;
+                }
+
+            CSenBaseAttribute* pNewBaseAttribute =
+                CSenBaseAttribute::NewL(pBaseAttribute->Name(),
+                                        pBaseAttribute->Value());
+            CleanupStack::PushL(pNewBaseAttribute);
+
+            // if attribute array is not yet allocated, instantiate here
+            if(!ipAttrs)
+                {
+                ipAttrs = new (ELeave) RPointerArray<CSenBaseAttribute>;
+                }
+
+#ifdef EKA2
+            ipAttrs->AppendL(pNewBaseAttribute);
+#else
+            User::LeaveIfError(ipAttrs->Append(pNewBaseAttribute));
+#endif
+            CleanupStack::Pop(pNewBaseAttribute);
+            }
+        }
+
+    RPointerArray<CSenElement> sourceElements = aSource.ElementsL();
+    if (sourceElements.Count() > 0)
+        {
+        for (TInt i=0;i<sourceElements.Count(); i++)
+            {
+            CSenElement* pElement = sourceElements[i];
+            CSenElement* pNewElement =
+                                CSenXmlElement::NewL(pElement->LocalName());
+            CleanupStack::PushL(pNewElement);
+            pNewElement->SetParent(this);
+            pNewElement->CopyFromL(*pElement);
+
+            if(!ipElements)
+                {
+                ipElements = new (ELeave) RPointerArray<CSenElement>;
+                }
+
+#ifdef EKA2
+            ipElements->AppendL(pNewElement);
+#else
+            User::LeaveIfError(ipElements->Append(pNewElement));
+#endif // EKA2
+            CleanupStack::Pop(pNewElement);
+            }
+        }
+    }
+
+EXPORT_C void CSenXmlElement::SetPrefixL(const TDesC8& aPrefix)
+    {
+    if (ipNamespaces && ipNamespaces->Find(ipNamespace) > -1)
+        {
+        //the namespace was locally declared
+
+        // Check if element already has a namespace with given prefix
+        CSenNamespace* pNamespace = NULL;
+        TInt count(ipNamespaces->Count());
+        for (TInt i=0; i<count && pNamespace == NULL; i++)
+            {
+            pNamespace = (*ipNamespaces)[i];
+            if (pNamespace->Prefix() != aPrefix) 
+                {
+                pNamespace = NULL;
+                }
+            }
+
+        if (pNamespace)
+            {
+            // Update existing namespace
+            const TDesC8& uri = ipNamespace->URI();
+            pNamespace->SetUriL(uri);
+            ipNamespace = pNamespace;
+            }
+        else
+            {
+            if(ipElements) // are there any child elements?
+                {
+                if (ipNamespace->Prefix().Length() > 0 && ipElements->Count() > 0)
+                    {
+                    // there may be children that depend on the old prefix in e.g. attribute names
+                    const TDesC8& uri = ipNamespace->URI();
+                    ipNamespace = CSenNamespace::NewL(aPrefix, uri);
+
+                    // append as new namespace
+                    ipNamespaces->Append(ipNamespace);
+                    }
+                }
+            ipNamespace->SetPrefixL(aPrefix);
+            }
+        }
+    }
+
+EXPORT_C const CSenNamespace* CSenXmlElement::AddNamespaceL(
+                                                CSenNamespace& aNewNamespace,
+                                                TBool aCheckInParent)
+    {
+    const CSenNamespace* pNamespace =
+                        Namespace(aNewNamespace.Prefix(), aCheckInParent);
+
+    if (pNamespace == NULL) // does not exist
+        {
+        CSenNamespace* pNewNamespace =
+            CSenNamespace::NewL(aNewNamespace.Prefix(), aNewNamespace.URI());
+
+        // allocate array if not already reserved
+        if(!ipNamespaces)
+            {
+            ipNamespaces = new (ELeave) RPointerArray<CSenNamespace>;
+            }
+        ipNamespaces->Append(pNewNamespace);
+        pNamespace = pNewNamespace;
+        }
+    return pNamespace;
+    }
+
+EXPORT_C const CSenNamespace* CSenXmlElement::AddNamespaceL(
+                                                         const TDesC8& aPrefix,
+                                                         const TDesC8& aUri)
+    {
+    CSenNamespace* pNamespace = (CSenNamespace*)Namespace(aPrefix);
+	if (!pNamespace)
+		{
+		if ( aUri.Length() > 0)
+			{
+				pNamespace = CSenNamespace::NewL(aPrefix, aUri);
+			// allocate array if not already reserved
+			if(!ipNamespaces)
+				{
+				ipNamespaces = new (ELeave) RPointerArray<CSenNamespace>;
+				}
+			ipNamespaces->Append(pNamespace);
+			}
+		}
+	    else
+	        {
+	        pNamespace->SetUriL(aUri); // override current namespace URI with new one
+	      
+			}
+
+    return pNamespace;
+    }
+
+EXPORT_C CSenElement* CSenXmlElement::DetachL()
+    {
+    if (!ipParent)
+        {
+        return NULL;
+        }
+
+    // allocate array if not already reserved
+    if(!ipNamespaces)
+        {
+        ipNamespaces = new (ELeave) RPointerArray<CSenNamespace>;
+        }
+
+    AddNamespaceMissingFromL(*ipNamespaces);
+
+    // optimization: if nothing was added, free the array allocation
+    if(ipNamespaces && ipNamespaces->Count()==0)
+        {
+        ipNamespaces->ResetAndDestroy(); 
+        delete ipNamespaces; 
+                            
+        ipNamespaces = NULL;
+        }
+
+    ipParent->RemoveElement(*this);
+    return this;
+    }
+
+void CSenXmlElement::AddNamespaceMissingFromL( RPointerArray<CSenNamespace>& aNamespaces )
+    {
+    // Add namespace of this element (possibly copied from parent)
+    // if that namespace is not already defined in
+    // aNamespaces array.
+    if ( ipNamespace && aNamespaces.Find(ipNamespace) == -1)
+        {
+        // Check if namespace declaration of this element can
+        // be found from aNamespaces array
+        TInt count(aNamespaces.Count());
+        TBool found(EFalse);
+        TInt i = 0;
+        for (; i<count; i++)
+            {
+            if ( aNamespaces[i]->URI() == ipNamespace->URI() && 
+                 aNamespaces[i]->Prefix() == ipNamespace->Prefix() )
+                {
+                found = ETrue;
+                break;
+                }
+            }
+        if ( !found )
+            {
+            //If not found then check in namespace usage array that namspace declaration 
+            //is present or not. If yes then continue without adding.
+            if((ipNamespaces && ipNamespaces->Find(ipNamespace) == -1) || !ipNamespaces)
+	            {
+            
+	            // Not found 
+	            // => Create a copy of namespace declaration
+	            //    and append it into aNamespaces array
+	            CSenNamespace* pCopy =
+	                    CSenNamespace::NewL(ipNamespace->Prefix(), ipNamespace->URI());
+	            CleanupStack::PushL(pCopy);
+	#ifdef EKA2
+	            aNamespaces.AppendL(pCopy);
+	#else
+	            User::LeaveIfError(aNamespaces.Append(pCopy));
+	#endif
+	            CleanupStack::Pop(pCopy);
+
+	            // Change namespace object for this element to namespace object
+	            // which can be found from aNamespaces array
+	            ipNamespace = pCopy;
+	            }
+            }
+        else
+            {
+            // Change namespace object for this element to namespace object
+            // which can be found from aNamespaces array
+            ipNamespace = aNamespaces[i];
+            }
+        }
+
+    // Add namespaces from this element's attributes
+    // if those namespaces are not already defined in
+    // aNamespaces array.
+    if ( ipAttrs && ipAttrs->Count() > 0 )
+        {
+        TInt colon = -1;
+        const CSenNamespace* pNamespace = NULL;
+
+        TInt count(ipAttrs->Count());
+        for(TInt i=0; i<count; i++)
+            {
+            CSenBaseAttribute* pAttribute = (*ipAttrs)[i];
+
+            // Check namespace assigned to Name
+            colon = pAttribute->Name().Locate(':');
+            if ( colon > 0 )
+                {
+                pNamespace =
+                    Namespace(pAttribute->Name().Mid(0, colon), KNullDesC8);
+                }
+            if ( pNamespace && (aNamespaces.Find(pNamespace) == -1) )
+                {
+                // Check if namespace declaration for handled attribute
+                // _name_ can be found from aNamespaces array.
+                TInt count(aNamespaces.Count());
+                TBool found(EFalse);
+                for (TInt i = 0; i<count; i++)
+                    {
+                    if ( aNamespaces[i]->URI() == pNamespace->URI() && 
+                         aNamespaces[i]->Prefix() == pNamespace->Prefix() )
+                        {
+                        found = ETrue;
+                        break;
+                        }
+                    }
+                if ( !found )
+                    {
+		            //If not found then check in namespace usage array that 
+		            //namespace declaration is present or not. If yes then 
+		            //continue without adding.
+		            if((ipNamespaces && ipNamespaces->Find(pNamespace) == -1) || !ipNamespaces)
+			            {
+                    
+	                    // Not found 
+	                    // => Create a copy of namespace declaration
+	                    //    and append it into aNamespaces array
+	                    CSenNamespace* pCopy =
+	                            CSenNamespace::NewL(pNamespace->Prefix(),
+	                                                pNamespace->URI());
+	                    CleanupStack::PushL(pCopy);
+	#ifdef EKA2
+	                    aNamespaces.AppendL(pCopy);
+	#else
+	                    User::LeaveIfError(aNamespaces.Append(pCopy));
+	#endif
+	                    CleanupStack::Pop(pCopy);
+			            }
+                    }
+                }
+            pNamespace = NULL;
+
+            // Check namespace assigned to Value
+            colon = pAttribute->Value().Locate(':');
+            if ( colon > 0 )
+                {
+                pNamespace =
+                    Namespace(pAttribute->Value().Mid(0, colon), KNullDesC8);
+                }
+            if ( pNamespace && (aNamespaces.Find(pNamespace) == -1) )
+                {
+                // Check if namespace declaration for handled attribute
+                // _value_ can be found from aNamespaces array.
+                TInt count(aNamespaces.Count());
+                TBool found(EFalse);
+                for (TInt i = 0; i<count; i++)
+                    {
+                    if ( aNamespaces[i]->URI() == pNamespace->URI() && 
+                         aNamespaces[i]->Prefix() == pNamespace->Prefix() )
+                        {
+                        found = ETrue;
+                        break;
+                        }
+                    }
+                if ( !found )
+                    {
+					//If not found then check in namespace usage array that 
+		            //namspace declaration is present or not.If yes then 
+		            //continue without adding.
+		            if(ipNamespaces && ipNamespaces->Find(pNamespace) == -1)
+			            {
+
+	                    // Not found 
+	                    // => Create a copy of namespace declaration
+	                    //    and append it into aNamespaces array
+	                    CSenNamespace* pCopy =
+	                            CSenNamespace::NewL(pNamespace->Prefix(), 
+	                                                pNamespace->URI());
+	                    CleanupStack::PushL(pCopy);
+	#ifdef EKA2
+	                    aNamespaces.AppendL(pCopy);
+	#else
+	                    User::LeaveIfError(aNamespaces.Append(pCopy));
+	#endif
+	                    CleanupStack::Pop(pCopy);
+			            }
+                    }
+                }
+            pNamespace = NULL;
+            }
+        }
+
+    if(ipElements && ipElements->Count() > 0)
+        {
+        TInt count(ipElements->Count());
+        for(TInt i=0; i<count; i++)
+            {
+            CSenXmlElement* pElement = (CSenXmlElement*) (*ipElements)[i];
+            pElement->AddNamespaceMissingFromL(aNamespaces);
+            }
+        }
+    }
+
+
+EXPORT_C void CSenXmlElement::Set(const TDesC8& aNamespaceURI,
+                                   const TDesC8& aLocalName,
+                                   const TDesC8& aQName)
+    {
+    delete ipLocalName;
+    ipLocalName = NULL;
+    HBufC8* pTemp = aLocalName.Alloc();
+    if(pTemp)
+        {
+        ipLocalName = pTemp;
+        }
+
+    TPtrC8 prefix(KNullDesC8);
+
+    if(aQName != KNullDesC8)
+        {
+        TInt colon(KErrNotFound);
+        colon = aQName.Locate(':');
+        if(colon!=KErrNotFound)
+            {
+            prefix.Set(aQName.Left(colon));
+            }
+        }
+    TInt leaveCode(KErrNone);
+    TRAP(leaveCode, SetNamespaceL(prefix, aNamespaceURI);)
+    leaveCode=0;
+    
+    //if (err) ; 
+    }
+
+EXPORT_C CSenElement* CSenXmlElement::Child(TInt aIndex)
+    {
+    CSenElement* pElement = NULL;
+    if(ipElements && aIndex < ipElements->Count())
+        {
+        pElement = (CSenXmlElement*) (*ipElements)[aIndex];
+        }
+    return pElement;
+    }
+
+EXPORT_C TBool CSenXmlElement::ConsistsOfL(MSenElement& aCandidate)
+    {
+    // First check the names and namespaces
+    if (    aCandidate.LocalName() != this->LocalName()
+        ||  aCandidate.NamespaceURI() != this->NamespaceURI()
+        ||  aCandidate.NsPrefix() != this->NsPrefix()
+        )
+        {
+        return EFalse;
+        }
+
+    // Then check content if it exists
+    if (aCandidate.HasContent())
+        {
+        if (aCandidate.Content() != this->Content())
+            {
+            return EFalse;  // Content doesn't match => no match
+            }
+        }
+
+    // Then handle the children
+    RPointerArray<CSenElement>& children = aCandidate.ElementsL();
+    TInt childCount = children.Count();
+    TInt i=0;
+    while (i < childCount)
+        {
+        CSenElement* pMatchChild = children[i];
+        CSenElement* pChild = this->Element(pMatchChild->LocalName());
+        if (!pChild)
+            {
+            return EFalse;  // no child with same name found in children, 
+                            // => no match
+            }
+        else
+            {
+            if (!pChild->ConsistsOfL(*pMatchChild))
+                {
+                return EFalse; // a non matching child was found => No match
+                }
+            }
+        i++;
+        }
+    return ETrue;
+    }
+
+void CSenXmlElement::Compress()
+    {
+    if(ipContentWriteStream)
+        {
+        ipContentWriteStream->Close();
+        delete ipContentWriteStream;
+        ipContentWriteStream = NULL;
+        }
+    if (ipContentBuf) ipContentBuf->Compress();
+    if(ipElements)
+        {
+        TInt count(ipElements->Count());
+
+        for (TInt i = 0; i < count; i++)
+            {
+            CSenElement* pElement = (*ipElements)[i];
+            ((CSenXmlElement*)pElement)->Compress();
+            }
+        }
+    
+    }
+
+// New methods; problem: assume, that one cannot change CSenElement (abstract)
+// class definition (virtual function tables); therefore one must be cautious
+// and avoid class casting to internal element in base fragment layer(!) in
+// order to access these methods! What if someone added a baseelement? -> crash
+
+// Optimized variant
+// @return NULL if this element has no child elements
+/*
+RPointerArray<CSenElement>* CSenXmlElement::ElementsL()
+    {
+    return ipElements;
+    }
+
+// Optimized variant
+//@return NULL if this element has no attributes 
+RPointerArray<CSenBaseAttribute>* CSenXmlElement::AttributesL()
+    {
+    return ipAttrs;
+    }
+
+// Optimized variant
+// @return RPointerArray<CSenNamespace>* or NULL if there are no attributes in this element
+RPointerArray<CSenNamespace>& CSenXmlElement::NamespacesL()
+    {
+    return ipNamespaces;
+    }
+*/
+
+// end of file