webservices/wsfragment/src/senfragmentbase.cpp
changeset 0 62f9d29f7211
child 23 a1df79fa35b4
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/webservices/wsfragment/src/senfragmentbase.cpp	Thu Jan 07 16:19:19 2010 +0200
@@ -0,0 +1,1632 @@
+/*
+* Copyright (c) 2002-2006 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:        Class implements XML base fragment using libxml2 classes
+*
+*/
+
+
+
+
+
+
+
+
+// INCLUDE FILES
+#include <flogger.h>
+#include <utf.h>
+#include <s32mem.h>
+#include "SenFragmentBase.h"
+#include "SenParser.h"
+#include "wslibxml2utils.h"
+
+#include <SenXmlConstants.h>
+
+#include <xml/attribute.h>               // needed for RAttributeArray
+#include <xml/parserfeature.h>           // for TParserFeature enumeration
+#include <xmlengserializationoptions.h> // for TSerializationOptions
+#include <xmlengbinarycontainer.h>
+#include <xmlengnodelist.h>
+
+
+typedef unsigned char xmlChar; // from "libxml/Libxml2_xmlstring.h"
+
+using namespace Xml;
+
+// ***************************************************************************
+// Fragment class state constants are as following (declared in subclasses):
+// KSenStateNotSet                  = -1;
+// KSenStateIgnore                  =  0; // even ones ignore(0),
+// KSenStateSave                    =  1; // and odd ones save(1)
+// KSenStateResume                  =  2;
+// KStateParsingFramework           =  4;
+// KStateParsingSoapFault           =  5;  // odd, save
+// KStateParsingServiceDescription  =  6;
+// KStateParsingResourceOffering    =  11; // odd, save
+// KStateParsingCredentials         =  12;
+// KStateParsingService             =  13; // odd state, saves content
+// KStateParsingPwTransforms        =  14;
+// KStateParsingSoapHeader          =  20; // ignore state (even num)
+// KStateParsingSoapBody            =  40; // ignore state (even num)
+// KStateParsingSingleCredential    =  122;
+// KStateParsingProviderPolicy      =  1222;
+
+namespace
+    {
+    const TInt KFlatBufSize = 128;
+    _LIT(KSenFragmentPanic, "SenFragment");
+    
+    TBool EncodeXmlEscapesL( const TDesC8& aOriginal, HBufC8*& aEncoded )
+        {
+        TBool retVal = EFalse;
+        delete aEncoded;
+        aEncoded = NULL;
+    
+        if (aOriginal == KNullDesC8)
+            {
+            return retVal;
+            }
+        TPtrC8 tokens[] =
+            {
+            KSenEscapedAmp(),
+            KSenEscapedApos(),
+            KSenEscapedDblQuot(),
+            KSenEscapedGt(),
+            KSenEscapedLt()  
+            };
+        TText16 tokenChars[] =
+            {
+            '&',
+            '\'',
+            '\"',
+            '>',
+            '<'
+            };
+        
+        // Replace escaped characters, if any
+        for (TInt i = 0; i < aOriginal.Length(); i++)
+            {
+            TBool foundChar = EFalse;
+            //for (TInt j = 0; j < (sizeof(tokenChars) / sizeof(TText16)); j++)
+            for (TInt j = 0; j < 5; j++)
+                {
+                if (aOriginal[i] == tokenChars[j])
+                    {
+                    if ( !aEncoded )
+                        {
+                        aEncoded =
+                            HBufC8::NewL(aOriginal.Length() * KSenMaxXmlEscapedLength);
+                        aEncoded->Des().Append(aOriginal.Left(i));
+                        }
+                    foundChar = ETrue;
+                    aEncoded->Des().Append(tokens[j]);
+                    retVal = ETrue; // indicate, that encoding was done
+                    break;
+                    }
+                }
+            if (!foundChar)
+                {
+                if (aEncoded)
+                    {
+                    
+                    aEncoded->Des().Append(aOriginal[i]);
+                    }
+                }
+            }
+        return retVal;
+        }
+    }
+
+EXPORT_C CSenFragmentBase* CSenFragmentBase::NewL(const TXmlEngElement& aElement)
+    {
+    CSenFragmentBase* pNew = new (ELeave) CSenFragmentBase;
+    CleanupStack::PushL(pNew);
+    pNew->BaseConstructL(aElement);
+    CleanupStack::Pop(pNew);
+    return pNew;
+    }
+
+EXPORT_C CSenFragmentBase* CSenFragmentBase::NewL(const TDesC8& aLocalName)
+    {
+    CSenFragmentBase* pNew = new (ELeave) CSenFragmentBase;
+    CleanupStack::PushL(pNew);
+    pNew->BaseConstructL(aLocalName);
+    CleanupStack::Pop(pNew);
+    return pNew;
+    }
+
+EXPORT_C CSenFragmentBase* CSenFragmentBase::NewL(const TDesC8& aNsUri,
+                                                  const TDesC8& aLocalName
+    )
+    {
+    CSenFragmentBase* pNew = new (ELeave) CSenFragmentBase;
+    CleanupStack::PushL(pNew);
+    pNew->BaseConstructL(aNsUri, aLocalName);
+    CleanupStack::Pop(pNew);
+    return pNew;
+    }
+
+EXPORT_C CSenFragmentBase* CSenFragmentBase::NewL(const TDesC8& aNsUri,
+                                                  const TDesC8& aLocalName,
+                                                  const TDesC8& aPrefix,
+                                                  const RAttributeArray& aAttrs
+    )
+    {
+    CSenFragmentBase* pNew = new (ELeave) CSenFragmentBase;
+    CleanupStack::PushL(pNew);
+    pNew->BaseConstructL(aNsUri, aLocalName, aPrefix, aAttrs);
+    CleanupStack::Pop(pNew);
+    return pNew;
+    }
+
+EXPORT_C CSenFragmentBase* CSenFragmentBase::NewL(const TDesC8& aNsUri,
+                                                  const TDesC8& aLocalName,
+                                                  const TDesC8& aPrefix,
+                                                  const RAttributeArray& aAttrs,
+                                                  TXmlEngElement& aParent
+    )
+    {
+    CSenFragmentBase* pNew = new (ELeave) CSenFragmentBase;
+    CleanupStack::PushL(pNew);
+    pNew->BaseConstructL(aNsUri, aLocalName, aPrefix, aAttrs, aParent);
+    CleanupStack::Pop(pNew);
+    return pNew;
+    }
+
+EXPORT_C CSenFragmentBase* CSenFragmentBase::NewL(const TDesC8& aNsUri,
+                                                  const TDesC8& aLocalName,
+                                                  const TDesC8& aPrefix,
+                                                  const RAttributeArray& aAttrs,
+                                                  TXmlEngElement& aParent,
+                                                  RSenDocument& aOwnerDocument
+    )
+    {
+    CSenFragmentBase* pNew = new (ELeave) CSenFragmentBase;
+    CleanupStack::PushL(pNew);
+    pNew->BaseConstructL(aNsUri, aLocalName, aPrefix, aAttrs, aParent,
+                         aOwnerDocument);
+    CleanupStack::Pop(pNew);
+    return pNew;
+    }
+
+EXPORT_C CSenFragmentBase* CSenFragmentBase::NewL(const TDesC8& aNsUri,
+                                                  const TDesC8& aLocalName,
+                                                  const TDesC8& aPrefix
+    )
+    {
+    CSenFragmentBase* pNew = new (ELeave) CSenFragmentBase;
+    CleanupStack::PushL(pNew);
+    pNew->BaseConstructL(aNsUri, aLocalName, aPrefix);
+    CleanupStack::Pop(pNew);
+    return pNew;
+    }
+    
+EXPORT_C CSenFragmentBase* CSenFragmentBase::NewL(TXmlEngElement& aRootElement,
+                                                  RSenDocument& aOwnerDocument)
+    {
+    CSenFragmentBase* pNew = new (ELeave) CSenFragmentBase;
+    CleanupStack::PushL(pNew);
+    pNew->BaseConstructL(aRootElement, aOwnerDocument);
+    CleanupStack::Pop(pNew);
+    return pNew;
+    }
+
+EXPORT_C CSenFragmentBase::~CSenFragmentBase()
+    {
+    if ( ipNamespaceArray )
+        {
+        ipNamespaceArray->ResetAndDestroy();
+        delete ipNamespaceArray;
+        }
+    iDocument.Close();
+    if ( ipContentBuf )
+    	{
+                
+        delete ipContentBuf;
+        ipContentBuf = NULL;
+        
+        delete ipContentWriteStream;
+        ipContentWriteStream = NULL;
+        }
+        
+     if ( ipDelegate )
+        {
+        delete ipDelegate;
+        ipDelegate = NULL;
+        }   
+    }
+
+EXPORT_C CSenFragmentBase::CSenFragmentBase()
+:   iState(KSenStateIgnore),
+    ipParser(NULL),
+    ipOwner(NULL),
+    ipDelegate(NULL)
+    {
+    }
+
+EXPORT_C void CSenFragmentBase::BaseConstructL(const TXmlEngElement& aSrc)
+    {
+    iElement = aSrc.CopyL();
+    iDocument = RSenDocument::NewL();
+    iDocument.SetDocumentElement(iElement);
+    }
+
+EXPORT_C void CSenFragmentBase::BaseConstructL(const TDesC8& aLocalName)
+    {
+    iDocument = RSenDocument::NewL();
+    if ( aLocalName != KNullDesC8 )
+        {
+        iDocument.CreateDocumentElementL(aLocalName);
+        iElement = iDocument.DocumentElement();
+        }
+    }
+
+EXPORT_C void CSenFragmentBase::BaseConstructL(const TDesC8& aNsUri,
+                                               const TDesC8& aLocalName
+    )
+    {
+    iDocument = RSenDocument::NewL();
+    iDocument.CreateDocumentElementL(aLocalName, aNsUri);
+    iElement = iDocument.DocumentElement();
+    }
+
+EXPORT_C void CSenFragmentBase::BaseConstructL(const TDesC8& aNsUri,
+                                               const TDesC8& aLocalName,
+                                               const TDesC8& aPrefix,
+                                               const RAttributeArray& aAttrs
+    )
+    {
+    iDocument = RSenDocument::NewL();
+    if (aPrefix == KNullDesC8)
+        {
+        iDocument.CreateDocumentElementL(aLocalName, aNsUri);
+        }
+    else
+        {
+        iDocument.CreateDocumentElementL(aLocalName, aNsUri, aPrefix);
+        }
+
+    iElement = iDocument.DocumentElement();
+    AddAttributesL(aAttrs);
+    }
+
+EXPORT_C void CSenFragmentBase::BaseConstructL(
+    const TDesC8& aNsUri,
+    const TDesC8& aLocalName,
+    const TDesC8& aPrefix,
+    const RAttributeArray& aAttributes,
+    TXmlEngElement& aParent
+    )
+    {
+    iDocument = RSenDocument::NewL();
+    iElement = aParent.AddNewElementL(aLocalName);
+
+    if (aNsUri != KNullDesC8 || aPrefix != KNullDesC8)
+        {
+        if (aPrefix == KNullDesC8)
+            {
+            // Check if namespace declaration for the root tag
+            // is already defined in parent element.
+            TXmlEngNamespace ns = aParent.LookupNamespaceByUriL(aNsUri);
+            if ( ns.IsNull() )
+                {
+                // Namespace declaration will be added to iElement
+                iElement.AddNamespaceDeclarationL(aNsUri, KNullDesC8);
+                }
+
+            WsXmlUtils domUtils;       
+            domUtils.XmlEngRenameElementL(iElement, aLocalName, aNsUri, KNullDesC8);
+            }
+        else
+            {
+            // Check if namespace declaration for the root tag
+            // is already defined in parent element.
+            TXmlEngNamespace ns = aParent.LookupNamespaceByUriL(aNsUri);
+            if ( ns.IsNull() )
+                {
+                // Namespace declaration will be added to iElement
+                iElement.AddNamespaceDeclarationL(aNsUri, aPrefix);
+                }
+
+            WsXmlUtils domUtils;
+            domUtils.XmlEngRenameElementL(iElement, aLocalName, aNsUri, aPrefix);
+            }
+        }
+    
+    aParent.AppendChildL(iElement);
+
+    AddAttributesL(aAttributes);
+    }
+
+EXPORT_C void CSenFragmentBase::BaseConstructL(
+    const TDesC8& aNsUri,
+    const TDesC8& aLocalName,
+    const TDesC8& aPrefix,
+    const RAttributeArray& aAttributes,
+    TXmlEngElement& aParent,
+    RSenDocument& aOwnerDocument
+    )
+    {
+    iDocument = aOwnerDocument.Copy();
+    iElement = aParent.AddNewElementL(aLocalName);
+    
+    if ( aNsUri != KNullDesC8 || aPrefix != KNullDesC8 )
+        {
+        if ( aPrefix == KNullDesC8 )
+            {
+            // Check if namespace declaration for the root tag
+            // is already defined in parent element.
+            TXmlEngNamespace ns = aParent.LookupNamespaceByUriL(aNsUri);
+            if ( ns.IsNull() )
+                {
+                // Namespace declaration will be added to iElement
+                iElement.AddNamespaceDeclarationL(aNsUri, KNullDesC8);
+                }
+
+            WsXmlUtils domUtils;
+            domUtils.XmlEngRenameElementL(iElement, aLocalName, aNsUri, KNullDesC8);
+            }
+        else
+            {
+            // Check if namespace declaration for the root tag
+            // is already defined in parent element.
+            TXmlEngNamespace ns = aParent.LookupNamespaceByUriL(aNsUri);
+            if ( ns.IsNull() )
+                {
+                // Namespace declaration will be added to iElement
+                iElement.AddNamespaceDeclarationL(aNsUri, aPrefix);
+                }
+            WsXmlUtils domUtils;
+            domUtils.XmlEngRenameElementL(iElement, aLocalName, aNsUri, aPrefix);
+            }
+        }
+    
+    aParent.AppendChildL(iElement);
+
+    AddAttributesL(aAttributes);
+    }
+
+EXPORT_C void CSenFragmentBase::BaseConstructL(const TDesC8& aNsUri,
+                                               const TDesC8& aLocalName,
+                                               const TDesC8& aPrefix
+    )
+    {
+    iDocument = RSenDocument::NewL();
+    if ( aNsUri == KNullDesC8 && aPrefix == KNullDesC8 )
+        {
+        iDocument.CreateDocumentElementL(aLocalName);
+        }
+    else
+        {
+        if ( aPrefix == KNullDesC8 )
+            {
+            iDocument.CreateDocumentElementL(aLocalName, aNsUri, KNullDesC8);
+            }
+        else
+            {
+            iDocument.CreateDocumentElementL(aLocalName, aNsUri, aPrefix);
+            }
+        }
+    iElement = iDocument.DocumentElement();
+    }
+    
+EXPORT_C void CSenFragmentBase::BaseConstructL(TXmlEngElement& aRootElement,
+                                               RSenDocument& aOwnerDocument)
+    {
+    iDocument = aOwnerDocument.Copy();
+    iElement = aRootElement;
+    }
+
+EXPORT_C void CSenFragmentBase::AddNamespacesL()
+    {
+    if (ipParser)
+        {
+        if ( ipParser->IsFeatureEnabled(EReportNamespaceMapping) )
+            {
+            // Add namespaces, if any
+            if ( ipNamespaceArray )
+                {
+                TInt count = ipNamespaceArray->Count();
+                for (TInt i=0; i < count; i++)
+                    {
+                    CSenNamespaceData* pNamespace = (*ipNamespaceArray)[i];
+                    TXmlEngNamespace ns =
+                                AsElementL().LookupNamespaceByUriL(*pNamespace->ipNamespaceUri);
+                    if ( ns.IsNull() )
+                        {
+                        if (pNamespace->ipPrefix == NULL)
+                            {
+                            AsElementL().AddNamespaceDeclarationL(*pNamespace->ipNamespaceUri,
+                                                                  KNullDesC8);
+                            }
+                        else
+                            {
+                            AsElementL().AddNamespaceDeclarationL(*pNamespace->ipNamespaceUri,
+                                                                  *pNamespace->ipPrefix);
+                            }
+                        }
+                    }
+                ipNamespaceArray->ResetAndDestroy();
+                }
+            }
+        }
+    }
+    
+EXPORT_C void CSenFragmentBase::AddAttributesToElementL(TXmlEngElement aElement,
+                                               const RAttributeArray& apAttrs)
+    {
+    TInt count(apAttrs.Count());
+
+    for(TInt i=0; i<count; i++)
+        {
+        TPtrC8 localName = apAttrs[i].Attribute().LocalName().DesC();
+        TPtrC8 value = apAttrs[i].Value().DesC();
+
+        if (apAttrs[i].Attribute().Uri().DesC() == KNullDesC8)
+            {
+            aElement.AddNewAttributeL(localName, value);
+            }
+        else
+            {
+            TPtrC8 namespaceUri = apAttrs[i].Attribute().Uri().DesC();
+            TPtrC8 prefix(KNullDesC8);
+            if ( apAttrs[i].Attribute().Prefix().DesC() != KNullDesC8 )
+                {
+                prefix.Set(apAttrs[i].Attribute().Prefix().DesC());
+                }
+                
+            TXmlEngNamespace ns = aElement.LookupNamespaceByUriL(namespaceUri);
+            if ( ns.NotNull() )
+                {
+                if (ns.Prefix() == KNullDesC8 && prefix == KNullDesC8)
+                    {
+                    aElement.AddNewAttributeWithNsL(localName, value, namespaceUri);
+                    }
+                else if ( ns.Prefix() == prefix )
+                    {
+                    aElement.AddNewAttributeL(localName, value, ns);
+                    }
+                else
+                    {
+                    aElement.AddNewAttributeL(localName, value, namespaceUri, prefix);
+                    }
+                }
+            else
+                {
+                if ( prefix == KNullDesC8 )
+                    {
+                    aElement.AddNamespaceDeclarationL(namespaceUri, KNullDesC8);
+                    aElement.AddNewAttributeWithNsL(localName, value, namespaceUri);
+                    }
+                else
+                    {
+                    aElement.AddNewAttributeL(localName, value, namespaceUri, prefix);
+                    }
+                }
+            }
+        }
+    }
+
+EXPORT_C void CSenFragmentBase::AddAttributesL(const RAttributeArray& apAttrs)
+    {
+    AddAttributesToElementL(AsElementL(), apAttrs);
+    }
+
+EXPORT_C RSenDocument& CSenFragmentBase::AsDocumentL()
+    {
+    return iDocument;
+    }
+
+EXPORT_C TXmlEngElement CSenFragmentBase::AsElementL()
+    {
+    __ASSERT_ALWAYS(iElement.NotNull(), User::Panic(KSenFragmentPanic, EFragmentElementNotInitialized));
+    
+    return iElement;
+    }
+    
+void CSenFragmentBase::RenameL(const TDesC8& aLocalName, const TDesC8& aPrefix, const TDesC8& aNamespace)
+    {
+    WsXmlUtils domUtils;       
+    domUtils.XmlEngRenameElementL(AsElementL(), aLocalName, aNamespace, aPrefix); // Note that in TElement the *prefix* is the last arg(!)
+    }
+
+void CSenFragmentBase::RenameL(const TDesC8& aLocalName, const TDesC8& aNamespace)
+    {
+    WsXmlUtils domUtils;       
+    domUtils.XmlEngRenameElementL(AsElementL(), aLocalName, aNamespace, KNullDesC8); // Note that in TElement the *prefix* is the last arg(!)
+    }
+    
+void CSenFragmentBase::RenameLocalNameL(const TDesC8& aLocalName)
+    {
+    WsXmlUtils domUtils;       
+    domUtils.XmlEngRenameElementL(AsElementL(), aLocalName, KNullDesC8, KNullDesC8); // Note that in TElement the *prefix* is the last arg(!)
+    }
+
+void CSenFragmentBase::RenameNamespaceL(const TDesC8& aNamespace)
+    {
+    WsXmlUtils domUtils;       
+    domUtils.XmlEngRenameElementL(AsElementL(), KNullDesC8, aNamespace, KNullDesC8); // Note that in TElement the *prefix* is the last arg(!)
+    }
+    
+void CSenFragmentBase::RenameNamespaceL(const TDesC8& aPrefix, const TDesC8& aNamespace)
+    {
+    WsXmlUtils domUtils;       
+    domUtils.XmlEngRenameElementL(AsElementL(), KNullDesC8, aNamespace, aPrefix); // Note that in TElement the *prefix* is the last arg(!)
+    }
+    
+void CSenFragmentBase::RenamePrefixL(const TDesC8& aPrefix)
+    {
+    WsXmlUtils domUtils;       
+    domUtils.XmlEngRenameElementL(AsElementL(), KNullDesC8, KNullDesC8, aPrefix); // Note that in TElement the *prefix* is the last arg(!)
+    }
+    
+EXPORT_C TXmlEngElement CSenFragmentBase::ExtractElement()
+    {
+    TXmlEngElement element = iDocument.DocumentElement();
+
+    if ( element.IsSameNode(iElement) )
+        {
+        // Unlink only when element is root element of this document.
+        //
+        // This fragment maybe delegate and element is still part
+        // of other Fragment's DOM Tree.
+        iElement.Unlink();
+        }
+
+    TXmlEngElement retElement = iElement;        
+    TXmlEngElement nullElement;
+    iElement = nullElement;
+    
+    return retElement;
+    }
+
+EXPORT_C void CSenFragmentBase::SetParser(CSenParser& aParser)
+    {
+    ipParser = &aParser;
+    }
+
+EXPORT_C void CSenFragmentBase::OnDelegateParsingL(CSenFragmentBase& aDelegate)
+    {
+    // Delegate parsing to a new Fragment, until we encounter 
+    // the end of an element with the given qualified name
+    aDelegate.SetOwner(*this);
+    aDelegate.ipParser = ipParser;
+    aDelegate.StartSavingContent();
+    SetContentHandler(aDelegate);
+    }
+
+EXPORT_C void CSenFragmentBase::OnDelegateParsingL(const RTagInfo& aElement, 
+                                                   const RAttributeArray& aAttributes, 
+                                                   TInt /*aErrorCode*/)
+    {
+    // Delegate parsing to a new Fragment, until we encounter the end of an
+    // element with the given qualified name
+    const TPtrC8 saxLocalName   = aElement.LocalName().DesC();
+    const TPtrC8 saxNsUri       = aElement.Uri().DesC();
+    const TPtrC8 saxPrefix      = aElement.Prefix().DesC();
+
+    TXmlEngElement element = AsElementL();
+    RSenDocument document = AsDocumentL();
+
+
+    __ASSERT_ALWAYS(
+        ipDelegate == NULL,
+        User::Panic(KSenFragmentPanic, EDelegatedFragmentAlreadySet)
+        );
+    ipDelegate = CSenFragmentBase::NewL(saxNsUri, 
+                                        saxLocalName, 
+                                        saxPrefix, 
+                                        aAttributes, 
+                                        element, 
+                                        document);
+
+    OnDelegateParsingL(*ipDelegate);
+    }
+
+EXPORT_C void CSenFragmentBase::StartSavingContent()
+    {
+    iState = KSenStateSave;
+    }
+
+EXPORT_C void CSenFragmentBase::SetOwner(CSenFragmentBase& aFragment)
+    {
+    ipOwner = &aFragment;
+    }
+
+EXPORT_C void CSenFragmentBase::OnResumeParsingFromL(const RTagInfo& aElement, TInt aErrorCode)
+    {
+    SetContentHandler(*this);
+    
+    // Destroy delegate
+    if ( ipDelegate )
+        {
+        HBufC8* pAsXml = ipDelegate->AsXmlL();
+        CleanupStack::PushL(pAsXml);
+                
+        delete ipDelegate; // free memory
+        ipDelegate = NULL;
+        
+        if ( !ipContentBuf )
+            {
+            ipContentBuf = CBufFlat::NewL(KFlatBufSize);
+            ipContentWriteStream = new (ELeave) RBufWriteStream;
+            ipContentWriteStream->Open(*ipContentBuf);
+            }
+        ipContentWriteStream->WriteL(*pAsXml);
+        
+        CleanupStack::PopAndDestroy(pAsXml);
+        }
+    
+    TInt currentState = KSenStateNotSet; // == -1
+    if ( iElement.NotNull() )
+        {
+        const TPtrC8 saxLocalName   = aElement.LocalName().DesC();
+        const TPtrC8 saxNsUri       = aElement.Uri().DesC();
+        TPtrC8 localName            = iElement.Name();
+        TPtrC8 nsUri                = iElement.NamespaceUri();
+    
+        if(localName == saxLocalName  && nsUri == saxNsUri)
+            {
+            currentState = iState;
+            // Before calling EndElementL, which may execute
+            // unpredictable amount of code in subclasses, the
+            // the state must be set to "ignore"
+            iState = KSenStateResume;
+            }
+        }
+    
+    OnEndElementL(aElement, aErrorCode);
+    // now check if current state was to be preserved
+    if(currentState!=KSenStateNotSet) // IOP
+        {
+        // restore the state preserved prior to
+        // "set ignore for endelement" -case
+        iState = currentState;
+        }
+    }
+
+EXPORT_C void CSenFragmentBase::OnStartElementL(const RTagInfo& aElement, 
+                                                const RAttributeArray& aAttributes, 
+                                                TInt aErrorCode) 
+    {
+    const TPtrC8 saxLocalName   = aElement.LocalName().DesC();
+    const TPtrC8 saxNsUri       = aElement.Uri().DesC();
+    const TPtrC8 saxPrefix      = aElement.Prefix().DesC();
+    
+    if ( iElement.IsNull() )
+        {
+        if ( saxNsUri == KNullDesC8 && saxPrefix == KNullDesC8 )
+            {
+            iDocument.CreateDocumentElementL(saxLocalName);
+            }
+        else
+            {
+            if ( saxPrefix == KNullDesC8 )
+                {
+                iDocument.CreateDocumentElementL(saxLocalName,
+                                                 saxNsUri,
+                                                 KNullDesC8);
+                }
+            else
+                {
+                iDocument.CreateDocumentElementL(saxLocalName,
+                                                 saxNsUri,
+                                                 saxPrefix);
+                }
+            }
+        iElement = iDocument.DocumentElement();        
+        }    
+    
+    TXmlEngElement element = AsElementL();
+    
+    TPtrC8 localName =  element.Name();
+    TPtrC8 nsUri(KNullDesC8);
+    if (element.NamespaceUri() != KNullDesC8)
+        {
+        nsUri.Set(element.NamespaceUri());
+        }
+    
+    if(iState == KSenStateIgnore)
+        {
+        if(localName == saxLocalName && nsUri == saxNsUri) 
+            {
+            iState = KSenStateSave;
+            AddNamespacesL();
+            AddAttributesL(aAttributes);
+            }
+        }
+    else if((iState & KSenStateSave) == KSenStateSave)
+        {
+        if(localName == saxLocalName && nsUri == saxNsUri)
+            {
+            // start a new BaseFragment otherwise we loose
+            // track of nested elements with the same name
+            OnDelegateParsingL(aElement, aAttributes, aErrorCode);
+            }
+        else
+            {
+            OnWriteStartElementL(aElement, aAttributes);
+            }
+        }
+    }
+
+EXPORT_C void CSenFragmentBase::OnEndElementL(const RTagInfo& aElement, TInt aErrorCode)
+    {
+    const TPtrC8 saxLocalName   = aElement.LocalName().DesC();
+    const TPtrC8 saxNsUri       = aElement.Uri().DesC();
+    const TPtrC8 saxPrefix      = aElement.Prefix().DesC();
+
+    TXmlEngElement element = AsElementL();
+
+    TPtrC8 localName =  element.Name();
+    TPtrC8 nsUri(KNullDesC8);
+    if (element.NamespaceUri() != KNullDesC8)
+        {
+        nsUri.Set(element.NamespaceUri());
+        }
+
+    if(localName == saxLocalName && nsUri == saxNsUri)
+        {
+        if(iState != KSenStateResume && ipOwner)
+            {
+            if ( ipContentBuf )
+                {
+                SetContentL(ipContentBuf->Ptr(0));
+            
+                delete ipContentBuf;
+                ipContentBuf = NULL;
+                delete ipContentWriteStream;
+                ipContentWriteStream = NULL;
+                }
+
+            ipOwner->OnResumeParsingFromL(aElement, aErrorCode);
+            return; // This is mandatory, since ResumeParsingFromL 
+                    // de-allocates delegate fragment!
+            }
+        iState = KSenStateIgnore;
+        }
+    if((iState & KSenStateSave) == KSenStateSave)
+        {
+        OnWriteEndElementL(aElement);
+        }
+    }
+
+EXPORT_C void CSenFragmentBase::OnContentL(const TDesC8& aBytes, TInt /*aErrorCode*/)
+    {
+    if((iState & KSenStateSave) == KSenStateSave)
+        {
+        if ( !ipContentBuf )
+            {
+            ipContentBuf = CBufFlat::NewL(KFlatBufSize);
+            ipContentWriteStream = new (ELeave) RBufWriteStream;
+            ipContentWriteStream->Open( *ipContentBuf );
+            }   
+        HBufC8* reEncoded = NULL;
+        TBool contentIncludesEncodedChars = EncodeXmlEscapesL( aBytes, reEncoded);
+        if ( contentIncludesEncodedChars )
+            {
+            CleanupStack::PushL( reEncoded );
+            ipContentWriteStream->WriteL( *reEncoded );
+            CleanupStack::PopAndDestroy( reEncoded  );
+            }
+        else
+            {
+            ipContentWriteStream->WriteL( aBytes );
+            }
+        }
+    }
+    
+EXPORT_C void CSenFragmentBase::OnStartDocumentL( const RDocumentParameters& /*aDocParam*/,
+                                                  TInt /*aErrorCode*/ )
+    {
+    if ( !ipContentBuf )
+        {
+        ipContentBuf = CBufFlat::NewL(KFlatBufSize);
+        ipContentWriteStream = new (ELeave) RBufWriteStream;
+        ipContentWriteStream->Open(*ipContentBuf);
+        }
+    }
+
+EXPORT_C void CSenFragmentBase::OnEndDocumentL(TInt /*aErrorCode*/)
+    {
+    if ( ipNamespaceArray)
+        {
+        ipNamespaceArray->ResetAndDestroy();
+        delete ipNamespaceArray;
+        ipNamespaceArray = NULL;
+        }
+    
+    if ( ipContentBuf )
+        {
+        if ( ipContentBuf->Ptr(0).Length() > 0 )
+            {
+            SetContentL(ipContentBuf->Ptr(0));
+            }
+
+        delete ipContentBuf;
+        ipContentBuf = NULL;
+        delete ipContentWriteStream;
+        ipContentWriteStream = NULL;
+        }
+    }
+
+EXPORT_C void CSenFragmentBase::OnStartPrefixMappingL(
+                                    const RString& aPrefix,
+                                    const RString& aUri,
+                                    TInt /*aErrorCode*/)
+    {
+    if ( !ipNamespaceArray )
+        {
+        ipNamespaceArray = new (ELeave) RPointerArray<CSenNamespaceData>;
+        }
+
+    CSenNamespaceData* pNamespaceData = new (ELeave) CSenNamespaceData;
+    CleanupStack::PushL(pNamespaceData);
+    pNamespaceData->ipNamespaceUri  = aUri.DesC().AllocL();
+    if (aPrefix.DesC() != KNullDesC8)
+        {
+        pNamespaceData->ipPrefix    = aPrefix.DesC().AllocL();
+        }
+    User::LeaveIfError(ipNamespaceArray->Append(pNamespaceData));
+    CleanupStack::Pop(pNamespaceData);
+    }
+
+EXPORT_C void CSenFragmentBase::OnEndPrefixMappingL(
+                                    const RString& /*aPrefix*/,
+                                    TInt /*aErrorCode*/)
+    {
+    }
+
+EXPORT_C void CSenFragmentBase::OnIgnorableWhiteSpaceL(
+                                    const TDesC8& /*aBytes*/,
+                                    TInt /*aErrorCode*/)
+    {
+    }
+
+EXPORT_C void CSenFragmentBase::OnSkippedEntityL(
+                                    const RString& /*aName*/,
+                                    TInt /*aErrorCode*/)
+    {
+    }
+
+EXPORT_C void CSenFragmentBase::OnProcessingInstructionL(
+                                    const TDesC8& /*aTarget*/,
+                                    const TDesC8& /*aData*/,
+                                    TInt /*aErrorCode*/)
+    {
+    }
+
+EXPORT_C void CSenFragmentBase::OnError(TInt /*aErrorCode*/)
+    {
+    }
+
+EXPORT_C TAny* CSenFragmentBase::GetExtendedInterface(const TInt32 /*aUid*/)
+    {
+    return NULL;
+    }    
+
+
+EXPORT_C void CSenFragmentBase::ResetContentL()
+    {
+    TXmlEngElement element = AsElementL();
+    element.RemoveChildren();
+    }
+
+EXPORT_C TPtrC8 CSenFragmentBase::ContentL()
+    {
+    TXmlEngElement element = AsElementL();
+    return element.Text();
+    }
+
+
+EXPORT_C HBufC* CSenFragmentBase::AsXmlUnicodeL()
+    {
+    HBufC8* pAsXml = AsXmlL();
+    CleanupStack::PushL(pAsXml);
+    HBufC16* pBuf = HBufC16::NewL(2 * pAsXml->Length());
+    CleanupStack::PushL(pBuf);
+    TPtr16 des = pBuf->Des();
+    TInt ret = CnvUtfConverter::ConvertToUnicodeFromUtf8(des, *pAsXml);
+    User::LeaveIfError(ret);
+    CleanupStack::Pop(pBuf);
+    CleanupStack::PopAndDestroy(pAsXml);
+    return pBuf;
+    }
+
+EXPORT_C HBufC8* CSenFragmentBase::AsXmlL()
+    {
+    TXmlEngElement element = AsElementL();
+    
+    TUint optionFlags = 0;
+    // Omit following declarations from the beginning of XML Document:
+    // <?xml version=\"1.0\...
+    //   encoding="..."
+    //   standalone="..."
+    // ?>
+    optionFlags = optionFlags | TXmlEngSerializationOptions::KOptionOmitXMLDeclaration;
+    
+    // Allow encoding declaration (if KOptionOmitXMLDeclaration is _not_ set)
+    //optionFlags = optionFlags | TSerializationOptions::KOptionEncoding;
+    
+    // Allow standalone declaration (if KOptionOmitXMLDeclaration is _not_ set)
+    //optionFlags = optionFlags | TSerializationOptions::KOptionStandalone;
+
+    TXmlEngSerializationOptions options(optionFlags);
+
+    RBuf8 asXml;
+    iDocument.SaveL(asXml, element, options);
+    CleanupClosePushL(asXml);
+    HBufC8* pAsXml = asXml.AllocL();
+    CleanupStack::PopAndDestroy(&asXml);
+
+    return pAsXml;
+    }
+    
+
+EXPORT_C void CSenFragmentBase::WriteAsXMLToL(RWriteStream& aWs)
+    {
+    HBufC8* pAsXml = AsXmlL();
+    CleanupStack::PushL(pAsXml);
+    aWs.WriteL(*pAsXml);
+    CleanupStack::PopAndDestroy(pAsXml);
+    }
+
+EXPORT_C TPtrC8 CSenFragmentBase::ContentOf(const TDesC8& aLocalName)
+    {
+    TInt err( KErrNone );
+    RXmlEngNodeList<TXmlEngElement> list;
+    TRAP(   
+        err, 
+        TXmlEngElement element = AsElementL(); 
+        element.GetElementsByTagNameL(list, aLocalName);
+        )
+    if ( !err && list.Count() > 0 )
+        {
+        TXmlEngElement firstElement = list.Next();
+        return firstElement.Text();
+        }
+    return KNullDesC8();
+    }
+
+EXPORT_C TXmlEngElement CSenFragmentBase::SetContentOfL(const TDesC8& aLocalName,
+                                                      const TDesC8& aContent)
+    {
+    TXmlEngElement element = AsElementL();
+    RXmlEngNodeList<TXmlEngElement> list;
+    CleanupClosePushL(list);
+    
+    element.GetElementsByTagNameL(list, aLocalName);
+        
+    if ( list.Count() > 0 )
+        {
+        TXmlEngElement firstElement = list.Next();
+        firstElement.SetTextNoEncL(aContent);
+        return firstElement;
+        }
+    CleanupStack::PopAndDestroy(&list);
+
+    TXmlEngElement newElement = element.AddNewElementL(aLocalName);
+    newElement.SetTextNoEncL(aContent);
+    return newElement;
+    }
+
+EXPORT_C void CSenFragmentBase::OnWriteStartElementL(const RTagInfo& aElement,  
+                                                     const RAttributeArray& aAttributes)
+    {
+    const TPtrC8 saxLocalName   = aElement.LocalName().DesC();
+    const TPtrC8 saxNsUri       = aElement.Uri().DesC();
+    const TPtrC8 saxPrefix      = aElement.Prefix().DesC();
+    
+    if ( !ipContentBuf )
+        {
+        ipContentBuf = CBufFlat::NewL(KFlatBufSize);
+        ipContentWriteStream = new (ELeave) RBufWriteStream;
+        ipContentWriteStream->Open(*ipContentBuf);
+        }
+    
+    ipContentWriteStream->WriteL(KSenLessThan);
+    if (saxPrefix != KNullDesC8)
+        {
+        ipContentWriteStream->WriteL(saxPrefix);
+        ipContentWriteStream->WriteL(KSenColon);
+        }
+    ipContentWriteStream->WriteL(saxLocalName);
+
+    TInt startPoint(0);
+    if ( !ipParser->IsFeatureEnabled(EReportNamespaceMapping) )
+        {
+        if ( !ipNamespaceArray)
+            {
+            ipNamespaceArray = new (ELeave) RPointerArray<CSenNamespaceData>;
+            }
+
+        // Collect namespace declaration from this element (if it's not
+        // previously defined)
+        TBool found(EFalse);
+        if ( saxNsUri != KNullDesC8 )
+            {
+            // Check if element of this document has already handled
+            // namespace definition.
+            TXmlEngNamespace ns = AsElementL().LookupNamespaceByUriL(saxNsUri);
+            if ( ns.NotNull() )
+                {
+                found = ETrue;
+                }
+            else
+                {
+                // Check if internal namespace array has already handled
+                // namespace defintion. <= Means that one of the parent
+                // elements (in flat content) has already namespace
+                // definition we are dealing with.
+                TInt jcount = ipNamespaceArray->Count();
+                for (TInt j=0; j < jcount; j++)
+                    {
+                    CSenNamespaceData* pNamespace = (*ipNamespaceArray)[j];
+                    if ( pNamespace->ipPrefix && *(pNamespace->ipPrefix) == saxPrefix )
+                        {
+                        if ( *pNamespace->ipNamespaceUri == saxNsUri )
+                            {
+                            found = ETrue;
+                            break;
+                            }
+                        }
+                    }
+                }
+            }
+
+        startPoint = ipNamespaceArray->Count();
+        if ( !found )
+            {
+            CSenNamespaceData* pNamespaceData = new (ELeave) CSenNamespaceData;
+            CleanupStack::PushL(pNamespaceData);
+            TInt retVal = ipNamespaceArray->Append(pNamespaceData);
+            User::LeaveIfError(retVal);
+            CleanupStack::Pop(pNamespaceData);
+            if (retVal == KErrNone )
+                {
+                pNamespaceData->ipNamespaceUri  = saxNsUri.AllocL();
+                pNamespaceData->ipPrefix        = saxPrefix.AllocL();
+                pNamespaceData->ipLocalName     = saxLocalName.AllocL();
+                }
+            }
+        
+        // Collect new (not previously defined) namespaces from attributes
+        TInt attCount(aAttributes.Count());
+        for ( TInt i = 0; i < attCount; i++)
+            {
+            found = EFalse;
+            TPtrC8 nsUri = aAttributes[i].Attribute().Uri().DesC();
+            if ( nsUri != KNullDesC8 )
+                {
+                TPtrC8 nsPrefix = aAttributes[i].Attribute().Prefix().DesC();
+                TBool found(EFalse);
+                // Check if element of this document has already handled
+                // namespace definition.
+                TXmlEngNamespace ns = AsElementL().LookupNamespaceByUriL(nsUri);
+                if ( ns.NotNull() )
+                    {
+                    found = ETrue;
+                    }
+                else
+                    {
+                    // Check if internal namespace array has already handled
+                    // namespace defintion. <= Means that one of the parent
+                    // elements (in flat content) has already namespace
+                    // definition we are dealing with.
+                    TInt jcount = ipNamespaceArray->Count();
+                    for (TInt j=0; j < jcount; j++)
+                        {
+                        CSenNamespaceData* pNamespace = (*ipNamespaceArray)[j];
+                        if ( pNamespace->ipPrefix && *(pNamespace->ipPrefix) == nsPrefix )
+                            {
+                            if ( *pNamespace->ipNamespaceUri == nsUri )
+                                {
+                                found = ETrue;
+                                break;
+                                }
+                            }
+                        }
+                    }
+                    
+                // If namespace was not found
+                // namespace will be added to internal array 
+                if ( !found )
+                    {
+                    CSenNamespaceData* pNamespaceData
+                                            = new (ELeave) CSenNamespaceData;
+                    CleanupStack::PushL(pNamespaceData);
+                    TInt retVal = ipNamespaceArray->Append(pNamespaceData);
+                    User::LeaveIfError(retVal);
+                    CleanupStack::Pop(pNamespaceData);
+                    if (retVal == KErrNone )
+                        {
+                        pNamespaceData->ipNamespaceUri  = nsUri.AllocL();
+                        pNamespaceData->ipPrefix        = nsPrefix.AllocL();
+                        if ( startPoint == ipNamespaceArray->Count() )
+                            {
+                            pNamespaceData->ipLocalName = saxLocalName.AllocL();
+                            }
+                        }
+                    }
+                }
+            }
+        }
+        
+    // Write namespaces, if any
+    if ( ipNamespaceArray )
+        {
+        TInt count = ipNamespaceArray->Count();
+        for (TInt i=startPoint; i < count; i++)
+            {
+            CSenNamespaceData* pNamespace = (*ipNamespaceArray)[i];
+            ipContentWriteStream->WriteL(KSenSpace);
+            ipContentWriteStream->WriteL(KSenXmlns);
+            if ( pNamespace->ipPrefix && *(pNamespace->ipPrefix) != KNullDesC8 )
+                {
+                ipContentWriteStream->WriteL(KSenColon);
+                ipContentWriteStream->WriteL(*pNamespace->ipPrefix);
+                }
+            ipContentWriteStream->WriteL(KSenEqualsDblQuot);
+            ipContentWriteStream->WriteL(*pNamespace->ipNamespaceUri);
+            ipContentWriteStream->WriteL(KSenDblQuot);
+            }
+            
+        if ( ipParser->IsFeatureEnabled(EReportNamespaceMapping) )
+            {
+            ipNamespaceArray->ResetAndDestroy();
+            }
+        }
+
+    // Write attributes, if any
+    TInt attCount(aAttributes.Count());
+    for (TInt i = 0; i < attCount; i++)
+        {
+        TPtrC8 prefix   = aAttributes[i].Attribute().Prefix().DesC();
+        TPtrC8 lAttName = aAttributes[i].Attribute().LocalName().DesC();
+        TPtrC8 attValue = aAttributes[i].Value().DesC();
+
+        ipContentWriteStream->WriteL(KSenSpace);
+        if (prefix != KNullDesC8)
+            {
+            ipContentWriteStream->WriteL(prefix);
+            ipContentWriteStream->WriteL(KSenColon);
+            }
+        ipContentWriteStream->WriteL(lAttName);
+
+        ipContentWriteStream->WriteL(KSenEqualsDblQuot);
+        ipContentWriteStream->WriteL(attValue);
+        ipContentWriteStream->WriteL(KSenDblQuot);
+        }
+
+    ipContentWriteStream->WriteL(KSenGreaterThan);
+    }
+
+EXPORT_C void CSenFragmentBase::OnWriteEndElementL(const RTagInfo& aElement)
+    {
+    const TPtrC8 saxLocalName = aElement.LocalName().DesC();
+    const TPtrC8 saxNsUri = aElement.Uri().DesC();
+    const TPtrC8 saxPrefix = aElement.Prefix().DesC();
+
+    if ( !ipContentBuf )
+        {
+        ipContentBuf = CBufFlat::NewL(KFlatBufSize);
+        ipContentWriteStream = new (ELeave) RBufWriteStream;
+        ipContentWriteStream->Open(*ipContentBuf);
+        }
+    
+    if ( ipNamespaceArray && !ipParser->IsFeatureEnabled(EReportNamespaceMapping) )
+        {
+        TInt foundIndex(KErrNotFound);
+        TInt jcount = ipNamespaceArray->Count();
+        for (TInt j=jcount-1; j >= 0 ; j--)
+            {
+            CSenNamespaceData* pNamespace = (*ipNamespaceArray)[j];
+            if ( pNamespace->ipLocalName != NULL )
+                {
+                if ( *pNamespace->ipLocalName == saxLocalName )
+                    {
+                    foundIndex = j;
+                    }
+                break;
+                }
+            }
+        if ( foundIndex != KErrNotFound )
+            {
+            for (TInt j=foundIndex; j < jcount; j++)
+                {
+                delete (*ipNamespaceArray)[foundIndex];
+                ipNamespaceArray->Remove(foundIndex);
+                }
+            }
+        }
+
+    // Check if EndTag should be written or not.
+    // There is no need to write EndTag if
+    // previous tag is StartTag for this element
+    // and there is no content for the element.
+    TBool writeEndTag = ETrue;        
+    TInt size = ipContentBuf->Size();
+    if ( size > 1 )
+        {
+        // Check if first character before this possible
+        // EndTag is '>'
+        if ( ipContentBuf->Ptr(size-1) == KSenGreaterThan )
+            {
+            // This element does not have content
+            // There is possibility that EndTag is not needed
+            TInt colon = KErrNotFound;
+            TInt space = KErrNotFound;
+            TBool insideDblQuot = EFalse;
+            
+            // Search backwards first '<'.
+            // Search also first ':' and space which
+            // are right after '<' (if those characters
+            // can be found).
+            // 
+            // => Following situations are handled:
+            // 1) <prefix:localname attr...>
+            // 2) <prefix:localname>
+            // 3) <localname>
+            TInt i=size-2;
+            TPtrC8 currentCharacter(KNullDesC8);
+            for (; i > 0; i--)
+                {
+                currentCharacter.Set(ipContentBuf->Ptr(i).Left(1));
+                
+                if ( currentCharacter == KSenDblQuot ) 
+                    {
+                    if ( insideDblQuot )
+                        {
+                        insideDblQuot = EFalse;
+                        }
+                    else
+                        {
+                        insideDblQuot = ETrue;
+                        }
+                    }
+                else if ( !insideDblQuot )
+                    {
+                    if ( currentCharacter == KSenSlash ) 
+                        {
+                        i = KErrNotFound;
+                        break;
+                        }
+                    else if ( currentCharacter == KSenLessThan ) 
+                        {
+                        break;
+                        }
+                    else if ( currentCharacter == KSenColon )
+                        {
+                        colon = i;
+                        }
+                    else if ( currentCharacter == KSenSpace )
+                        {
+                        colon = KErrNotFound;
+                        space = i;
+                        }
+                    }
+                }
+
+            // Now that we know place of '<' character and
+            // also places of ':' and space characters (if
+            // those two characters exist),
+            // we can find out possible prefix and localname.
+            if ( i > 0 )
+                {
+                TPtrC8 localNamePtr(KNullDesC8);
+                TPtrC8 prefixPtr(KNullDesC8);
+                if ( colon != KErrNotFound )
+                    {
+                    // Both Prefix and LocalName can be found.
+                    if ( space != KErrNotFound )
+                        {
+                        localNamePtr.Set(ipContentBuf->Ptr(colon+1).MidTPtr(0, space-colon-1));
+                        }
+                    else
+                        {
+                        localNamePtr.Set(ipContentBuf->Ptr(colon+1).MidTPtr(0, size-colon-2));
+                        }
+                    prefixPtr.Set(ipContentBuf->Ptr(i+1).MidTPtr(0, colon-i-1));
+                    }
+                else
+                    {
+                    // Only LocalName can be found.
+                    if ( space != KErrNotFound )
+                        {
+                        localNamePtr.Set(ipContentBuf->Ptr(i+1).MidTPtr(0, space-i-1));
+                        }
+                    else
+                        {
+                        localNamePtr.Set(ipContentBuf->Ptr(i+1).MidTPtr(0, size-i-2));
+                        }
+                    }
+                
+                // Do comparison for localname and prefix of
+                // this EndTag
+                if ( ( localNamePtr == saxLocalName ) && 
+                     ( prefixPtr == saxPrefix ) )
+                    {
+                    // LocalName and prefix matched. So
+                    // the EndTag should not be written.
+                    // => Now the last character '>' of StartTag can
+                    //    be replaced with characters '\' and '>'
+                    //    which means that element is closed without
+                    //    separate EndTag.
+                    ipContentBuf->Delete((ipContentBuf->Size()-1),1);
+                    ipContentBuf->InsertL((ipContentBuf->Size()), KSenSlash);
+                    ipContentWriteStream->WriteL(KSenGreaterThan);
+                    writeEndTag = EFalse;
+                    }
+                }
+            }
+        }
+    
+    if ( writeEndTag )
+        {
+        ipContentWriteStream->WriteL(KSenLessThanSlash());
+        
+        if ( saxPrefix.Length() > 0)
+            {
+            HBufC8*  pQName = HBufC8::NewLC( saxPrefix.Length()
+                                             +KSenColon().Length()
+                                             +saxLocalName.Length());
+            TPtr8 qname = pQName->Des();
+            qname.Append(saxPrefix);
+            qname.Append(KSenColon);
+            qname.Append(saxLocalName);
+            ipContentWriteStream->WriteL(qname);
+            CleanupStack::PopAndDestroy(pQName);
+            }
+        else
+            {
+            ipContentWriteStream->WriteL(saxLocalName);
+            }
+       
+        ipContentWriteStream->WriteL(KSenGreaterThan());
+        }    
+    }
+
+EXPORT_C TXmlEngNamespace CSenFragmentBase::Namespace(const TDesC8& aPrefix)
+    {
+    TXmlEngNamespace ns;
+    if (aPrefix.Length() == 0) return ns;
+    TRAP_IGNORE
+        (    
+        TXmlEngElement element = AsElementL();
+        ns = element.LookupNamespaceByPrefixL(aPrefix);
+        )
+    return ns;
+    }
+
+/*EXPORT_C void CSenFragmentBase::DetachL()
+    {
+    //First add all the namespaces referred to in the content.
+    if (iNamespaces.Count() > 0)
+        {
+        TInt count(iNamespaces.Count());
+        for (TInt i=0; i<count; i++)
+            {
+            CSenNamespace* pNamespace = (CSenNamespace*) iNamespaces[i];
+            ipElement->AddNamespaceL(*pNamespace, EFalse);
+            //TRAPD(err, ipElement->AddNamespaceL(*pNamespace, EFalse));
+            //if (err) ;
+            }
+        }
+    //Detach the element from its parent.
+    ipElement->DetachL();
+    }*/
+
+EXPORT_C TPtrC8 CSenFragmentBase::LocalName() const
+    {
+    __ASSERT_ALWAYS(iElement.NotNull(), User::Panic(KSenFragmentPanic, EFragmentElementNotInitialized));
+        
+    return iElement.Name();
+    }
+
+EXPORT_C TPtrC8 CSenFragmentBase::NsUri() const
+    {
+    __ASSERT_ALWAYS(iElement.NotNull(), User::Panic(KSenFragmentPanic, EFragmentElementNotInitialized));
+
+    return iElement.NamespaceUri();
+    }
+
+EXPORT_C TPtrC8 CSenFragmentBase::NsPrefix() const
+    {
+    __ASSERT_ALWAYS(iElement.NotNull(), User::Panic(KSenFragmentPanic, EFragmentElementNotInitialized));
+
+    return iElement.Prefix();
+    }
+    
+EXPORT_C TBool CSenFragmentBase::ConsistsOfL(TXmlEngElement& aElement, TXmlEngElement& aCandidate)
+    {
+    // First check the names and namespaces
+    TPtrC8 elementLocalName         = aElement.Name();
+    TPtrC8 candidateLocalName       = aCandidate.Name();
+    // Check localnames (element should always have localname
+    //                  <=> localname can't be Null).
+    if ( elementLocalName != candidateLocalName )
+        {
+        return EFalse;
+        }
+        
+    TPtrC8 elementNamespaceUri      = aElement.NamespaceUri();
+    TPtrC8 candidateNamespaceUri    = aCandidate.NamespaceUri();
+    // Check namespaceUris (element does not always have namespaceUri
+    //                      <=> namespaceUri can be Null).
+    if ( elementNamespaceUri != KNullDesC8 && candidateNamespaceUri != KNullDesC8 )
+        {
+        if ( elementNamespaceUri != candidateNamespaceUri )
+            {
+            return EFalse;
+            }
+        }
+    else
+        {
+        if ( elementNamespaceUri != KNullDesC8 || candidateNamespaceUri != KNullDesC8 )
+            {
+            return EFalse;
+            }
+        }
+        
+    TPtrC8 elementPrefix            = aElement.Prefix();
+    TPtrC8 candidatePrefix          = aCandidate.Prefix();
+    // Check prefixes (element does not always have prefix
+    //                 <=> prefix can be Null).
+    if ( elementPrefix != KNullDesC8 && candidatePrefix != KNullDesC8 )
+        {
+        if ( elementPrefix != candidatePrefix )
+            {
+            return EFalse;
+            }
+        }
+    else
+        {
+        if ( elementPrefix != KNullDesC8 || candidatePrefix != KNullDesC8 )
+            {
+            return EFalse;
+            }
+        }
+
+    RBuf8 candidateContent;
+    aCandidate.WholeTextContentsCopyL(candidateContent);
+    CleanupClosePushL(candidateContent);
+    RBuf8 content;
+    aElement.WholeTextContentsCopyL(content);
+    CleanupClosePushL(content);
+    if ( candidateContent != content )
+        {
+        CleanupStack::PopAndDestroy(&content);
+        CleanupStack::PopAndDestroy(&candidateContent);
+        return EFalse;  // Content doesn't match => no match
+        }
+    CleanupStack::PopAndDestroy(&content);
+    CleanupStack::PopAndDestroy(&candidateContent);
+    
+    // Then handle the children
+    RXmlEngNodeList<TXmlEngElement> candidateChildren;
+    CleanupClosePushL(candidateChildren);
+    aCandidate.GetChildElements(candidateChildren);
+
+    RXmlEngNodeList<TXmlEngElement> children;
+    CleanupClosePushL(children);
+    aElement.GetChildElements(children);
+    
+    // Element should have at least as many child elements
+    // as candidateElement has.
+    TInt childrenCount = children.Count();
+    TInt candidateChildrenCount = candidateChildren.Count();
+    if ( childrenCount < candidateChildrenCount )
+        {
+        CleanupStack::PopAndDestroy(&children);
+        CleanupStack::PopAndDestroy(&candidateChildren);
+        return EFalse;
+        }
+    
+    // Every child element of candidate should be found
+    // from element.
+    while ( candidateChildren.HasNext() )
+        {
+        TXmlEngElement candidateMatchChild = candidateChildren.Next();
+        RXmlEngNodeList<TXmlEngElement> matchChilds;
+        CleanupClosePushL(matchChilds);
+
+        aElement.GetElementsByTagNameL(matchChilds,
+                                       candidateMatchChild.Name(),
+                                       candidateMatchChild.NamespaceUri());
+        if ( !matchChilds.HasNext() )
+            {
+            CleanupStack::PopAndDestroy(&matchChilds);
+            CleanupStack::PopAndDestroy(&children);
+            CleanupStack::PopAndDestroy(&candidateChildren);
+            return EFalse;
+            }
+        else
+            {
+            TBool found = EFalse;
+            while ( matchChilds.HasNext() )
+                {
+                TXmlEngElement matchChild = matchChilds.Next();
+                found = ConsistsOfL(matchChild, candidateMatchChild);
+                if ( found ) break;
+                }
+            if ( !found )
+                {
+                CleanupStack::PopAndDestroy(&matchChilds);
+                CleanupStack::PopAndDestroy(&children);
+                CleanupStack::PopAndDestroy(&candidateChildren);
+                return EFalse;
+                }
+            }
+            
+        CleanupStack::PopAndDestroy(&matchChilds);
+        }
+        
+    CleanupStack::PopAndDestroy(&children);
+    CleanupStack::PopAndDestroy(&candidateChildren);
+    return ETrue;    
+    }
+
+EXPORT_C TBool CSenFragmentBase::ConsistsOfL(CSenFragmentBase& aCandidate)
+    {
+    TXmlEngElement element          = AsElementL();
+    TXmlEngElement candidateElement = aCandidate.AsElementL();
+    return ConsistsOfL(element, candidateElement);
+    }
+
+EXPORT_C void CSenFragmentBase::SetContentHandler(
+                                            CSenFragmentBase& aContentHandler)
+    {
+    ipParser->SetContentHandler(aContentHandler);
+    }
+
+EXPORT_C void CSenFragmentBase::SetContentL(const TDesC8& aContent)
+    {
+    TXmlEngElement element = AsElementL();
+    element.SetTextNoEncL(aContent);
+    }
+
+EXPORT_C void CSenFragmentBase::AddContentL(const TDesC8& aContent)
+    {
+    TPtrC8 content = ContentL();
+    TXmlEngElement element = AsElementL();
+    if ( content.Length() > 0 )
+        {
+        HBufC8* pContent = HBufC8::NewLC( content.Length() + aContent.Length() );
+        TPtr8 ptrContent = pContent->Des();
+        ptrContent.Append(content);
+        ptrContent.Append(aContent);
+        element.SetTextNoEncL(*pContent);
+        CleanupStack::PopAndDestroy(pContent);
+        }
+    else
+        {
+        element.SetTextNoEncL(aContent);
+        }
+    }
+    
+EXPORT_C void CSenFragmentBase::SetDocument(RSenDocument& aDocument)
+    {
+    iDocument.Close();
+    iDocument = aDocument.Copy();
+    }
+
+CSenNamespaceData::~CSenNamespaceData()
+    {
+    delete ipNamespaceUri;
+    delete ipPrefix;
+    delete ipLocalName;
+    }
+
+// End of File
+
+