webservices/wscore/src/senxmldao.cpp
changeset 0 62f9d29f7211
child 20 32ab7ae9ec94
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/webservices/wscore/src/senxmldao.cpp	Thu Jan 07 16:19:19 2010 +0200
@@ -0,0 +1,1971 @@
+/*
+* Copyright (c) 2002-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 <f32file.h>
+#include <s32file.h>
+#include <s32strm.h>
+#include <e32std.h>
+#include <sysutil.h>
+#include <eikenv.h>
+#include <s32mem.h>
+
+#include <SenServiceConnection.h> // error codes and framework ids
+#include <MSenServiceDescription.h>
+#include "senwsdescription.h"
+#include <SenXmlUtils.h>          // static attribute value getter
+#include <SenXmlReader.h>
+
+#include "senprovider.h"
+#include "senxmldao.h"
+#include "msencoreservicemanager.h"
+
+#include "senservicemanagerdefines.h" // KMaxTicks (1209600000)
+                                      // 1 tick = 1 millisec
+                                      // 86400 sec = 1 day
+                                      // 86400*1000 millisec = 1 day
+                                      // 86400*14*1000 = 1209600000 millisec = 2 weeks
+
+#include "senlogger.h"
+#include "sendebug.h"                       // internal Utils\inc
+#include "msenserviceinvocationframework.h" // internal Framework\inc
+#include "senserviceinvocationframework.h"  // internal Framework\inc
+#include "sensecuritymechanism.h"           // internal Framework\inc
+#include "senservicesession.h"              // internal Framework\inc
+
+#include "senprovider.h"
+
+#include "senlogger.h" 
+
+
+// CONSTANTS
+namespace
+    {
+    const TInt KFlatBufSize = 128;
+
+#if !defined( EKA2 ) && !defined( RD_SECURE_PRIV_DATA )
+     _LIT(KSenXMLDAOFile,        "C:\\system\\data\\sensessions.xml");
+     // since CoreSM & XMLDAO are singleton, single temp file is ok:
+     _LIT(KSenXMLDAOTempFile,    "C:\\system\\data\\sensessions.temp.xml");
+#else
+    _LIT(KSenXMLDAOFile,        "sensessions.xml");
+    // since CoreSM & XMLDAO are singleton, single temp file is ok:
+    _LIT(KSenXMLDAOTempFile,    "sensessions.temp.xml");
+#endif   
+
+    //_LIT(KSenXmlDaoPanic, "SenXmlDao");
+
+    _LIT8(KDefaultFrameworkCue1,
+                "com.nokia.Sen.idwsf.IdentityBasedWebServicesFramework");
+    _LIT8(KDefaultFrameworkCue2,
+                "com.nokia.Sen.wsi.WSIBasicFramework");
+    _LIT8(KDefaultFrameworkCue3,
+                "com.nokia.Sen.rest.RestServiceFramework");
+    _LIT8(KDefaultFrameworkCue4,
+                "com.nokia.ws.wsstar.WSStarFramework");
+    _LIT8(KDefaultFrameworkCue5,
+                "com.nokia.ws.atompub.AtomPubFramework");
+    _LIT8(KDefaultFrameworkCue6,
+                "com.nokia.ws.ovi.OviFramework");
+
+    _LIT8(KEqual, "=");
+    _LIT8(KQuote, "\"");
+    _LIT8(KCloseTag, ">");
+    _LIT8(KEmptySpace, " ");
+
+    _LIT8(KServiceDescription, "ServiceDescription");
+    _LIT8(KFramework, "Framework");
+    _LIT8(KClass, "class");
+    _LIT8(KProxyHost, "proxyHost");
+    _LIT8(KProxyPort, "proxyPort");
+
+
+    _LIT8(KLocalName, "SenConfiguration");
+    _LIT8(KTransport,   "Transport");
+    _LIT8(KEndTag, "</SenConfiguration>");
+    _LIT8(KStartTag,
+            "<SenConfiguration xmlns=\"urn:com.nokia.Sen.config.1.0\">");
+    _LIT8(KStartTagEndless,
+            "<SenConfiguration xmlns=\"urn:com.nokia.Sen.config.1.0\"");
+    _LIT8(KNamespaceName, "urn:com.nokia.Sen.config.1.0");
+
+    _LIT8(KSpace, " ");
+    _LIT8(KTouch, "touch");
+
+    // Transport plug-in spesific constants:
+    _LIT8(KLocalTransportScheme,                "local");
+    _LIT8(KDefaultLocalTransportPluginCue,      "com.nokia.wsf.transport.plugin.local");
+
+    _LIT8(KTcpTransportScheme,                   "tcp");
+    _LIT8(KDefaultVirtualTcpTransportPluginCue,  "com.nokia.wsf.transport.plugin.virtualtcp");
+    }
+
+CSenXMLDAO* CSenXMLDAO::NewL(MSenCoreServiceManager& aManager)
+    {
+    CSenXMLDAO* pNew = CSenXMLDAO::NewLC(aManager);
+    CleanupStack::Pop();
+    return pNew;
+    }
+
+CSenXMLDAO* CSenXMLDAO::NewLC(MSenCoreServiceManager& aManager)
+    {
+    CSenXMLDAO* pNew = new (ELeave) CSenXMLDAO(aManager);
+    CleanupStack::PushL(pNew);
+
+    // SenConfiguration xmlns="urn:com.nokia.Sen.config.1.0">
+    pNew->ConstructL();
+    return pNew;
+    }
+
+CSenXMLDAO::CSenXMLDAO(MSenCoreServiceManager& aManager)
+    :iManager(aManager),
+    iReadingConfig(ESenIdle),
+    iErrorState(KErrNone),
+    iFileName(KSenXMLDAOFile),
+    iSessions(2),
+    iFrameworks(2),                     
+    iServiceDescription(NULL),
+    iFrameworkConfigParser(NULL),
+    iDefaultFrameworkCheckedToExist(EFalse),
+    iProxyHost(NULL),
+    iProxyPort(0),
+    iTransportMap(ETrue, ETrue),
+    iDefaultTransportMapChecked(EFalse),
+    iSharableProviders(2),              
+    iUnsharableProviders(ETrue, ETrue) 
+    {
+    }
+
+void CSenXMLDAO::ConstructL()
+    {
+    TLSLOG(KSenCoreServiceManagerLogChannelBase  , KMinLogLevel,(_L("CSenXMLDAO ConstructL()")));
+    BaseConstructL(KNamespaceName(), KLocalName());
+    TLSLOG(KSenCoreServiceManagerLogChannelBase  , KMinLogLevel,(_L("CSenXMLDAO Base done")));
+
+
+    SetReader(*iManager.XMLReader());
+
+    //Data caging 2 implementation
+#if defined( EKA2 ) || defined( RD_SECURE_PRIV_DATA )
+    TBuf<KMaxPath> privatePath;
+    RFs fss;
+        User::LeaveIfError(fss.Connect());
+        CleanupClosePushL(fss);
+    fss.CreatePrivatePath(EDriveC);
+    fss.PrivatePath(privatePath);
+    iFileName.Insert(0,privatePath);
+    CleanupStack::PopAndDestroy(1);
+#endif
+    TLSLOG(KSenCoreServiceManagerLogChannelBase  , KMinLogLevel,(_L("CSenXMLDAO ConstructL() done")));
+    iCriticalSection.CreateLocal();
+    }
+
+CSenXMLDAO::~CSenXMLDAO()
+    {
+    // Save the XML
+    CSenXMLDAO::Save();
+
+    if(iServiceDescription)
+        {
+        TInt index = iSessions.Find(iServiceDescription);
+        if(index==KErrNotFound)
+            {
+            // would otherwise NOT be taken care by:
+            //             iSessions.ResetAndDestroy()
+            delete iServiceDescription;
+            }
+        }
+
+    iSessions.ResetAndDestroy();
+
+
+    if(iFrameworkConfigParser)
+        {
+        CSIF* pSIF = (CSIF*) iFrameworkConfigParser;
+
+        TInt index = iFrameworks.Find(pSIF);
+        if(index==KErrNotFound)
+            {
+            // otherwise deleted in ResetAndDestroy() below
+            delete iFrameworkConfigParser;
+            }
+        }
+    iFrameworks.ResetAndDestroy();
+
+    if ( iProxyHost )
+        {
+        delete iProxyHost;
+        iProxyHost = NULL;
+        }
+
+    iTransportMap.Reset();
+
+    iSharableProviders.ResetAndDestroy();
+    iUnsharableProviders.Reset(); // destroys any unloaded / unreleased providers..
+    iCriticalSection.Close();
+
+    if( ipTransportDelegate )
+        {
+        ipTransportDelegate->ExtractElement();
+        }
+    delete ipTransportDelegate;    
+    }
+
+CSenXmlReader* CSenXMLDAO::XMLReader()
+    {
+    return iManager.XMLReader();
+    }
+
+void CSenXMLDAO::Load()
+    {
+    TLSLOG(KSenCoreServiceManagerLogChannelBase  , KMinLogLevel,(_L("CSenXMLDAO::Load()")));
+    TInt leaveCode(KErrNone);
+    TRAP(leaveCode, ReadL());
+
+#ifdef _SENDEBUG
+    if(leaveCode!=KErrNone)
+        {
+        TLSLOG_FORMAT((KSenCoreServiceManagerLogChannelBase  , KMinLogLevel, _L8("CSenXMLDAO::Load() - ReadL() leaved: %d"), leaveCode));
+        }
+#else
+    leaveCode = 0; 
+#endif
+
+
+    // Default frameworks are checked (and loaded)after all the frameworks have
+    // been parsed in the MIDDLE of PARSING, to PREVENT possibility of orphan
+    // SD, if no ID-WSF plug-in was found, for example because ECOM cue
+    // (default_data) was wrong. MOVED the installation of default
+    // frameworks to be in StartElementL() instead(!)
+
+    // Handle the case where no frameworks or service descriptions were found 
+    // from sensessions.xml
+    if(!iDefaultFrameworkCheckedToExist)
+        {
+        TInt retVal = CheckDefaultFrameworks();
+        retVal = 0; // not used currently
+        iDefaultFrameworkCheckedToExist=ETrue;
+        }
+
+    if(!iDefaultTransportMapChecked)
+        {
+        TInt retCode = CheckDefaultTransports();
+        iDefaultTransportMapChecked=ETrue;
+        retCode=0; // not used currently
+        }
+
+    iReadingConfig = ESenIdle;
+
+    // This way the sensessions.xml -file is validated,
+    // and expired sessions will be deleted, etc..
+    TInt saveRetVal = Save();
+    saveRetVal = 0; // not used currently
+    }
+
+TInt CSenXMLDAO::Save()
+    {
+    TLSLOG(KSenCoreServiceManagerLogChannelBase  , KMinLogLevel,(_L("CSenXMLDAO::SaveSessions()")));
+    TInt notifyLeaveCode(KErrNone);
+    TRAP(notifyLeaveCode, NotifyFrameworksL(KNullDesC8, KSenEventSessionsDbWriteBegin, NULL));
+    TInt leaveCode(KErrNone);
+    TRAP(leaveCode, WriteL());
+    TRAP(notifyLeaveCode, NotifyFrameworksL(KNullDesC8, KSenEventSessionsDbWriteComplete, NULL));
+    
+    iManager.SaveCredentialDB();
+    
+    notifyLeaveCode = 0; // not used
+    return leaveCode;
+    }
+
+MSIF* CSenXMLDAO::Framework(const TDesC8& aFrameworkId)
+    {
+    TLSLOG_L(KSenCoreServiceManagerLogChannelBase  , KMinLogLevel,"CSenXMLDAO::Framework");
+    CSIF* pFramework = NULL;
+
+    TInt count(iFrameworks.Count());
+    for (TInt i=0; i<count; i++)
+        {
+        if(iFrameworks[i])
+            {
+            const TDesC8& frameworkId = iFrameworks[i]->Id();
+
+            if(frameworkId == aFrameworkId)
+                {
+                pFramework = iFrameworks[i];
+                break;
+                }
+            }
+        }
+    if(pFramework)  TLSLOG_L(KSenCoreServiceManagerLogChannelBase  , KMinLogLevel,"  framework found:");//LOG_WRITE_L("  framework found:");
+    else TLSLOG_L(KSenCoreServiceManagerLogChannelBase  , KMinLogLevel,"  could not find:");        //   LOG_WRITE_L("  could not find:");
+    TLSLOG(KSenCoreServiceManagerLogChannelBase  , KMaxLogLevel,(aFrameworkId));
+
+    return pFramework;
+    }
+
+MSIF* CSenXMLDAO::DefaultFrameworkL(const TDesC8& aFrameworkID, 
+                                    const TDesC8& aCue)
+    {
+    TLSLOG(KSenCoreServiceManagerLogChannelBase  , KMinLogLevel,(_L("CSenXMLDAO::DefaultFramework()")));
+
+    MSIF* pFramework = Framework(aFrameworkID);
+
+    if(!pFramework)
+        {
+        TLSLOG(KSenCoreServiceManagerLogChannelBase  , KMinLogLevel,(_L("CSenXMLDAO::DefaultFramework() is not installed:")));
+        TLSLOG(KSenCoreServiceManagerLogChannelBase  , KMaxLogLevel,(aFrameworkID));
+        TLSLOG(KSenCoreServiceManagerLogChannelBase  , KMaxLogLevel,(aCue));
+
+        TRAPD(leaveCode, iManager.InstallFrameworkL(aCue));
+        if(leaveCode==KErrNone)
+            {
+            pFramework = Framework(aFrameworkID);
+            if(pFramework)
+                {
+                TLSLOG(KSenCoreServiceManagerLogChannelBase  , KMaxLogLevel,(_L("CSenXMLDAO::DefaultFramework() - now installed.")));
+                }
+            }
+#ifdef _SENDEBUG
+        else
+            {
+            // install framework failed!
+            TLSLOG(KSenCoreServiceManagerLogChannelBase  , KMinLogLevel,(_L("CSenXMLDAO::DefaultFramework() - install failed:")));
+            TLSLOG_L(KSenCoreServiceManagerLogChannelBase  , KMinLogLevel,"FATAL!");
+            TLSLOG(KSenCoreServiceManagerLogChannelBase  , KMinLogLevel,(aCue));
+            }
+#endif //_SENDEBUG
+        }
+#ifdef _SENDEBUG
+    else
+        {
+        TLSLOG(KSenCoreServiceManagerLogChannelBase  , KMaxLogLevel,(_L("CSenXMLDAO::DefaultFramework() - was already installed:")));
+        TLSLOG(KSenCoreServiceManagerLogChannelBase  , KMaxLogLevel,(aFrameworkID));
+        TLSLOG(KSenCoreServiceManagerLogChannelBase  , KMaxLogLevel,(aCue));
+                   
+        }
+#endif //_SENDEBUG
+
+    return pFramework;
+    }
+
+RFileLogger* CSenXMLDAO::Log() const
+    {
+    return iManager.Log();
+    }
+
+TInt CSenXMLDAO::SizeOfSessionsXmlInBytesL()
+    {
+    TInt size(0);
+
+    TInt count = iSessions.Count();
+    CBufFlat* pBuf = NULL;
+    for(TInt i = 0; i < count; i++)
+        {
+        pBuf = CBufFlat::NewL(KFlatBufSize);
+        CleanupStack::PushL(pBuf);
+        RBufWriteStream bufWs(*pBuf);
+        CleanupClosePushL(bufWs);
+#ifdef _SENDEBUG
+        TPtrC8 e = iSessions[i]->Endpoint();
+        TPtrC8 c = iSessions[i]->Contract();
+        TPtrC8 fid = iSessions[i]->FrameworkId();
+        TInt leaveCode(KErrNone);
+        TRAP( leaveCode, iSessions[i]->WriteAsXMLToL(bufWs); )
+        if( leaveCode )
+            {
+            TLSLOG_FORMAT((KSenCoreServiceManagerLogChannelBase  , KMinLogLevel, _L8("FATAL: CSenXMLDAO::SizeOfSessionsXmlInBytesL leaved:   %d"), leaveCode));
+            TLSLOG_FORMAT((KSenCoreServiceManagerLogChannelBase  , KMaxLogLevel, _L8("     : endpoint: '%S', contract: '%S', frameworkID: '%S'"), &e, &c, &fid));
+            
+            }
+        User::LeaveIfError(leaveCode);
+        
+#else // release builds
+        iSessions[i]->WriteAsXMLToL(bufWs);
+#endif // _SENDEBUG        
+        TPtr8 p8 = pBuf->Ptr(0);
+        size += p8.Length();
+        CleanupStack::PopAndDestroy(2); // bufWs (close), pBuf
+        pBuf = NULL;
+        }
+    TLSLOG_FORMAT((KSenCoreServiceManagerLogChannelBase  , KNormalLogLevel, _L8("CSenXMLDAO::SizeOfSessionsXmlInBytesL:   %d"), size));
+
+    return size;
+    }
+
+TInt CSenXMLDAO::SizeOfFrameworksXmlInBytesL()
+    {
+    TInt size(0);
+
+    HBufC8* pTemp = NULL;
+
+    TInt frameworks = iFrameworks.Count();
+
+    for (TInt j = 0; j < frameworks; j++)
+        {
+        pTemp = iFrameworks[j]->AsXmlL();
+        if(pTemp)
+            {
+            CleanupStack::PushL(pTemp);
+            size += pTemp->Length();
+            
+            CleanupStack::PopAndDestroy(); // pTemp
+            pTemp = NULL;
+            }
+        }
+    TLSLOG_FORMAT((KSenCoreServiceManagerLogChannelBase  , KNormalLogLevel, _L8("CSenXMLDAO::SizeOfFrameworksXmlInBytesL: %d"), size));
+    return size;
+    }
+
+
+void CSenXMLDAO::WriteL()
+    {
+    if (iReadingConfig != ESenIdle)
+        {
+        iReadingConfig = ESenSaveNeeded;
+        return;
+        }
+    TLSLOG(KSenCoreServiceManagerLogChannelBase  , KMinLogLevel,(_L("CSenXMLDAO::WriteL()")));
+
+
+    CBufFlat *pBuf = CBufFlat::NewL(KFlatBufSize);
+    CleanupStack::PushL(pBuf);
+    RBufWriteStream bufWs(*pBuf);
+    CleanupClosePushL(bufWs);
+
+
+    if ( !iProxyHost )
+        {
+        bufWs.WriteL(KStartTag);
+        }
+    else
+        {
+        bufWs.WriteL( KStartTagEndless );
+
+        bufWs.WriteL( KEmptySpace );
+        bufWs.WriteL( KProxyHost );
+        bufWs.WriteL( KEqual );
+        bufWs.WriteL( KQuote );
+
+        bufWs.WriteL(*iProxyHost);
+        bufWs.WriteL( KQuote );
+
+        bufWs.WriteL( KEmptySpace );
+        bufWs.WriteL( KProxyPort );
+        bufWs.WriteL( KEqual );
+        bufWs.WriteL( KQuote );
+
+        HBufC8* pPort = HBufC8::NewLC(5);
+        TPtr8 pPtrPort = pPort->Des();
+        pPtrPort.AppendNum( iProxyPort );
+        bufWs.WriteL( *pPort );
+
+        CleanupStack::PopAndDestroy( pPort );
+
+        bufWs.WriteL( KQuote );
+        bufWs.WriteL( KCloseTag );
+
+        }
+
+    // Now ensure that we have enough disk space for
+    // new configuration file!
+
+    TInt configFileSize(0);
+
+    TPtr8 p8 = pBuf->Ptr(0);
+
+    // calculate and add required space for sessions as XML (in bytes)
+    configFileSize += SizeOfSessionsXmlInBytesL(); 
+
+    // calculate and add required space for frameworks as XML (in bytes)
+    configFileSize += SizeOfFrameworksXmlInBytesL(); 
+
+    // add size of root element start tag (in bytes)
+    configFileSize += p8.Length();
+    // add size of root element close tag (in bytes)
+    configFileSize += KEndTag().Length();
+    TLSLOG_FORMAT((KSenCoreServiceManagerLogChannelBase  , KNormalLogLevel, _L8("CSenXMLDAO::WriteL() - Base config size: %d bytes"), p8.Length()));
+
+    TLSLOG_FORMAT((KSenCoreServiceManagerLogChannelBase  , KNormalLogLevel, _L8("CSenXMLDAO::WriteL() - Config file size: %d bytes"),  configFileSize));
+
+
+    // Now use SysUtils to ensure that we have room for temp file(!)
+    RFs fss;
+    User::LeaveIfError(fss.Connect());
+    CleanupClosePushL(fss);
+
+    // Create and open write stream to temp file
+    TFileName tempFile(KSenXMLDAOTempFile);
+
+    // this will create the file or replace and zero-length any existing file
+    // and might free some space, if write failed last time..
+    RFileWriteStream tempFileWriteStream;
+    CleanupClosePushL(tempFileWriteStream);
+    tempFileWriteStream.Replace(fss, tempFile, EFileWrite);
+
+    
+    TInt retVal(SysUtil::FFSSpaceBelowCriticalLevelL(&fss, configFileSize));
+    if(retVal == KErrNone)
+        {
+        TLSLOG_L(KSenCoreServiceManagerLogChannelBase  , KMinLogLevel, "File system check: OK, there is enough space available.");
+        }
+    else
+        {
+        TLSLOG_L(KSenCoreServiceManagerLogChannelBase  , KMinLogLevel,"File system check: FAILED, NOT enough space available.");
+        // release the root configuration XML buffer:
+        // tempFileWriteStream.Close(), fss.Close(), bufWs.Close(), delete pBuf
+        CleanupStack::PopAndDestroy(4); 
+        User::Leave(retVal);
+        }
+
+
+    HBufC8* pTemp = NULL;
+
+    // Write root level configuration XML into temp file
+    tempFileWriteStream.WriteL(p8);
+
+    // Write frameworks directly into temp file
+    TInt frameworks = iFrameworks.Count();
+    TLSLOG_FORMAT((KSenCoreServiceManagerLogChannelBase  , KNormalLogLevel, _L8(" - Framework count: (%d)"),  frameworks));
+
+    for (TInt j = 0; j < frameworks; j++)
+        {
+        pTemp = iFrameworks[j]->AsXmlL();
+        if(pTemp)
+            {
+            CleanupStack::PushL(pTemp);
+            TLSLOG(KSenCoreServiceManagerLogChannelBase  , KMaxLogLevel,(*pTemp));
+            tempFileWriteStream.WriteL(*pTemp);
+            CleanupStack::PopAndDestroy(); // pTemp
+            pTemp = NULL;
+            }
+        }
+
+    // Write sessions directly into temp file
+    TInt count = iSessions.Count();
+    TLSLOG_FORMAT((KSenCoreServiceManagerLogChannelBase  , KNormalLogLevel, _L8(" - Description/Session count: (%d)"), count));
+    for(TInt i = 0; i < count; i++)
+        {
+        iSessions[i]->WriteAsXMLToL(tempFileWriteStream);
+        }
+
+    // Write root level configuration element's end tag into temp file
+    tempFileWriteStream.WriteL(KEndTag);
+
+    // close the temp file write stream:
+    CleanupStack::PopAndDestroy(); // tempFileWriteStream.Close()
+
+    // create file manager to replace original database file
+    CFileMan* pFileMan = CFileMan::NewL(fss);
+    CleanupStack::PushL(pFileMan);
+
+    // Now copy temp file over the real database. EOverWrite is default
+    User::LeaveIfError(pFileMan->Move(KSenXMLDAOTempFile, KSenXMLDAOFile));
+
+    // destroy file manager instance and close the fss
+    CleanupStack::PopAndDestroy(2); // delete pFileMan, fss.Close()
+
+    // release the root configuration XML buffer
+    CleanupStack::PopAndDestroy(2); // bufWs.Close(), delete pBuf
+    }
+
+
+    /*
+    Snippet from deprecated WriteL() version:
+
+    TPtr8 p8 = pBuf->Ptr(0);
+
+    HBufC8* pFileContentAsUtf8 = p8.AllocL();
+
+    CleanupStack::PushL(pFileContentAsUtf8);
+
+    // Everything in MEMORY ok, prepare to write into file
+
+
+    RFileWriteStream fileOutStream;
+    CleanupClosePushL(fileOutStream);
+
+
+    if(!SysUtil::FFSSpaceBelowCriticalLevelL(&fss,
+                            pFileContentAsUtf8->Length()) )
+        {
+        // note, this will zero-length the file(!) 
+        fileOutStream.Replace(fss, iFileName, EFileWrite);
+
+        // finally write the UTF-8 into the file.
+        fileOutStream.WriteL(*pFileContentAsUtf8);
+        }
+    // else { User::Leave("KFSSpaceBelowCriticalLevel"); }
+
+    */
+void CSenXMLDAO::ReadL()
+    {
+    TLSLOG(KSenCoreServiceManagerLogChannelBase  , KMinLogLevel,(_L("CSenXMLDAO::ReadL()")));
+
+    NotifyFrameworksL(KNullDesC8, KSenEventSessionsDbReadBegin, NULL);
+
+
+    RFs fss;
+        User::LeaveIfError(fss.Connect());
+        CleanupClosePushL(fss);
+
+    iReadingConfig = ESenReading;
+
+    XMLReader()->SetContentHandler(*this);
+    TInt leaveCode(KErrNone);
+    TRAP(leaveCode, XMLReader()->ParseL(fss, iFileName));
+    iReadingConfig = ESenIdle;
+
+    CleanupStack::PopAndDestroy(1); // fss
+    NotifyFrameworksL(KNullDesC8, KSenEventSessionsDbReadComplete, NULL);
+    leaveCode = 0; // not used currently
+    }
+
+TInt CSenXMLDAO::Add(CSenWSDescription& aSD)
+    {
+    // Try to take ownership:
+    TInt retVal(iSessions.Append(&aSD));
+    if(retVal==KErrNone)
+        {
+        // Must be set so that it can be saved as XML fragment which 
+        // has an owner. This prevents empty namespace to be written.
+        aSD.SetOwner(*(MSenFragment*)this);
+    TInt retValSave = Save();
+    TInt notifyLeaveCode(KErrNone);
+    TRAP(notifyLeaveCode, NotifyFrameworksL(KNullDesC8,
+    		KSenEventRegisterNewServiceDescription, NULL));
+        TLSLOG_FORMAT((KSenCoreServiceManagerLogChannelBase  , KNormalLogLevel, _L8("CSenXMLDAO::Add(SD), Save() returned: %d"), retValSave));
+        retValSave = 0; // not in use in release builds
+        }
+    return retVal;
+    }
+
+// return an error code (Append might leave!)
+TInt CSenXMLDAO::Add(CSIF& aFramework)
+    {
+    TLSLOG_L(KSenCoreServiceManagerLogChannelBase  , KMinLogLevel,"CSenXMLDAO::Add(SIF)");
+    TBool alreadyExists(EFalse);
+    TInt sifCount = iFrameworks.Count();
+    for (TInt i=0; i<sifCount; i++)
+        {
+        if (iFrameworks[i]->Id() == aFramework.Id())
+            {
+            alreadyExists = ETrue;
+            break;
+            }
+        }
+    TInt retCode(KErrNone);
+    if (!alreadyExists)
+        {
+        retCode = iFrameworks.Append(&aFramework);
+        if(retCode==KErrNone)
+            {
+            TInt saveRetVal = Save();
+            TLSLOG_FORMAT((KSenCoreServiceManagerLogChannelBase  , KNormalLogLevel, _L8("CSenXMLDAO::Add(SIF), Save() returned: %d"), saveRetVal));
+            saveRetVal = 0; // not used in release builds
+            }
+        }
+    TLSLOG_L(KSenCoreServiceManagerLogChannelBase  , KMinLogLevel,"CSenXMLDAO::Add(CSIF&) - complete.");
+    return retCode;
+    }
+
+TBool CSenXMLDAO::Remove(CSenWSDescription& aSD)
+    {
+    TLSLOG(KSenCoreServiceManagerLogChannelBase  , KMinLogLevel,(_L("CSenXMLDAO::Remove(SD)")));
+    TInt index(KErrNotFound);
+    TInt count(iSessions.Count());
+
+    // Due architectural change
+    // REMOVE COMMENTED 3.0 CODE BELOW in 5.0:
+    //TPtrC8 contract = aSD.Contract();
+    //TPtrC8 endpoint = aSD.Endpoint();
+
+    //if(contract.Length()>0)
+    //    {
+
+    TInt leaveCode(KErrNone);
+    for(TInt i=0; i<count; i++)
+        {
+        // Due architectural change
+        // REMOVE COMMENTED 3.0 CODE BELOW in 5.0:
+        //TPtrC8 sessContract = iSessions[i]->Contract();
+        //TPtrC8 sessEndpoint = iSessions[i]->Endpoint();
+
+        //if ( sessContract == contract && sessEndpoint == endpoint )
+        CSenWSDescription* pSD = iSessions[i];
+        TBool equals(EFalse);
+        TRAP(leaveCode, equals = pSD->HasEqualPrimaryKeysL(aSD));
+#ifdef _SENDEBUG
+        if(leaveCode!=KErrNone)
+            {
+            TLSLOG_FORMAT((KSenCoreServiceManagerLogChannelBase  , KMinLogLevel, _L8("CSenXMLDAO::Remove - HasEqualPrimaryKeysL leaved: %d"), leaveCode));
+            }
+#endif
+        if(leaveCode==KErrNone && equals)
+            {
+                index = i;
+                break;
+            }
+        leaveCode = KErrNone;
+        }
+    //    }
+
+    if(index != KErrNotFound)
+        {
+
+#ifdef _SENDEBUG
+        TRAP_IGNORE
+            (
+        TLSLOG_L(KSenCoreServiceManagerLogChannelBase  , KMaxLogLevel,"Removing service description from DAO: ");
+            CBufFlat *pBuf = CBufFlat::NewL(KFlatBufSize);
+            CleanupStack::PushL(pBuf);
+            RBufWriteStream bufWs(*pBuf);
+            CleanupClosePushL(bufWs);
+            iSessions[index]->WriteAsXMLToL(bufWs);
+        TLSLOG_ALL(KSenCoreServiceManagerLogChannelBase  , KMaxLogLevel,(pBuf->Ptr(0)));
+            CleanupStack::PopAndDestroy(2); // bufWs, pBuf
+            )
+#endif // _SENDEBUG
+
+        delete iSessions[index];
+        iSessions.Remove(index);
+        TInt saveRetVal = Save();
+        TLSLOG_FORMAT((KSenCoreServiceManagerLogChannelBase  , KNormalLogLevel, _L8("CSenXMLDAO::Remove(SD), Save() returned: %d"), saveRetVal));
+        saveRetVal = 0; // not used in release builds
+        return ETrue;
+        }
+#ifdef _SENDEBUG
+    else
+        {
+        TLSLOG_L(KSenCoreServiceManagerLogChannelBase  , KMinLogLevel,"CSenXMLDAO::Remove(SD): description not found.");
+        }
+#endif
+    return EFalse;
+    }
+
+
+void CSenXMLDAO::Remove(CSIF& aFramework)
+    {
+    TLSLOG(KSenCoreServiceManagerLogChannelBase  , KMinLogLevel,(_L("CSenXMLDAO::Remove(SIF)")));
+    TInt index(-1);
+    TInt count(iFrameworks.Count());
+    for(TInt i=0; i<count; i++)
+        {
+        if((iFrameworks[i])->Id() == aFramework.Id())
+            {
+            index = i;
+            break;
+            }
+        }
+
+    if(index != KErrNotFound)
+        {
+        delete iFrameworks[index];
+        iFrameworks.Remove(index);
+        TInt retValSave = Save();
+        TLSLOG_FORMAT((KSenCoreServiceManagerLogChannelBase  , KNormalLogLevel, _L8("CSenXMLDAO::Remove(SIF), Save() returned: %d"), retValSave));
+        retValSave = 0; // not in use in release builds
+        }
+#ifdef _SENDEBUG
+    else
+        {
+        TLSLOG_L(KSenCoreServiceManagerLogChannelBase  , KMinLogLevel,"CSenXMLDAO::Remove(SIF): plugin not found.");
+        }
+#endif
+    }
+
+
+
+void CSenXMLDAO::StartElementL(const TDesC8& /* aNsURI */,
+                              const TDesC8& aLocalName,
+                              const TDesC8& /* aQName */,
+                              const RAttributeArray& aAttributes)
+    {
+    TLSLOG(KSenCoreServiceManagerLogChannelBase  , KMinLogLevel,(_L("Entering CSenXMLDAO::StartElementL")));
+    TLSLOG(KSenCoreServiceManagerLogChannelBase  , KMaxLogLevel,(aLocalName));
+    //LOG_WRITEFORMAT((_L8("Namespace: %S"), &aNsURI));
+
+    if(aLocalName == KServiceDescription)
+        {
+        TLSLOG(KSenCoreServiceManagerLogChannelBase  , KMinLogLevel,(_L("Found a ServiceDescription")));
+
+        // Default framework is checked after all the frameworks have been
+        // parsed in the MIDDLE of PARSING, to PREVENT orphanizing the SD(s),
+        // if no ID-WSF plugin was found; for example because ECOM cue
+        // (default_data) was wrong. MOVED the installation of default
+        // frameworks to be in here instead of LoadL()
+
+        // NOTE: expect, that when first SD is encountered, all of
+        // the frameworks have been parsed and installed properly
+        // if such (plugins) exist.
+
+        // No need to store the SIF* anywhere, just doing this to ensure the
+        // installation of the ID-WSF framework
+        if(!iDefaultFrameworkCheckedToExist)
+            {
+            // do only once per read configuration
+
+            TInt retCode = CheckDefaultFrameworks();
+            iDefaultFrameworkCheckedToExist=ETrue;
+            retCode = 0; // not used currently
+            }
+
+        // Alike frameworks, default transport (scheme-to-cue) mapping
+        // is ensured when first service description is recognized.
+        // The list for scheme-cue mappings is expected to be found
+        // before service descriptions (in the beginning of sensessions.xml)
+        if(!iDefaultTransportMapChecked)
+            {
+            TInt retCode = CheckDefaultTransports();
+            iDefaultTransportMapChecked=ETrue;
+            retCode=0; // not used currently
+            }
+
+
+        // check, if for some reason the iServiceDescription
+        // was NOT added to iSessions. If so, delete the
+        // orphan SD
+        if(iServiceDescription)
+            {
+            TInt index = iSessions.Find(iServiceDescription);
+            if(index==KErrNotFound)
+                {
+                // would otherwise NOT be taken care by:
+                //             iSessions.ResetAndDestroy()
+                delete iServiceDescription;
+                }
+            iServiceDescription=NULL;
+            }
+        
+        
+        iServiceDescription = CSenWSDescription::NewL(
+                            AsElement().NamespaceURI() );
+        iServiceDescription->SetAttributesL(aAttributes);
+        iServiceDescription->SetReader(*Reader());
+
+#ifdef _SENDEBUG
+        TPtrC8 frameworkID = iServiceDescription->FrameworkId();
+        TLSLOG_L(KSenCoreServiceManagerLogChannelBase  , KMinLogLevel,"CSenXMLDAO::StartElementL");
+        TLSLOG_FORMAT((KSenCoreServiceManagerLogChannelBase  , KMinLogLevel, _L8(" - %S service description now parsed by delegate."), &frameworkID));
+#endif
+
+        iState = KStateParsingServiceDescription;
+
+        DelegateParsingL(*iServiceDescription);
+        }
+    else if(aLocalName == KFramework)
+        {
+        iFrameworkConfigParser = NULL;
+        // we can take the framework id from attribute list,
+        // no need to wait for end element...
+        TPtrC8 fwId = SenXmlUtils::AttrValue(aAttributes, KClass);
+        iFrameworkConfigParser = iManager.InstallFrameworkL(fwId);
+        if(iFrameworkConfigParser)
+            {
+            iFrameworkConfigParser->SetOwner((MSenFragment&)*this);
+            iFrameworkConfigParser->SetAttributesL(aAttributes);
+            iFrameworkConfigParser->SetReader(*Reader());
+
+            iState = KStateParsingFramework;
+
+            DelegateParsingL(*iFrameworkConfigParser);
+            }
+        // Expect, that frameworks are first in the XML. Set boolean
+        // "check-done" flag to EFalse, so that check will be issued
+        // when first SD is encountered.
+        iDefaultFrameworkCheckedToExist=EFalse;
+        }
+    else if (aLocalName == KLocalName)  // SenConfiguration starting tag
+        {
+        // check if HTTP proxy HOST -param was set:
+        TPtrC8 host = SenXmlUtils::AttrValue(aAttributes, KProxyHost);
+        if ( host.Length() > 0 &&  host != KSpace)
+            {
+            delete iProxyHost;
+            iProxyHost = NULL; 
+            iProxyHost = host.AllocL();
+            TLSLOG_FORMAT((KSenCoreServiceManagerLogChannelBase  , KMaxLogLevel, _L8("HTTP proxy HOST read: '%S'"), iProxyHost));
+            }
+
+        // check if HTTP proxy PORT -param was set:
+        TPtrC8 port = SenXmlUtils::AttrValue(aAttributes, KProxyPort);
+        if (port.Length() > 0 && port != KSpace)
+            {
+            TLex8 lex;
+            lex.Assign(port);
+            lex.Val( iProxyPort );
+            TLSLOG_FORMAT((KSenCoreServiceManagerLogChannelBase  , KMaxLogLevel, _L8("HTTP proxy PORT read: '%d'"), iProxyPort));
+            }
+        }
+        /*
+    else if ( aLocalName == KTransport && aNsURI == KNamespaceName )  // Transport starting tag
+        {
+        if ( ipTransportDelegate )
+            {
+            ipTransportDelegate->ExtractElement();
+            delete ipTransportDelegate;
+            ipTransportDelegate = NULL;
+            }
+        ipTransportDelegate = CSenDomFragment::NewL(KTransport);
+        CSenElement& element = ipTransportDelegate->AsElement();
+        this->AsElement().AddElementL(element);        
+        iState = KStateParsingTransport;
+        DelegateParsingL(*ipTransportDelegate); 
+        }
+        */
+    TLSLOG(KSenCoreServiceManagerLogChannelBase  , KMinLogLevel,(_L("Leaving CSenXMLDAO::StartElementL")));
+
+    }
+
+void CSenXMLDAO::EndElementL(const TDesC8& aUri,
+                             const TDesC8& aLocalName,
+                             const TDesC8& aName)
+    {
+    TLSLOG(KSenCoreServiceManagerLogChannelBase  , KMinLogLevel,(_L("CSenXMLDAO::EndElementL()")));
+    TLSLOG_FORMAT((KSenCoreServiceManagerLogChannelBase  , KMaxLogLevel, _L8("Namespace URI: %S"), &aUri));
+    TLSLOG_FORMAT((KSenCoreServiceManagerLogChannelBase  , KMaxLogLevel, _L8("Local name URI: %S"), &aLocalName));
+
+
+    switch(iState)
+        {
+        case KStateParsingServiceDescription:
+            {
+            TLSLOG(KSenCoreServiceManagerLogChannelBase  , KMinLogLevel,(_L("CSenXMLDAO::EndElementL() - EParsingServiceDescription")));
+            if(aLocalName == KServiceDescription)
+                {
+#ifdef _SENDEBUG
+                HBufC8* pAsXmlUtf8 = iServiceDescription->AsXmlL();
+                if(pAsXmlUtf8)
+                    {
+                    CleanupStack::PushL(pAsXmlUtf8);
+                    TLSLOG_FORMAT((KSenCoreServiceManagerLogChannelBase  , KMaxLogLevel, _L8("SD as XML:")));
+                    TLSLOG_ALL(KSenCoreServiceManagerLogChannelBase  , KMaxLogLevel,(*pAsXmlUtf8));
+                    CleanupStack::PopAndDestroy(1); // pAsXmlUtf8
+                    }
+#endif
+
+                // transfer ownership
+                iManager.RegisterServiceDescriptionL(iServiceDescription);
+                iServiceDescription = NULL; // now owned elsewhere
+                }
+            break;
+            }
+        case KStateParsingFramework:
+            {
+            if (aLocalName == KFramework)
+                {
+                iState = KStateIgnore;
+                }
+            break;
+            }
+        case KStateParsingTransport:
+            {
+            if ( aLocalName == KTransport && aUri == KNamespaceName ) 
+                {
+                 // Transport ending tag
+                iState = KStateIgnore;
+                }
+            break;
+            }
+        default:
+            {
+            CSenBaseFragment::EndElementL(aUri,aLocalName,aName);
+            break;
+            }
+        }
+    }
+
+
+TBool CSenXMLDAO::Owns(CSenWSDescription* aSD)
+    {
+    TInt count(iSessions.Count());
+    for(TInt i=0; i<count; i++)
+        {
+        if(iSessions[i]==aSD)
+            {
+            return ETrue;
+            }
+        }
+    return EFalse;
+    }
+
+TInt CSenXMLDAO::ProxyPort()
+    {
+    return iProxyPort;
+    }
+
+const TDesC8& CSenXMLDAO::ProxyHost()
+    {
+    if ( iProxyHost )
+        {
+        return *iProxyHost;
+        }
+    else
+        {
+        return KNullDesC8;
+        }
+    }
+CSenWSDescription* CSenXMLDAO::FindExactServiceDescriptionL(
+                                                CSenWSDescription& aSd)
+    {
+    TInt sessCount = iSessions.Count();
+    for (TInt i=0; i<sessCount; i++)
+        {
+        CSenWSDescription* pCandidate = iSessions[i];
+
+        // The concrete session implementation of framework "X" decides
+        // what are the primary keys (unique) in a service description
+        if(pCandidate && pCandidate->HasEqualPrimaryKeysL(aSd))
+            {
+            TLSLOG_L(KSenCoreServiceManagerLogChannelBase  , KMinLogLevel,"CSenXMLDAO::FindExactServiceDescriptionL:");
+            TLSLOG_L(KSenCoreServiceManagerLogChannelBase  , KMinLogLevel," - exact match found.");
+            return pCandidate;
+            }
+
+        // It is better to let framework sessions classes to define the
+        // "primary keys" of this comparison(!). That is more extensible.
+        // SO: REMOVE BELOW COMMENTED CODE in 5.0:
+        //if(pCandidate)
+        //    {
+        //    if (pCandidate->Endpoint() == aSd.Endpoint() &&
+        //            pCandidate->Contract() == aSd.Contract() )
+        //        {
+        //
+        //
+        //        LOG_WRITE_L("CSenXMLDAO::FindExactServiceDescriptionL:");
+        //        LOG_WRITE_L(" - exact match found.");
+        //        return pCandidate;
+        //        }
+        //    }
+
+        }
+    TLSLOG_L(KSenCoreServiceManagerLogChannelBase  , KMinLogLevel,"CSenXMLDAO::FindMatchingServiceDescription: no match found.");
+    return NULL;
+    }
+
+CSenWSDescription* CSenXMLDAO::FindMatchingServiceDescriptionL(
+                                                CSenWSDescription& aSd)
+    {
+    TInt sessCount = iSessions.Count();
+    for (TInt i=0; i<sessCount; i++)
+        {
+        CSenWSDescription* pCandidate = iSessions[i];
+        if(pCandidate)
+            {
+            if(pCandidate->Matches(aSd))
+                {
+                TLSLOG_L(KSenCoreServiceManagerLogChannelBase  , KMinLogLevel,"CSenXMLDAO::FindMatchingServiceDescription:");
+                TLSLOG_L(KSenCoreServiceManagerLogChannelBase  , KMinLogLevel," - matching SD found.");
+                return pCandidate;
+                }
+            }
+        }
+    TLSLOG_L(KSenCoreServiceManagerLogChannelBase  , KMinLogLevel,"CSenXMLDAO::FindMatchingServiceDescription: no match found.");
+    return NULL;
+    }
+    
+CSenWSDescription* CSenXMLDAO::FindMatchingSDAndBestScoreL(
+                                            CSenWSDescription& aSd,
+                                            TInt &aBestScore)	//CodeScannerWarnings
+    {
+    CSenWSDescription* pMatchingSD = NULL;
+    TLSLOG_L(KSenCoreServiceManagerLogChannelBase  , KMaxLogLevel,"***************************************************************");
+    TLSLOG_L(KSenCoreServiceManagerLogChannelBase  , KMaxLogLevel,"CSenXMLDAO::FindMatchingSDAndBestScore");
+    TPtrC8 sdendpoint = aSd.Endpoint();
+    TPtrC8 sdcontract = aSd.Contract();
+    TLSLOG_FORMAT((KSenCoreServiceManagerLogChannelBase  , KMaxLogLevel, _L8("Endpoint URI: %S"), &sdendpoint ));
+    TLSLOG_FORMAT((KSenCoreServiceManagerLogChannelBase  , KMaxLogLevel, _L8("Contract: %S"), &sdcontract ));
+    
+    TInt score( 0 );
+    // Make sure that at least endpoint or contract should match
+    aBestScore = 1;
+    TInt sessCount = iSessions.Count();
+    for (TInt i=0; i<sessCount; i++)
+        {
+        CSenWSDescription* pCandidate = iSessions[i];
+        TLSLOG_L(KSenCoreServiceManagerLogChannelBase  , KMaxLogLevel,"----------------------------------------------");
+        TPtrC8 endpoint = pCandidate->Endpoint();
+        TPtrC8 contract = pCandidate->Contract();
+        TLSLOG_FORMAT((KSenCoreServiceManagerLogChannelBase  , KMaxLogLevel, _L8("Endpoint URI: %S"), &endpoint ));
+        TLSLOG_FORMAT((KSenCoreServiceManagerLogChannelBase  , KMaxLogLevel, _L8("Contract: %S"), &contract ));
+        if(pCandidate)
+            {
+			score = pCandidate->ScoreMatchL(aSd);
+			if (score > aBestScore) 
+			    {
+			    if ( pCandidate->Matches(aSd) )
+			        {
+			        TLSLOG_L(KSenCoreServiceManagerLogChannelBase  , KMaxLogLevel,"-> Selected");
+    				TLSLOG_FORMAT((KSenCoreServiceManagerLogChannelBase  , KMaxLogLevel, _L8("[score: %d]"), score ));
+			        pMatchingSD = pCandidate;
+			        }
+    			aBestScore = score;
+			    }
+
+            if ( !pMatchingSD && pCandidate->Matches(aSd) )
+                {
+                TLSLOG_L(KSenCoreServiceManagerLogChannelBase  , KMaxLogLevel,"-> Selected");
+                pMatchingSD = pCandidate;
+                }
+            }
+        }
+        
+#ifdef _SENDEBUG
+    if ( !pMatchingSD )
+        {
+        TLSLOG_L(KSenCoreServiceManagerLogChannelBase  , KMaxLogLevel,"CSenXMLDAO::FindMatchingSDAndBestScore: no match found.");
+        }
+#endif
+    TLSLOG_FORMAT((KSenCoreServiceManagerLogChannelBase  , KMaxLogLevel, _L8("Best score: %d"), aBestScore ));
+    TLSLOG_L(KSenCoreServiceManagerLogChannelBase  , KMaxLogLevel,"***************************************************************");
+    
+    return pMatchingSD;
+    }
+
+CSenWSDescription* CSenXMLDAO::FindScoreMatchingServiceDescriptionL(
+                                            CSenWSDescription& aSd,
+                                            TInt aBestScore)
+    {
+	/* We should now try the primary search again.
+	 * Note that we try to pick a service that matches 
+	 * at least as good as the given aBestScore
+	 * but at least the contract or endpoint should
+	 * match.
+	 */ 
+	TLSLOG_L(KSenCoreServiceManagerLogChannelBase  , KMaxLogLevel,">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");
+    TLSLOG_L(KSenCoreServiceManagerLogChannelBase  , KMaxLogLevel,"CSenXMLDAO::FindScoreMatchingServiceDescription");
+    TLSLOG_FORMAT((KSenCoreServiceManagerLogChannelBase  , KMaxLogLevel, _L8("Best score: %d"), aBestScore ));
+    TPtrC8 sdendpoint = aSd.Endpoint();
+    TPtrC8 sdcontract = aSd.Contract();
+    TLSLOG_FORMAT((KSenCoreServiceManagerLogChannelBase  , KMaxLogLevel, _L8("Endpoint URI: %S"), &sdendpoint ));
+    TLSLOG_FORMAT((KSenCoreServiceManagerLogChannelBase  , KMaxLogLevel, _L8("Contract: %S"), &sdcontract ));
+	 
+	TInt score( 0 );
+	// Make sure that at least endpoint or contract should match
+	if (aBestScore < 1) aBestScore = 1; 
+	
+    TInt sessCount = iSessions.Count();
+    for (TInt i=sessCount-1 ; i>=0 ; i--)
+        {
+        CSenWSDescription* pCandidate = iSessions[i];
+        if(pCandidate)
+            {
+            TLSLOG_L(KSenCoreServiceManagerLogChannelBase  , KMaxLogLevel,"----------------------------------------------");
+            TPtrC8 endpoint = pCandidate->Endpoint();
+            TPtrC8 contract = pCandidate->Contract();
+            TLSLOG_FORMAT((KSenCoreServiceManagerLogChannelBase  , KMaxLogLevel, _L8("Endpoint URI: %S"), &endpoint ));
+            TLSLOG_FORMAT((KSenCoreServiceManagerLogChannelBase  , KMaxLogLevel, _L8("Contract: %S"), &contract ));
+			score = pCandidate->ScoreMatchL(aSd);
+			TLSLOG_FORMAT((KSenCoreServiceManagerLogChannelBase  , KMaxLogLevel, _L8("score: %d"), score ));
+			if (score >= aBestScore)
+                {
+                TLSLOG_L(KSenCoreServiceManagerLogChannelBase  , KMaxLogLevel,"CSenXMLDAO::FindScoreMatchingServiceDescription:");
+                TLSLOG_FORMAT((KSenCoreServiceManagerLogChannelBase  , KMaxLogLevel, _L8(" - Scorematching SD found. Score : %d"),
+                                score));
+                TLSLOG_L(KSenCoreServiceManagerLogChannelBase  , KMaxLogLevel,">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");
+                return pCandidate;
+                }
+            }
+        }
+    TLSLOG_L(KSenCoreServiceManagerLogChannelBase  , KMaxLogLevel,"CSenXMLDAO::FindScoreMatchingServiceDescription: no scorematch found.");
+    TLSLOG_L(KSenCoreServiceManagerLogChannelBase  , KMaxLogLevel,">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");
+    
+    return NULL;
+    }
+
+TInt CSenXMLDAO::FindAllMatchingServiceDescriptions(RWSDescriptionArray& aMatches,
+                                                    const TDesC8& aContract)
+    {
+    TInt retVal(KErrNone);
+    TInt sessCount(iSessions.Count());
+
+    TLSLOG_L(KSenCoreServiceManagerLogChannelBase  , KMinLogLevel,"CSenXMLDAO::FindAllMatchingServiceDescriptions(contract)");
+
+    for(TInt i=0; i<sessCount; i++)
+        {
+        TPtrC8 sessContract = iSessions[i]->Contract();
+
+        if ( sessContract.Length()>0 && aContract == sessContract
+            ||
+            aContract == KNullDesC8 // if no contract given, all match
+            )
+            {
+            TLSLOG_L(KSenCoreServiceManagerLogChannelBase  , KMaxLogLevel," - match found, appending to array.");
+            TInt appendRetVal(aMatches.Append(iSessions[i]));
+            if(appendRetVal!=KErrNone)
+                {
+                retVal = appendRetVal; // note: last error is retuned
+                TLSLOG_L(KSenCoreServiceManagerLogChannelBase  , KMinLogLevel," - FATAL: due OOM Append(SD) failed!");
+                TLSLOG_FORMAT((KSenCoreServiceManagerLogChannelBase  , KMinLogLevel, _L8(" - error code: %d"), appendRetVal));
+
+                // Attempt to append other hits/matching SDs
+                }
+            }
+        }
+    TLSLOG_FORMAT((KSenCoreServiceManagerLogChannelBase  , KNormalLogLevel, _L8(" - total of %d matches found."), 
+                        aMatches.Count()));
+
+    return retVal; // last error from Append() is returned atm
+    }
+
+TInt CSenXMLDAO::FindAllMatchingServiceDescriptions(RWSDescriptionArray& aMatches,
+                                                    MSenServiceDescription& aPattern)
+    {
+    TInt sessCount(iSessions.Count());
+    TInt retVal(KErrNone);
+    TLSLOG_L(KSenCoreServiceManagerLogChannelBase  , KMinLogLevel,"CSenXMLDAO::FindAllMatchingServiceDescriptions(pattern)");
+    for (TInt i=0; i<sessCount; i++)
+        {
+        if (iSessions[i]->Matches(aPattern))
+            {
+            TLSLOG_L(KSenCoreServiceManagerLogChannelBase  , KMinLogLevel," -> matching service description found");
+
+            TInt appendRetVal(aMatches.Append(iSessions[i]));
+            if(appendRetVal!=KErrNone)
+                {
+                retVal = appendRetVal; // note: last error is retuned
+                TLSLOG_L(KSenCoreServiceManagerLogChannelBase  , KMinLogLevel," - FATAL: due OOM Append(SD) failed!");
+                TLSLOG_FORMAT((KSenCoreServiceManagerLogChannelBase  , KMinLogLevel, _L8(" - error code: %d"), appendRetVal));
+
+                // Attempt to append other hits/matching SDs
+                }
+            }
+        }
+     TLSLOG_FORMAT((KSenCoreServiceManagerLogChannelBase  , KNormalLogLevel, _L8(" - total of %d matches found."), 
+                        aMatches.Count()));
+
+    return retVal; // last error from Append() is returned atm
+    }
+
+
+TInt CSenXMLDAO::AddServiceDescriptionToFrameworksL( CSenWSDescription& aPattern,
+                                                     MSenRemoteServiceConsumer& aRemoteConsumer,
+                                                     HBufC8*& aErrorMsg )
+    {
+    CSLOG_L(aRemoteConsumer.ConnectionId()  , KMinLogLevel,"CSenXMLDAO::AddServiceDescriptionToFrameworksL");
+
+    TInt fwCount = iFrameworks.Count();
+    CSLOG_FORMAT((aRemoteConsumer.ConnectionId() , KNormalLogLevel, _L8("Adding SD to (%d) SIF plug-ins."), fwCount));
+    TInt retVal;
+    TInt error(KErrNone);
+    TInt sdCount(0);
+    TPtrC8 patternFwId = aPattern.FrameworkId();
+    HBufC8* pLastErrorMsg = NULL;
+    for (TInt i=0; i<fwCount; i++ )
+        {
+        // altered the SIF inteface to return the count or leave
+        // (no ref to int as argument)
+        retVal = iFrameworks[i]->AddServiceDescriptionL( aPattern, aRemoteConsumer, pLastErrorMsg);
+        if ( retVal > 0 )
+            {
+            sdCount += retVal;
+            }
+        
+        TPtrC8 frameworkID = iFrameworks[i]->Id();
+        
+        // Store the latest error, in case that no match has yet been found(!)
+        if ( (sdCount == 0) && 
+             (retVal < 0 || (pLastErrorMsg && pLastErrorMsg->Length() > 0) )
+           )
+            {
+            if( patternFwId.Length() == 0 || frameworkID == patternFwId )
+                {
+                // if pattern provides NO framework ID, or if it provides
+                // mathing framework ID, then collect error message from
+                // last SIF plugin in the array:
+                if ( pLastErrorMsg )
+                    {
+                    delete aErrorMsg;
+                    aErrorMsg = pLastErrorMsg;
+                    pLastErrorMsg = NULL;
+                    }
+                if ( retVal < 0 )
+                    {
+                    error = retVal;
+                    }
+                }
+            }
+        CSLOG_L(aRemoteConsumer.ConnectionId()  , KNormalLogLevel,"CSenXMLDAO::AddServiceDescriptionToFrameworksL:");
+        CSLOG_FORMAT((aRemoteConsumer.ConnectionId()  , KNormalLogLevel, _L8("- After %S SIF, the add count is [%d]"), &frameworkID, sdCount));
+        }
+    
+    if ( pLastErrorMsg )
+        {
+        delete pLastErrorMsg;
+        }
+        
+    if ( sdCount > 0 )
+        {
+        retVal = sdCount;
+        delete aErrorMsg;
+        aErrorMsg = NULL;
+        }
+    else
+        {
+        retVal = error;
+        }
+        
+    return retVal;
+    }
+
+
+TInt CSenXMLDAO::NotifyFrameworksL(const TDesC8& aFrameworkID,
+                                   const TInt aEvent,
+                                    TAny* aArgument)
+    {
+    TLSLOG_L(KSenCoreServiceManagerLogChannelBase  , KMinLogLevel,"CSenXMLDAO::NotifyFrameworksL");
+    TInt fwCount = iFrameworks.Count();
+    TLSLOG_FORMAT((KSenCoreServiceManagerLogChannelBase  , KNormalLogLevel, _L8("There are %d loaded SIF plug-in(s)."), fwCount));
+    TInt retVal(KErrNone);
+    for (TInt i=0; i<fwCount; i++ )
+        {
+        TPtrC8 fwID = iFrameworks[i]->Id();
+        if(aFrameworkID.Length()==0 || aFrameworkID == fwID)
+            {
+            TLSLOG_FORMAT((KSenCoreServiceManagerLogChannelBase  , KNormalLogLevel, _L8("+ Notified '%S' SIF. Event (%d)"),
+                            &fwID,
+                            aEvent));
+            
+            TInt pluginRetVal = iFrameworks[i]->OnEvent(aEvent, aArgument);
+            if(retVal==KErrNone && pluginRetVal!=KErrNone)
+                {
+                retVal = pluginRetVal;
+                }
+            }   
+#ifdef _SENDEBUG
+        else
+            {
+            TLSLOG_FORMAT((KSenCoreServiceManagerLogChannelBase  , KNormalLogLevel, _L8("-Not notifying '%S' SIF [framework ID does not match]"),
+                &fwID));
+            }
+#endif // _SENDEBUG
+        }
+    return retVal;
+    }
+
+
+TInt CSenXMLDAO::SaveL(const CSenServiceSession& /* aServiceSession */ )
+    {
+    Save(); //This implementation does not save single objects (yet).
+    return KErrNone;
+    }
+
+TInt CSenXMLDAO::SaveL(const CSIF& /* aServiceInvocationFramework */)
+    {
+    Save(); //This implementation does not save single objects (yet).
+    return KErrNone;
+    }
+
+CDesC8Array& CSenXMLDAO::SupportedFrameworksL()
+    {
+    TInt fwCount(iFrameworks.Count());
+    CDesC8Array* retVal = new (ELeave) CDesC8ArraySeg(fwCount);
+    for (TInt i=0; i<fwCount; i++)
+        {
+        retVal->AppendL(*iFrameworks[i]->Id().AllocL());
+        }
+    TLSLOG_FORMAT((KSenCoreServiceManagerLogChannelBase  , KNormalLogLevel, _L8("CSenXMLDAO::SupportedFrameworksL(): Count: (%d)"),
+                        retVal->Count()));
+    return *retVal;
+    }
+
+TInt CSenXMLDAO::ContainsServiceDescriptionL(TBool& aContains,
+                                             CSenWSDescription& aPattern)
+    {
+    aContains = EFalse;
+    TInt sessCount = iSessions.Count();
+    for (TInt i=0; i<sessCount && !aContains; i++)
+        {
+        CBufFlat *pBuf = CBufFlat::NewL(KFlatBufSize);
+        CleanupStack::PushL(pBuf);
+        RBufWriteStream bufWs(*pBuf);
+        CleanupClosePushL(bufWs);
+        iSessions[i]->WriteAsXMLToL(bufWs);
+        CSenWSDescription* pSd = CSenWSDescription::NewLC();
+        pSd->SetReader(*Reader());
+        pSd->ParseL(pBuf->Ptr(0));
+
+        if (pSd->ConsistsOfL(aPattern))
+            {
+            TLSLOG(KSenCoreServiceManagerLogChannelBase  , KMinLogLevel,(_L("CSenXMLDAO::ContainsServiceDescriptionL(): matches given pattern:")));
+            aContains = ETrue;
+            }
+        CleanupStack::PopAndDestroy(3); // pSd, bufWs, pBuf
+        }
+    
+    return KErrNone;
+    }
+
+
+TInt CSenXMLDAO::CheckDefaultFrameworks()
+    {
+    // Do only once per read-text being parsed..
+    TInt retCode(KErrNone);
+    TInt leaveCode(KErrNone);
+
+    TRAP(leaveCode, DefaultFrameworkL(KDefaultIdWsfFrameworkID, 
+                                      KDefaultFrameworkCue1));
+#ifdef _SENDEBUG
+    if(leaveCode!=KErrNone)
+        {
+        TLSLOG_FORMAT((KSenCoreServiceManagerLogChannelBase  , KMinLogLevel, _L8("CSenXMLDAO::Load() - DefaultFrameworkL() leaved: %d"),
+            leaveCode));
+        }
+#else
+    if(leaveCode!=KErrNone)
+        {
+        retCode = leaveCode;
+        }
+#endif
+
+    leaveCode = KErrNone;
+    TRAP(leaveCode, DefaultFrameworkL(KDefaultBasicWebServicesFrameworkID, 
+                                      KDefaultFrameworkCue2));
+#ifdef _SENDEBUG
+    if(leaveCode!=KErrNone)
+        {
+        TLSLOG_FORMAT((KSenCoreServiceManagerLogChannelBase  , KMinLogLevel, _L8("CSenXMLDAO::Load() - DefaultFrameworkL() leaved: %d"),
+            leaveCode));
+        }
+#else
+    if(leaveCode!=KErrNone)
+        {
+        retCode = leaveCode; // overrides possible leave from ID-WSF ECOM loading..
+        }
+#endif
+
+    leaveCode = KErrNone;
+    TRAP(leaveCode, DefaultFrameworkL(KDefaultRestServicesFrameworkID, 
+                                      KDefaultFrameworkCue3));
+
+#ifdef _SENDEBUG
+    if(leaveCode!=KErrNone)
+        {
+        TLSLOG_FORMAT((KSenCoreServiceManagerLogChannelBase  , KMinLogLevel, _L8("CSenXMLDAO::Load() - DefaultFrameworkL() leaved: %d"),
+            leaveCode));
+        }
+#else
+    if(leaveCode!=KErrNone)
+        {
+        retCode = leaveCode; // overrides possible leave from ID-WSF & WS-I ECOMs loading..
+        }
+#endif
+
+    leaveCode = KErrNone;
+    TRAP(leaveCode, DefaultFrameworkL(KDefaultWSStarFrameworkID, 
+                                      KDefaultFrameworkCue4));
+
+#ifdef _SENDEBUG
+    if(leaveCode!=KErrNone)
+        {
+        TLSLOG_FORMAT((KSenCoreServiceManagerLogChannelBase  , KMinLogLevel, _L8("CSenXMLDAO::Load() - DefaultFrameworkL() leaved: %d"),
+            leaveCode));
+        }
+#else
+    if(leaveCode!=KErrNone)
+        {
+        retCode = leaveCode; // overrides possible leave from ID-WSF & WS-I & REST ECOMs loading..
+        }
+#endif
+
+    leaveCode = KErrNone;
+    TRAP(leaveCode, DefaultFrameworkL(KDefaultAtomPubFrameworkID, 
+                                      KDefaultFrameworkCue5));
+
+#ifdef _SENDEBUG
+    if(leaveCode!=KErrNone)
+        {
+		TLSLOG_FORMAT((KSenCoreServiceManagerLogChannelBase  , KMinLogLevel, _L8("CSenXMLDAO::Load() - DefaultFrameworkL() leaved: %d"),
+            leaveCode));
+        }
+#else
+    if(leaveCode!=KErrNone)
+        {
+        retCode = leaveCode; // overrides possible leave from ID-WSF & WS-I & REST ECOMs loading..
+        }
+#endif
+
+//################OVI PLUGIN
+    leaveCode = KErrNone;
+    TRAP(leaveCode, DefaultFrameworkL(KDefaultOviFrameworkID, 
+                                      KDefaultFrameworkCue6));
+
+#ifdef _SENDEBUG
+    if(leaveCode!=KErrNone)
+        {
+        LOG_WRITEFORMAT((_L8("CSenXMLDAO::Load() - DefaultFrameworkL() leaved: %d"),
+            leaveCode));
+        }
+#else
+    if(leaveCode!=KErrNone)
+        {
+        retCode = leaveCode; // overrides possible leave from ID-WSF & WS-I & REST ECOMs loading..
+        }
+#endif
+    return retCode;
+    }
+
+
+
+TPtrC8 CSenXMLDAO::TransportPluginCueBySchemeL(const TPtrC8& aScheme)
+    {
+    TPtrC8 cue = KNullDesC8();
+
+    TInt index = iTransportMap.Find(aScheme);
+    if(index!=KErrNotFound)
+        {
+        const HBufC8* pCue = iTransportMap.ValueAt(index);
+        if(pCue)
+            {
+            cue.Set(*pCue);
+            }
+        }
+    return cue;
+    }
+
+TInt CSenXMLDAO::CheckDefaultTransports()
+    {
+    // Note: HTTP Channel is the highest priority default, also in case
+    // that scheme is not provided, so it does not need to be
+    // added as default (CSenTransport::NewL() without cue returns the
+    // default version HTTP Channel Transport plug-in).
+
+    // Check whether local scheme default has been overridden by 
+    // configuration file (sensessions.xml). The configuration file
+    // has now been loaded, so one should not discard any changes to
+    // default scheme-cue mappings that were read from that file.
+
+    TInt retVal(KErrNone);
+    TInt index = iTransportMap.Find(KLocalTransportScheme);
+    if(index==KErrNotFound)
+        {
+        // apply & map the default local transport ECOM cue with its scheme
+        HBufC8* pScheme = KLocalTransportScheme().Alloc();
+        HBufC8* pCue = KDefaultLocalTransportPluginCue().Alloc();
+
+        if(pScheme && pCue)
+            {
+            TInt retCode = iTransportMap.Append(pScheme, pCue);
+            if(retCode!=KErrNone)
+                {
+                retVal = retCode;
+                }
+            TLSLOG_FORMAT((KSenCoreServiceManagerLogChannelBase  , KNormalLogLevel, _L8("CSenXMLDAO::CheckDefaultTransportsL - Append(local) returned: %d"), 
+                retVal));
+            }
+        }
+
+    index = iTransportMap.Find(KTcpTransportScheme);
+    if(index==KErrNotFound)
+        {
+        // apply & map the default local transport ECOM cue with its scheme
+        HBufC8* pScheme = KTcpTransportScheme().Alloc();
+        HBufC8* pCue = KDefaultVirtualTcpTransportPluginCue().Alloc();
+        if(pScheme && pCue)
+            {
+            TInt retCode = iTransportMap.Append(pScheme, pCue);
+            if(retCode!=KErrNone)
+                {
+                retVal = retCode;
+                }
+              TLSLOG_FORMAT((KSenCoreServiceManagerLogChannelBase  , KNormalLogLevel, _L8("CSenXMLDAO::CheckDefaultTransportsL - Append(tcp) returned: %d"), 
+                retVal));
+            }
+        }
+    return retVal; // returns the last error code
+    }
+
+MSenProvider& CSenXMLDAO::LookupHostletForL(const TDesC8& aHostletEndpoint,
+                                            const TDesC& aReqThreadId,
+                                            const TDesC8& aReqConsumerId)
+    {
+    // This method needs to be wrapped inside critical section 
+    // NOTE: do *NOT* file log before this line(!):
+
+    TLSLOG_L(KSenCoreServiceManagerLogChannelBase  , KMaxLogLevel,"CSenXMLDAO::LookupHostletForL:");
+    TLSLOG(KSenCoreServiceManagerLogChannelBase  , KMaxLogLevel,(aReqThreadId));
+    TLSLOG(KSenCoreServiceManagerLogChannelBase  , KMaxLogLevel,(aReqConsumerId));
+
+    
+    // LIST OF SHARABLE PROVIDERS IS USED TO LOOKUP A MATCHING,
+    // SHARABLE PROVIDER, which is accessed by multiple requests,
+    // possibly even by multiple threads at the same time (if
+    // provider's type is non-threadsafe, meaning that it 
+    // itself implements mutex for incoming ServiceL calls etc.
+    TInt sharableCount(iSharableProviders.Count());
+    CSenProvider* pHostlet = NULL;
+
+    for(TInt s=0; s<sharableCount; s++)
+        {
+        pHostlet = iSharableProviders[s];
+        if(pHostlet)
+            {
+            if(pHostlet->Endpoint()==aHostletEndpoint)
+                {
+                TLSLOG_FORMAT((KSenCoreServiceManagerLogChannelBase  , KMaxLogLevel, _L8("- Matching sharable hostlet found from cache: 0x%X"), &pHostlet));
+                return *pHostlet;
+                }
+            }
+        }
+
+    
+    // Lookup unsharable providers, which EITHER are non-threadsafe
+    // (shared between several simultaneous requests from same consumer)
+    // OR which wish to stay on background and support reinitialization.
+    CSenHostletLookupInfo* pLookupInfo = 
+        CSenHostletLookupInfo::NewLC(aReqThreadId, aReqConsumerId);
+
+    // It is not actually possible to get match with any threadsafe, 
+    // cached provider from this find:
+    TInt index = iUnsharableProviders.Find(*pLookupInfo);
+    CleanupStack::PopAndDestroy(); // pLookupInfo
+    pLookupInfo = NULL;
+
+    if(index!=KErrNotFound)
+        {
+        pHostlet = (CSenProvider*) iUnsharableProviders.ValueAt(index);
+        pLookupInfo = iUnsharableProviders.KeyAt(index);
+        if(pHostlet && pLookupInfo && !pHostlet->Threadsafe()) // sanity check
+            {
+            // Next line is critical; when count goes to zero,
+            // provider can be de-allocated from memory!
+            pLookupInfo->IncrementLookupCount();
+            TLSLOG_FORMAT((KSenCoreServiceManagerLogChannelBase  , KMaxLogLevel, _L8("- A non-threadsafe, unsharable local provider (hostlet) was found: 0x%X - lookup info: 0x%X, lookup count: %d"), pHostlet, pLookupInfo, pLookupInfo->LookupCount()));
+            if(pHostlet->Reinitializable())
+                {
+                pHostlet->ReinitL();
+                TLSLOG_L(KSenCoreServiceManagerLogChannelBase  , KMaxLogLevel,"- Provider was also reinitialized.");
+                }
+            return *pHostlet;
+            }
+        }
+#ifdef _SENDEBUG
+    else
+        {
+        TLSLOG_L(KSenCoreServiceManagerLogChannelBase  , KMaxLogLevel,"- Matching unsharable provider was NOT found from the cache.");
+        }
+#endif
+
+    
+    // The provider has not yet been cached into memory, so load it:
+    // This method call *can leave*, if ECOM lookup fails!
+    // In case of leave Propagate meaningful error code to Remote Service Consumer 
+    TInt leaveCode(KErrNone); 
+    TRAP( leaveCode, pHostlet = CSenProvider::NewL(aHostletEndpoint) );
+    if( !pHostlet )
+    	{
+    	if( leaveCode )
+    		{
+    		TLSLOG_FORMAT((KSenCoreServiceManagerLogChannelBase  , KMinLogLevel, _L8("- Could not load Local Provider plugin, leave: %d"), leaveCode));	
+    		User::Leave( KErrSenHostNotAvailable ); // throw forward : meaningful errcode to consumer
+    		}
+    	}
+    	
+    CleanupStack::PushL(pHostlet);
+
+    TInt append(KErrNone);
+	if (pHostlet)
+	{
+    if(pHostlet->Sharable())
+        {
+        append = iSharableProviders.Append(pHostlet);
+        if(append==KErrNone)
+            {
+            TLSLOG_FORMAT((KSenCoreServiceManagerLogChannelBase  , KMaxLogLevel, _L8("- Loaded new sharable hostlet instance: 0x%X"), &pHostlet));
+            CleanupStack::Pop(); // pHostlet
+            }
+        else
+            {
+            TLSLOG_L(KSenCoreServiceManagerLogChannelBase  , KMinLogLevel,"- iSharableProviders.Append failed."); // OOM case
+            CleanupStack::PopAndDestroy(); // pHostlet
+            }
+        }
+    else // unsharable provider
+        {
+        // LIST OF UNSHARABLE PROVIDERS IS USED MAINLY TO MAKE IT
+        // POSSIBLE TO DE-ALLOCATE LOADED ECOM PLUG-IN INSTANCIES.
+        // In MCoreServiceManager there ReleaseHostletL() method gets
+        // called, which means that such provider may be removed from
+        // the map and destroyed. Otherwise, such hostlets are destroyed,
+        // when server (main thread) goes down.
+        
+        pLookupInfo = NULL;
+        if(pHostlet->Threadsafe())
+            {
+            TLSLOG_L(KSenCoreServiceManagerLogChannelBase  , KMaxLogLevel,"- Adding new threadsafe, unsharable provider into cache.");
+            pLookupInfo = CSenHostletLookupInfo::NewLC(aReqThreadId, aReqConsumerId);
+            }
+        else
+            {
+            // Any non-threadsafe provider should compare whether consumer ID
+            // is equal. The thread ID is irrelevant in the matching.
+            TLSLOG_L(KSenCoreServiceManagerLogChannelBase  , KMaxLogLevel,"- Adding new non-threadsafe, unsharable provider into cache.");
+            pLookupInfo = CSenHostletLookupInfo::NewLC(KNullDesC, aReqConsumerId);
+            }
+
+        pLookupInfo->IncrementLookupCount();
+        append = iUnsharableProviders.Append(pLookupInfo, pHostlet);
+        if(append==KErrNone)
+            {
+            TLSLOG_FORMAT((KSenCoreServiceManagerLogChannelBase  , KMaxLogLevel, _L8("- Loaded new unsharable hostlet instance: 0x%X, lookup info: 0x%X, lookup count: %d"), pHostlet, pLookupInfo, pLookupInfo->LookupCount()));
+            CleanupStack::Pop(2); // pLookupInfo, pHostlet
+            }
+        else
+            {
+            TLSLOG_L(KSenCoreServiceManagerLogChannelBase  , KMinLogLevel,"- iUnsharableProviders.Append failed."); // OOM case
+            CleanupStack::PopAndDestroy(2); // pLookupInfo, pHostlet
+            }
+        }
+	}
+    User::LeaveIfError(append); // KErrNoMemory
+    return *pHostlet;
+    }
+
+TInt CSenXMLDAO::ReleaseHostletL(const MSenProvider* aHostlet,
+                                 const TDesC& aReqThreadId,
+                                 const TDesC8& aReqConsumerId)
+    {
+    // This method needs to be wrapped inside critical section 
+    TLSLOG_L(KSenCoreServiceManagerLogChannelBase  , KMaxLogLevel,"CSenXMLDAO::ReleaseHostletL:");
+    TLSLOG(KSenCoreServiceManagerLogChannelBase  , KMaxLogLevel,(aHostlet->Endpoint()));
+    TLSLOG(KSenCoreServiceManagerLogChannelBase  , KMaxLogLevel,(aHostlet->Contract()));
+    TLSLOG(KSenCoreServiceManagerLogChannelBase  , KMaxLogLevel,(aReqThreadId));
+    TLSLOG(KSenCoreServiceManagerLogChannelBase  , KMaxLogLevel,(aReqConsumerId));
+
+
+    // Currently, sharable hostlets cannot be released
+    if(aHostlet->Sharable())
+        {
+        return KErrNotSupported;
+        }
+
+    // This method simple looks for any unsharable providers, which
+    TInt unsharableCount(iUnsharableProviders.Count());
+    TInt retVal(KErrNotFound);
+    for(TInt u=0; u<unsharableCount; u++)
+        {
+        CSenHostletLookupInfo* pLookupInfo = iUnsharableProviders.KeyAt(u);
+        MSenProvider* pHostlet = (MSenProvider*)iUnsharableProviders.ValueAt(u);
+        // Check whether the hostlet instances match
+        if(pHostlet && aHostlet != pHostlet)
+            {
+            continue; // no match
+            }
+        else if(aHostlet->Threadsafe())
+            {
+            if(!(pLookupInfo && pLookupInfo->ThreadId() == aReqThreadId
+                           && pLookupInfo->ConsumerId() == aReqConsumerId))
+                {
+                // mismatch either in thread or consumer id, or both; so
+                // check next one from the cache (map)
+                continue; // no match
+                }
+            }
+        else if(!(pLookupInfo && pLookupInfo->ConsumerId() == aReqConsumerId))
+            {
+            // even though thread (requester) is allowed to be change, the 
+            // hostlet still needs to be invoked using same consumer id,
+            // Since this is *not* the case, check next one from the cache (map)
+            continue; // no match
+            }
+            
+        // match: decrement lookup count
+        pLookupInfo->DecrementLookupCount();
+        TInt lookupCount = pLookupInfo->LookupCount();
+        TLSLOG_FORMAT((KSenCoreServiceManagerLogChannelBase  , KNormalLogLevel, _L8("- LookupInfo: 0x%X, lookup count after decrement: %d"), pLookupInfo, lookupCount));
+        if(pHostlet && pHostlet->StayOnBackground())
+            {
+            if(pHostlet->Reinitializable() && lookupCount==0)
+                {
+                // no-one is consuming the service, 
+                // so re-init this hostlet instance:
+                TLSLOG_FORMAT((KSenCoreServiceManagerLogChannelBase  , KMaxLogLevel, _L8("- Reinitializing unsharable hostlet instance: 0x%x"), pHostlet));
+                retVal = pHostlet->ReinitL();
+                }
+            }
+        else if(lookupCount==0) // this is the last consumer
+            {
+            // no need to keep this instance on background
+            // and no-one is consuming it's service
+            // destroy the ECOM plug-in instance:
+            TLSLOG_FORMAT((KSenCoreServiceManagerLogChannelBase  , KMaxLogLevel, _L8("- Deleting unsharable hostlet instance: 0x%x"), pHostlet));
+            retVal = iUnsharableProviders.RemoveByKey(*pLookupInfo); 
+            }
+        break; // release complete
+        } // for each map item..
+    return retVal; // KErrNone or KErrNotFound, or some error from ReinitL()
+  }
+void CSenXMLDAO::UpdateTouchSessionDBL(MSenServiceDescription& asd)
+	{
+	TInt count(0);
+	
+	RWSDescriptionArray matches;
+	CleanupClosePushL(matches);
+	
+	FindAllMatchingServiceDescriptions(matches, asd);
+	count = matches.Count();
+	
+	for(TInt i=0; i < count; i++)
+		{
+		TUint current_tick(0);
+		TBuf8<32> tickBuf;
+		
+		CSenWSDescription* sd = matches[i];
+		CSenElement& sdElem = sd->AsElement();
+		
+		current_tick = User::NTickCount();
+		tickBuf.Num(current_tick);
+		sdElem.AddAttrL(KTouch(), tickBuf);
+		}
+	
+	CleanupStack::PopAndDestroy(&matches);
+	// CleanupUnusedSessionDBL(); 
+                                  // (don't de-serialize old items). Serialized 
+	                              // objects cannot be de-allocated on the fly.
+	}
+	
+void CSenXMLDAO::CleanupUnusedSessionDBL()
+	{
+	TInt count(0);
+	
+	RPointerArray<CSenElement> sdElemList;
+	CleanupClosePushL(sdElemList);
+	
+	count = iSessions.Count();
+	
+	TUint32 current_tick(0);
+	TUint32 db_ticks(0);
+	TUint32 diff_ticks(0);
+	
+	for(TInt i=0; i < count; i++)
+		{
+				
+		CSenXmlServiceDescription* sd = iSessions[i];
+		CSenElement& sdElem = sd->AsElement();
+		TPtrC8 localName = sdElem.LocalName();
+		const TDesC8* val = sdElem.AttrValue(KTouch());
+		if(val != NULL)
+			{
+			TLex8 lex;
+            lex.Assign(*val);
+            lex.Val(db_ticks, EDecimal);
+            
+            current_tick = User::NTickCount();
+            diff_ticks = current_tick - db_ticks;
+                        	
+			if(KMaxTicks <= diff_ticks || current_tick < db_ticks)
+				{
+				delete iSessions[i];
+        		iSessions.Remove(i);
+        		
+        		i--;
+        		count--;
+				}
+			}
+		}
+	
+	CleanupStack::PopAndDestroy(&sdElemList);	
+	}	
+
+CSenHostletLookupInfo* CSenHostletLookupInfo::NewL(const TDesC& aThreadIdFullName,
+                                                   const TDesC8& aConsumerIdUrn)
+    {
+    CSenHostletLookupInfo* pNew = CSenHostletLookupInfo::NewLC(aThreadIdFullName,
+                                                               aConsumerIdUrn);
+    CleanupStack::Pop();
+    return pNew;
+    }
+
+CSenHostletLookupInfo* CSenHostletLookupInfo::NewLC(const TDesC& aThreadIdFullName,
+                                                  const TDesC8& aConsumerIdUrn)
+    {
+    CSenHostletLookupInfo* pNew = new (ELeave) CSenHostletLookupInfo;
+    CleanupStack::PushL(pNew);
+    pNew->ConstructL(aThreadIdFullName, aConsumerIdUrn);
+    return pNew;
+    }
+
+void CSenHostletLookupInfo::ConstructL(const TDesC& aThreadIdFullName,
+                                      const TDesC8& aConsumerIdUrn)
+    {
+    ipFullThreadName = aThreadIdFullName.AllocL();
+    ipUniqueConsumerId = aConsumerIdUrn.AllocL();
+    ipLookupCount = new (ELeave) TInt(0);
+    }
+
+
+CSenHostletLookupInfo::CSenHostletLookupInfo()
+: ipFullThreadName(NULL),
+  ipUniqueConsumerId(NULL),
+  ipLookupCount(NULL)
+    {
+    }
+
+CSenHostletLookupInfo::~CSenHostletLookupInfo()
+    {
+    delete ipFullThreadName;
+    delete ipUniqueConsumerId;
+    delete ipLookupCount;
+    }
+
+TPtrC CSenHostletLookupInfo::ThreadId() const
+    {
+    return *ipFullThreadName;
+    }
+
+TPtrC8 CSenHostletLookupInfo::ConsumerId() const
+    {
+    return *ipUniqueConsumerId;
+    }
+
+
+TInt CSenHostletLookupInfo::LookupCount() const
+    {
+    return *ipLookupCount;
+    }
+
+void CSenHostletLookupInfo::IncrementLookupCount()
+    {
+    (*ipLookupCount)++;
+    }
+
+void CSenHostletLookupInfo::DecrementLookupCount()
+    {
+    (*ipLookupCount)--;
+    }
+
+
+TBool CSenHostletLookupInfo::operator==(const CSenHostletLookupInfo& aHostletRequestor)
+    {
+    return((ipFullThreadName->Length()==0 || aHostletRequestor.ThreadId() == *ipFullThreadName)
+            && aHostletRequestor.ConsumerId() == *ipUniqueConsumerId);
+    
+    //    return (aHostletRequestor.ThreadId() == *ipFullThreadName
+//            && aHostletRequestor.ConsumerId() == *ipUniqueConsumerId);
+    }
+
+
+// END OF FILE
+