syncmlfw/dm/hostserver/dmhostserverbase/src/nsmldmhostsession.cpp
changeset 0 b497e44ab2fc
child 2 5594fba90824
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/syncmlfw/dm/hostserver/dmhostserverbase/src/nsmldmhostsession.cpp	Thu Dec 17 09:07:52 2009 +0200
@@ -0,0 +1,2380 @@
+/*
+* Copyright (c) 2005 Nokia Corporation and/or its subsidiary(-ies). 
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:  A common session class for all the specialized 
+*				 DM Host Servers.
+*
+*/
+
+
+// ------------------------------------------------------------------------------------------------
+// Includes
+// ------------------------------------------------------------------------------------------------
+//
+#include <s32mem.h>
+#include <s32strm.h>
+#include <implementationinformation.h>
+#include <ecom.h>
+#include <nsmlconstants.h>
+#include <nsmldebug.h>
+#include <smldmadapter.h>
+
+// FOTA
+#include <nsmldmconst.h>
+// FOTA end
+#include <nsmldmuri.h>
+#include <e32property.h>
+#include "nsmldminternalpskeys.h"
+#include "nsmldmclientandserver.h"
+#include "nsmldmhostserver.h"
+#include "nsmldmhostsession.h"
+#include "nsmldmcmdarghandler.h"
+#include "nsmldmimpluids.h"
+#include <featmgr.h>
+
+#ifndef __WINS__
+// This lowers the unnecessary compiler warning (armv5) to remark.
+// "Warning:  #174-D: expression has no effect..." is caused by 
+// DBG_ARGS8 macro in no-debug builds.
+#pragma diag_remark 174
+#endif
+
+
+// ------------------------------------------------------------------------------------------------
+// Constants
+// ------------------------------------------------------------------------------------------------
+//
+// Granularity of the lists; mapping info and prevUriSegList
+const TInt KNSmlDmGranularity = 8;
+
+// This means the dm adapter doesn't support streaming
+const TInt KNSmlDmNotSupported = -1;
+
+// During the fetch link serving the callbacks are handled differently
+const TInt KNSmlDmNoRef = -1; 
+
+// A safety margin (in bytes) which is left unreserved in the chunk
+const TInt KNSmlDmChunkMarginal = 128;
+
+// A cross-reference to the interner adapter is recognized using these strings
+_LIT8 ( KNSmlDmApAdapterURI1, "AP" );
+_LIT8 ( KNSmlDmApAdapterURI2, "./AP" );
+
+// Identifies the server which owns the internet DM plug-in adapter
+const TInt KNSmlDmApAdapterServerId = 1;
+
+// Tells to the session class that it is acting as a fetch link server
+const TInt KNSmlDmFetchLinkServerId = 99;
+
+// The constant part of the result item size in bytes: 	
+//  iResultRef => 2 bytes
+//  iResult->Size => 4 bytes
+//  iMimeType->Length => 2 bytes
+const TInt KNSmlDmConstItemSize = 8;
+
+// FOTA
+const TInt KNSmlDmLastPackage = 1;
+// FOTA end
+
+
+// ------------------------------------------------------------------------------------------------
+// CNSmlDMHostSession::CNSmlDMHostSession
+//	C++ constructor.
+//	@param aServer. The server instance, owner of session.
+// ------------------------------------------------------------------------------------------------
+//
+CNSmlDMHostSession::CNSmlDMHostSession ( CNSmlDMHostServer& aServer ) : 
+    iServer(aServer)
+	{
+	_DBG_FILE("CNSmlDMHostSession::CNSmlDMHostSession(): begin");
+	iServer.IncSessionCount();
+	_DBG_FILE("CNSmlDMHostSession::CNSmlDMHostSession(): end");
+	}
+
+// ------------------------------------------------------------------------------------------------
+// CNSmlDMHostSession::~CNSmlDMHostSession
+//  C++ destructor.
+// ------------------------------------------------------------------------------------------------
+//
+CNSmlDMHostSession::~CNSmlDMHostSession()
+	{	
+	_DBG_FILE("CNSmlDMHostSession::~CNSmlDMHostSession(): begin");
+	if ( iCbSessConnected )
+		{
+		iCbSession.Close();		
+		}
+	iServer.DecSessionCount();
+	delete iMgmtTree;
+	if ( iOwnId != KNSmlDmFetchLinkServerId )
+		{
+		iChunk.Close(); 		
+		}
+	
+	for ( TInt i=0; i<iResultList.Count(); i++ )
+		{
+		delete iResultList[i];
+		}
+	iResultList.Close();
+	iStatusCodeList.Close();
+	iCallbackList.Close();
+	
+	if ( iLargeWriteStream.streamPtr )
+		{
+		iLargeWriteStream.streamPtr->Close();		
+		}
+	if ( iResultReadStream )
+		{
+		iResultReadStream->Close();		
+		}
+	
+	// delete all loaded adapters
+	for ( TInt i=0; i<iAdapters.Count(); i++ )
+		{
+		delete iAdapters[i].adapterPtr;
+		}
+	iAdapters.Close();
+	REComSession::FinalClose();	
+	if ( iMapUris )
+		{
+		iMapUris->ResetAndDestroy();
+		delete iMapUris;	
+		}
+	if ( iMapLuids )
+		{
+		iMapLuids->ResetAndDestroy();
+		delete iMapLuids;
+		}
+	delete iSemaphoreName;
+	delete iResultOtherAdapter;
+	delete iLargeObject;
+	DeletePrevParams();
+	FeatureManager::UnInitializeLib();
+	_DBG_FILE("CNSmlDMHostSession::~CNSmlDMHostSession(): end");
+	}
+
+// ------------------------------------------------------------------------------------------------
+// CNSmlDMHostSession::NewL
+//	Creates a new session object.
+//	@param aServer. Reference to server is needed in order to increase and decrease session counts.
+//	@return CNSmlDMHostSession*. New instance of this class.
+// ------------------------------------------------------------------------------------------------
+//
+CNSmlDMHostSession* CNSmlDMHostSession::NewL ( CNSmlDMHostServer& aServer )
+	{
+	_DBG_FILE("CNSmlDMHostSession::NewL(): begin");
+	CNSmlDMHostSession* self= new (ELeave) CNSmlDMHostSession ( aServer );
+	CleanupStack::PushL(self);
+	self->ConstructL();
+	CleanupStack::Pop(); // self
+	_DBG_FILE("CNSmlDMHostSession::NewL(): end");
+	return self;
+	}
+
+// ------------------------------------------------------------------------------------------------
+// CNSmlDMHostSession::ConstructL
+//	Symbian 2nd phase constructor
+// ------------------------------------------------------------------------------------------------
+//
+void CNSmlDMHostSession::ConstructL()
+	{
+	_DBG_FILE("CNSmlDMHostSession::ConstructL(): begin");
+	iMgmtTree = CNSmlDmMgmtTree::NewL();
+	iCommitStatus.iStreamingOngoing = EFalse;
+	iCommitStatus.iStreamCommitted = EFalse;
+	FeatureManager::InitializeLibL();
+	_DBG_FILE("CNSmlDMHostSession::ConstructL(): end");
+	}
+
+// ------------------------------------------------------------------------------------------------
+// CNSmlDMHostSession::ServiceL
+//	Handles the servicing of client requests.
+//	Entry point for arriving messages.
+//	@param aMessage. An object which encapsulates a client request.
+// ------------------------------------------------------------------------------------------------
+//
+void CNSmlDMHostSession::ServiceL ( const RMessage2& aMessage )
+	{
+	_DBG_FILE("CNSmlDMHostSession::ServiceL(): begin");
+	if(!aMessage.HasCapability(ECapabilityDiskAdmin))
+	    {
+	    _DBG_FILE("CNSmlDMHostSession::ServiceL(): capability fail");
+	    aMessage.Complete( KErrPermissionDenied );
+	    return;
+	    }
+	TRAPD ( err, DispatchMessageL ( aMessage ) );
+	aMessage.Complete( err );
+	_DBG_FILE("CNSmlDMHostSession::ServiceL(): end");
+	}
+
+// ------------------------------------------------------------------------------------------------
+// CNSmlDMHostSession::DispatchMessageL
+//	Extracts the operation code from the message. 
+//	Based on that calls the right private function.
+//	@param aMessage. An object which encapsulates a client request.
+// ------------------------------------------------------------------------------------------------
+//
+void CNSmlDMHostSession::DispatchMessageL ( const RMessage2& aMessage )
+	{
+	_DBG_FILE("CNSmlDMHostSession::DispatchMessageL(): begin");
+	switch( aMessage.Function() )
+        {
+		case ENSmlDMCloseSession:
+        	CloseSessionL();
+        	break;
+		case ENSmlDMGetDDF:
+        	GetDDFStructureL ( aMessage );
+        	break;
+        case ENSmlDMUpdateLeaf:
+        	UpdateLeafOrExecuteL ( aMessage, ENSmlDMUpdateLeaf );
+        	break;
+        case ENSmlDMExecute:
+        	UpdateLeafOrExecuteL ( aMessage, ENSmlDMExecute );
+        	break;
+        case ENSmlDMUpdateLeafLarge:
+        	UpdateLeafOrExecuteLargeL ( aMessage, ENSmlDMUpdateLeafLarge );
+        	break;
+        case ENSmlDMExecuteLarge:
+        	UpdateLeafOrExecuteLargeL ( aMessage, ENSmlDMExecuteLarge );
+        	break;        	
+        case ENSmlDMAddNode:
+        	AddCopyOrDeleteL ( aMessage, ENSmlDMAddNode );
+        	break;
+        case ENSmlDMCopy:
+        	AddCopyOrDeleteL ( aMessage, ENSmlDMCopy );
+        	break;
+        case ENSmlDMDelete:
+        	AddCopyOrDeleteL ( aMessage, ENSmlDMDelete );
+        	break;        
+        case ENSmlDMStartAtomic:
+        	StartAtomicL ( aMessage );
+        	break;
+        case ENSmlDMCommitAtomic:
+        	CommitAtomicL ( aMessage );
+        	break;
+        case ENSmlDMRollbackAtomic:
+        	RollbackAtomicL ( aMessage );
+        	break;
+        case ENSmlDMCompleteCommands:
+        	CompleteCommandsL ( aMessage );
+        	break;
+        case ENSmlDMFetchLeaf:
+        	FetchLeafChildUrisOrSizeL ( aMessage, ENSmlDMFetchLeaf );
+        	break;
+        case ENSmlDMFetchLink:
+        	FetchLinkL ( aMessage );
+        	break;
+        case ENSmlDMFetchLeafSize:
+        	FetchLeafChildUrisOrSizeL ( aMessage, ENSmlDMFetchLeafSize );
+        	break;
+        case ENSmlDMChildUriList:
+        	FetchLeafChildUrisOrSizeL ( aMessage, ENSmlDMChildUriList );
+        	break;
+    	case ENSmlDMChunkHandle:
+        	SetChunkHandleL ( aMessage ); 
+        	break;
+    	case ENSmlDMGetMappings:
+        	GetMappingsL ( aMessage ); 
+        	break;
+    	case ENSmlDMGetStatuses:
+        	GetStatusesL ( aMessage ); 
+        	break;
+    	case ENSmlDMGetResults:
+        	GetResultsL ( aMessage ); 
+        	break;
+    	case ENSmlDMGetMore:
+        	GetResultsL ( aMessage ); 
+        	break;
+        // FOTA
+    	case ENSmlDMGenericAlertsSent:
+    	if(!FeatureManager::FeatureSupported( KFeatureIdSyncMlDm112  ))
+    	{
+    	_DBG_FILE(" CNSmlDMHostSession::DispatchMessageL(): calling new MarkGenAlertsSentL(message)");
+        	MarkGenAlertsSentL(aMessage); 	
+    	}
+    	else
+    	{
+    	_DBG_FILE(" CNSmlDMHostSession::DispatchMessageL(): calling old  MarkGenAlertsSentL ");
+        MarkGenAlertsSentL();	
+    	}
+        	break;
+        // FOTA end
+		default:
+			PanicClient ( aMessage, KErrNotSupported );
+        }
+	_DBG_FILE("CNSmlDMHostSession::DispatchMessageL(): end");
+	}
+
+
+// ------------------------------------------------------------------------------------------------
+// CNSmlDMHostSession::PanicClient
+//	Panics the client
+//	@param aMessage. Message from client to panic.
+//	@param aReason. Reason code.
+// ------------------------------------------------------------------------------------------------
+//
+void CNSmlDMHostSession::PanicClient ( const RMessage2& aMessage, TInt aReason ) const
+	{
+	_DBG_FILE("CNSmlDMHostSession::PanicClient(): begin");
+	aMessage.Panic ( _L( "CNSmlDMHostSession" ), aReason );
+	_DBG_FILE("CNSmlDMHostSession::PanicClient(): end");
+	}
+	
+// ------------------------------------------------------------------------------------------------
+// CNSmlDMHostSession::CloseSessionL
+//	Empty function.
+//	Kept here for possible future needs. 
+//	Freeing of resources is done in the destructor.
+// ------------------------------------------------------------------------------------------------
+//
+void CNSmlDMHostSession::CloseSessionL() const
+	{
+	_DBG_FILE("CNSmlDMHostSession::CloseSessionL(): begin");
+	_DBG_FILE("CNSmlDMHostSession::CloseSessionL(): end");
+	}
+
+void CNSmlDMHostSession::MarkGenAlertsSentL(const RMessage2& aMessage)
+	{
+
+	_DBG_FILE("CNSmlDMHostSession::MarkGenAlertsSentL(RMessage2): begin");
+	
+	HBufC8* tempPtr = HBufC8::NewLC(aMessage.GetDesLength(0));
+	_DBG_FILE("CNSmlDMHostSession::MarkGenAlertsSentL(RMessage2): crating hBufC for length of URI ");
+	TPtr8 uRI = tempPtr->Des();
+   _DBG_FILE("CNSmlDMHostSession::MarkGenAlertsSentL(RMessage2): TPrt got from HBufC ");
+	aMessage.ReadL(0, uRI, 0);
+	TUint32 adId(0);
+	TNSmlDmDDFFormat nodeType;
+	_DBG_FILE("CNSmlDMHostSession::MarkGenAlertsSentL(RMessage2): Before calling adapterIdFromUriL  ");
+	TBool adapterFound = AdapterIdFromUriL ( uRI, adId, nodeType );
+	
+	_LIT8(KSCOMONODE, "SCOMO");
+	
+	// For AM Adapter check for Node "SCOMO" if present in Uri then use Adapter Implementation UID
+	
+	if(uRI.Compare(KSCOMONODE) == KErrNone)
+	{
+		adId = KNSmlDMAMAdapterImplUid;
+		adapterFound = ETrue;
+	}
+	
+	
+	_DBG_FILE("CNSmlDMHostSession::MarkGenAlertsSentL(RMessage2): After calling adapterIdFromUriL ");
+	
+	if ( adapterFound )
+		{
+	_DBG_FILE("CNSmlDMHostSession::MarkGenAlertsSentL(RMessage2): adapter is found ! ");	  
+	
+        CSmlDmAdapter* adapter = NULL;
+        adapterFound = EFalse;
+	    for ( TInt i(0); i<iAdapters.Count(); i++ )
+		{
+		
+		if ( iAdapters[i].adapterId == adId )
+			{
+			adapterFound = ETrue;
+			if ( !iAdapters[i].adapterPtr )
+				{
+				adapter = LoadNewAdapterL ( i, adId );
+				if ( !adapter )
+					{
+					User::Leave ( KErrArgument );
+					}
+				}
+			// Call overloaded function of the  adapter to request
+			// the  adapter to mark Generic Alerts sent.
+		
+			TInt resetGenAlerts ( KNSmlDMResetGenAlerts );
+			iAdapters[i].adapterPtr->StreamingSupport ( resetGenAlerts );
+		
+			}
+		}
+	}
+	CleanupStack::PopAndDestroy(); //tempPtr
+	if ( !adapterFound )
+	    {
+	    _DBG_FILE("CNSmlDMHostSession::MarkGenAlertsSentL(RMessage2): adapter NOT :-( found ! ");	  
+		User::Leave ( KErrNotFound );	    
+	    }
+	_DBG_FILE("CNSmlDMHostSession::MarkGenAlertsSentL(): end");
+	}
+
+// FOTA
+// ------------------------------------------------------------------------------------------------
+// CNSmlDMHostSession::MarkGenAlertsSentL
+//	This function is called only for the FOTA adapter.
+//	Makes a request for the FOTA adapter to mark generic alerts sent.
+//	In other words, the written generic alerts are issued without
+//	errors to the remote server.
+// ------------------------------------------------------------------------------------------------
+//
+void CNSmlDMHostSession::MarkGenAlertsSentL()
+	{
+	_DBG_FILE("CNSmlDMHostSession::MarkGenAlertsSentL(): begin");
+	CSmlDmAdapter* adapter = NULL;
+	TBool adapterFound ( EFalse );
+	for ( TInt i(0); i<iAdapters.Count(); i++ )
+		{
+		if ( iAdapters[i].adapterId == KNSmlDMFotaAdapterImplUid )
+			{
+			adapterFound = ETrue;
+			if ( !iAdapters[i].adapterPtr )
+				{
+				adapter = LoadNewAdapterL ( i, KNSmlDMFotaAdapterImplUid );
+				if ( !adapter )
+					{
+					User::Leave ( KErrArgument );
+					}
+				}
+			// Call overloaded function of the FOTA adapter to request
+			// the FOTA adapter to mark Generic Alerts sent.
+			TInt resetGenAlerts ( KNSmlDMResetGenAlerts );
+			iAdapters[i].adapterPtr->StreamingSupport ( resetGenAlerts );
+			}
+		else if ( iAdapters[i].adapterId == KNSmlDMAMAdapterImplUid )
+			{
+			adapterFound = ETrue;
+			if ( !iAdapters[i].adapterPtr )
+				{
+				adapter = LoadNewAdapterL ( i, KNSmlDMAMAdapterImplUid );
+				if ( !adapter )
+					{
+					User::Leave ( KErrArgument );
+					}
+				}
+			// Call overloaded function of the AM adapter to request
+			// the AM adapter to mark Generic Alerts sent.
+			TInt resetGenAlerts ( KNSmlDMResetGenAlerts );
+			iAdapters[i].adapterPtr->StreamingSupport ( resetGenAlerts );
+			}
+		
+			
+		}
+	if ( !adapterFound )
+	    {
+		User::Leave ( KErrNotFound );	    
+	    }
+	_DBG_FILE("CNSmlDMHostSession::MarkGenAlertsSentL(): end");
+	}
+// FOTA end
+
+// ------------------------------------------------------------------------------------------------
+// CNSmlDMHostSession::GetDDFStructureL
+//	Gets DDF structure from the dm adapters.
+//	aMessage parameter contains a list of adapters which are already loaded.
+//	Writes the combined DDF structure to the chunk in the WBXML format.
+//	Returns also a checksum of the DDF structure to the client. 
+//	@param aMessage. A list of already loaded adapters, and place for checksum.
+// ------------------------------------------------------------------------------------------------
+//
+void CNSmlDMHostSession::GetDDFStructureL ( const RMessage2& aMessage )
+	{
+	_DBG_FILE("CNSmlDMHostSession::GetDDFStructureL(): begin");
+	RImplInfoPtrArray allDmAdapters;
+	CleanupStack::PushL ( PtrArrCleanupItemRArr ( CImplementationInformation, &allDmAdapters ) );
+
+	RArray<TUint32> dontLoadThese;
+	CleanupClosePushL ( dontLoadThese );
+	ReadUidsL ( aMessage, dontLoadThese );
+		
+	TUid ifUid = { KSmlDMInterfaceUid };
+	REComSession::ListImplementationsL ( ifUid, allDmAdapters );
+	RemoveAlreadyLoadedL ( allDmAdapters, dontLoadThese );
+	CleanupStack::PopAndDestroy();  // dontLoadThese
+
+	RPointerArray<HBufC8> versions;
+	CleanupStack::PushL ( PtrArrCleanupItemRArr ( HBufC8, &versions ) );
+	RArray<TInt32> uids;
+	CleanupClosePushL ( uids );
+	
+	CSmlDmAdapter* adapter = NULL;
+	for ( TInt i=0; i<allDmAdapters.Count(); i++ )
+		{
+		TRAPD ( err, ( adapter = CSmlDmAdapter::NewL ( allDmAdapters[i]->ImplementationUid(), *this ) ) );
+		if ( err == KErrNone && adapter )
+			{
+			CleanupStack::PushL(adapter);
+			AskInfoFromAdapterL ( adapter, versions, uids, allDmAdapters[i]->ImplementationUid().iUid );		
+			CleanupStack::PopAndDestroy(); //adapter
+			}
+		} 
+	TUint16 crc = CalcCheckSumL ( versions, uids );
+	CleanupStack::PopAndDestroy(3); // uids, versions, allDmAdapters
+	WriteTreeToChunkL();
+	aMessage.WriteL ( 2, TPckgBuf<TInt> (crc) );
+	TPckgBuf<TInt> cb = ( iCallbackList.Count() ) ? iCallbackList[0].callBack : ENSmlDmCallbackNone;
+	aMessage.WriteL ( 3, cb );	
+	_DBG_FILE("CNSmlDMHostSession::GetDDFStructureL(): end");
+	}
+
+
+// ------------------------------------------------------------------------------------------------
+// CNSmlDMHostSession::ReadUidsL
+//	Auxiliary function called by GetDDFStructureL.
+//	Reads the UIDs of the loaded adapters from the message, 
+//	and stores those to internal list. 
+//	@param aMessage. An object which encapsulates a client request.
+//	@param aUids. A reference parameter, a place for extracted list of UIDs.
+// ------------------------------------------------------------------------------------------------
+//
+void CNSmlDMHostSession::ReadUidsL ( const RMessage2& aMessage, RArray<TUint32>& aUids ) const
+	{
+	_DBG_FILE("CNSmlDMHostSession::ReadUidsL(): begin");
+	HBufC8* buffer = HBufC8::NewLC ( aMessage.GetDesLengthL(0) );
+    TPtr8 bufPtr = buffer->Des();
+    aMessage.ReadL ( 0, bufPtr, 0 );
+    
+    RDesReadStream readStream;
+	readStream.Open ( *buffer );
+	CleanupClosePushL ( readStream );
+	TUint8 nOfuids = readStream.ReadUint8L();
+    	
+	for ( TInt i=0; i<nOfuids; i++ )
+		{
+		TUint32 uidTemp = readStream.ReadUint32L();
+		aUids.Append ( uidTemp );		
+		}
+	
+	CleanupStack::PopAndDestroy(2); // readStream, buffer
+	_DBG_FILE("CNSmlDMHostSession::ReadUidsL(): end");
+	}
+
+// ------------------------------------------------------------------------------------------------
+// CNSmlDMHostSession::RemoveAlreadyLoadedL
+//	Auxiliary function called by GetDDFStructureL.
+//	Gets a list of all the potential dm adapters.
+//	Removes from it those which are alreay loaded.  
+//	@param aAllAds. A reference parameter, after this function call 
+//	                contains the acceptable adapters.
+//	@param aUids. A list of adapters which are already loaded.
+// ------------------------------------------------------------------------------------------------
+//
+void CNSmlDMHostSession::RemoveAlreadyLoadedL ( RImplInfoPtrArray& aAllAds, RArray<TUint32>& aUids ) const
+	{
+	_DBG_FILE("CNSmlDMHostSession::RemoveAlreadyLoadedL(): begin");
+	for ( TInt i=0; i<aAllAds.Count(); i++ )
+		{
+		for ( TInt u=0; u<aUids.Count(); u++ )
+			{
+			if ( aUids[u] == (TUint32)aAllAds[i]->ImplementationUid().iUid )
+				{
+				delete aAllAds[i];
+				aAllAds[i] = NULL;
+				aAllAds.Remove(i);
+				i--;
+				break;								
+				}
+			}
+		}
+	_DBG_FILE("CNSmlDMHostSession::RemoveAlreadyLoadedL(): end");
+	}
+
+// ------------------------------------------------------------------------------------------------
+// CNSmlDMHostSession::AskInfoFromAdapterL
+//	Auxiliary function called by GetDDFStructureL.
+//	Asks initial information from the loaded dm adapter.
+//	E.g. whether the adapter supports streaming or not.
+//	@param aAdapter. A pointer to the just loaded dm plug-in adapter. 
+//	@param aVersions. A list of DDF versions collected from the adapters. 
+//	@param aUids. A list of adapter UIDs. Note that aVersions and aUids
+//	              are always ordered to ascending order in order to prevent
+//	              a checksum to change value if ECom framework gives a list
+//	    	      of potential plug-in adapters in different order.
+//	@param aAdapterId. Identifier of the dm plug-in adapter.
+// ------------------------------------------------------------------------------------------------
+//
+void CNSmlDMHostSession::AskInfoFromAdapterL ( CSmlDmAdapter* aAdapter, RPointerArray<HBufC8>& aVersions, 
+												RArray<TInt32>& aUids, TInt32 aAdapterId )
+	{
+	_DBG_FILE("CNSmlDMHostSession::AskInfoFromAdapterL(): begin");
+	TNSmlDmAdapter newElement;
+	newElement.adapterPtr = NULL;
+	newElement.adapterId = aAdapterId;
+	newElement.startAtomicCalled = EFalse;
+	newElement.commandsCalled = EFalse;
+	TInt limit ( KNSmlDmNotSupported );
+	newElement.streamingLimit = ( aAdapter->StreamingSupport ( limit ) ) ? limit : KNSmlDmNotSupported;	
+	iAdapters.Append ( newElement );
+
+	CBufBase* version = CBufFlat::NewL(16);
+	CleanupStack::PushL ( version );
+	aAdapter->DDFVersionL ( *version );
+	HBufC8* versionHBufC = HBufC8::NewLC ( version->Size() );
+	*versionHBufC = version->Ptr(0);
+	TInt j=0;
+	// Sort uids and versions to ascending order in arrays
+	while ( j<aUids.Count() &&  aAdapterId < aUids[j] )  
+		{
+		j++;
+		}
+	aUids.InsertL ( aAdapterId, j );
+	aVersions.InsertL ( versionHBufC, j );
+	CleanupStack::Pop(); //versionHBufC
+	CleanupStack::PopAndDestroy(); //version
+		
+	aAdapter->DDFStructureL ( *iMgmtTree );
+	iMgmtTree->SetAdapterUid ( aAdapterId );
+
+	_DBG_FILE("CNSmlDMHostSession::AskInfoFromAdapterL(): end");
+	}
+
+// ------------------------------------------------------------------------------------------------
+// CNSmlDMHostSession::WriteTreeToChunkL
+//	Auxiliary function called by GetDDFStructureL.
+//	Writes a combined DDF stucture to the chunk using DM Utils services.
+// ------------------------------------------------------------------------------------------------
+//
+void CNSmlDMHostSession::WriteTreeToChunkL()
+	{
+	_DBG_FILE("CNSmlDMHostSession::WriteTreeToChunkL(): begin");
+	CBufBase* buffer = CBufFlat::NewL ( 64 );
+	CleanupStack::PushL ( buffer );
+
+	RBufWriteStream writeStream ( *buffer );
+	CleanupClosePushL ( writeStream );
+	iMgmtTree->GenerateWBXMLL ( writeStream );
+	CleanupStack::PopAndDestroy();  // writeStream
+
+	RBufReadStream readStream ( *buffer );
+	CleanupClosePushL ( readStream );
+	iChunk.Adjust ( buffer->Size() );
+
+	RMemWriteStream chunkStream ( iChunk.Base(), iChunk.Size() );
+	CleanupClosePushL ( chunkStream );
+	chunkStream.WriteL ( readStream );
+	CleanupStack::PopAndDestroy(3);  // chunkStream, readStream, buffer
+	_DBG_FILE("CNSmlDMHostSession::WriteTreeToChunkL(): end");
+	}
+
+
+// ------------------------------------------------------------------------------------------------
+// CNSmlDMHostSession::CalcCheckSumL
+//	Auxiliary function called by GetDDFStructureL.
+//	Calculates a CCITT CRC checksum from the collected DDF versions and adapter UIDs 
+//	@param aVersions. A collected list from adapters containing versions of the DDF structure. 
+//	@param aUids. A list of adapter UIDs. 
+//	@return TUint16. Calculated checksum value.
+// ------------------------------------------------------------------------------------------------
+//
+TUint16 CNSmlDMHostSession::CalcCheckSumL ( RPointerArray<HBufC8>& aVersions, RArray<TInt32>& aUids ) const
+	{
+	_DBG_FILE("CNSmlDMHostSession::CalcCheckSumL(): begin");
+	TUint16 crc(0);	
+	CBufBase* checkData = CBufFlat::NewL(32);
+	CleanupStack::PushL(checkData);
+	for ( TInt i(0); i<aUids.Count(); i++ )
+		{
+		checkData->InsertL ( checkData->Size(), aVersions[i]->Des() );
+		checkData->InsertL ( checkData->Size(), &aUids[i], sizeof ( aUids[i] ) );
+		}
+	Mem::Crc ( crc, checkData->Ptr(0).Ptr(), checkData->Size() );
+	CleanupStack::PopAndDestroy(); //checkData
+	_DBG_FILE("CNSmlDMHostSession::CalcCheckSumL(): end");
+	return crc;
+	}
+
+// ------------------------------------------------------------------------------------------------
+// CNSmlDMHostSession::UpdateLeafOrExecuteL
+//	Common function for handling UpdateLeafObject and Execute DM commands.
+//	Reads parameters from the chunk.
+//	Loads the requested adapter if this is a first command to it in this session.
+//	Checks the need to inform adapter at atomic command situation.
+//	Decides whether or not use streaming for passing data to dm plug-in adapter.
+//	Informs the client (DM Tree Module) if there are unread statuses, results or mappings.
+//	@param aMessage. An object which encapsulates a client request. 
+//	@param aCommand. Needed to choose between Update and Execute commands. 
+// ------------------------------------------------------------------------------------------------
+//
+void CNSmlDMHostSession::UpdateLeafOrExecuteL ( const RMessage2& aMessage, TNSmlDmHostOperationCodes aCommand )
+	{
+	_DBG_FILE("CNSmlDMHostSession::UpdateLeafOrExecuteL(): begin");
+	ReadCmdParamsL ( aMessage );
+	CSmlDmAdapter* adapter = NULL;
+	for ( TInt i=0; i<iAdapters.Count(); i++ )
+		{
+		if ( iAdapters[i].adapterId == iAdapterId )
+			{
+			if ( !iAdapters[i].adapterPtr )
+				{
+				adapter = LoadNewAdapterL ( i, iAdapterId );
+				if ( !adapter )
+					{
+					User::Leave ( KErrArgument );					
+					}
+				}
+			if ( iStartAtomic && !iAdapters[i].startAtomicCalled )
+				{
+				iAdapters[i].startAtomicCalled = ETrue;
+				iAdapters[i].adapterPtr->StartAtomicL();
+				}				
+			if ( iAdapters[i].streamingLimit == KNSmlDmNotSupported || iData->Size() < iAdapters[i].streamingLimit )
+				{
+				CallAdapterCommandL ( aCommand, i );
+				}
+			else 
+				{
+				RWriteStream* writeStream = NULL;
+				// FOTA
+				if ( iAdapterId == KNSmlDMFotaAdapterImplUid && aCommand == ENSmlDMUpdateLeaf )
+					{
+					// Call overloaded function of the FOTA adapter to tell the 
+					// total size of incoming large object.
+					TInt sizeOfData ( iData->Size() );
+					iAdapters[i].adapterPtr->StreamingSupport ( sizeOfData );
+					if ( sizeOfData == KErrNoMemory )
+						{
+						User::Leave ( KErrTooBig );						
+						}
+					}
+				// FOTA end
+				CallAdapterCommandL ( aCommand, i, writeStream );
+				if ( !writeStream )
+					{
+					User::Leave ( KErrGeneral );						
+					}
+				writeStream->WriteL ( *iData );
+				writeStream->Close();
+				iAdapters[i].adapterPtr->StreamCommittedL();
+				}
+			TPckgBuf<TInt> cb = ( iCallbackList.Count() ) ? iCallbackList[0].callBack : ENSmlDmCallbackNone;
+			aMessage.WriteL ( 3, cb );				
+			return;
+			}
+		}
+	User::Leave ( KErrArgument );
+	_DBG_FILE("CNSmlDMHostSession::UpdateLeafOrExecuteL(): end");
+	}
+
+// ------------------------------------------------------------------------------------------------
+// CNSmlDMHostSession::UpdateLeafOrExecuteLargeL
+//	Common function for handling UpdateLeafObject and Execute DM commands for large objects.
+//	Reads parameters from the chunk.
+//	Loads the requested adapter if this is a first command to it in this session.
+//	Checks the need to inform adapter at atomic command situation.
+//	Decides whether or not use streaming for passing data to dm plug-in adapter.
+//	In case this is last package of the large object, closes and commits stream,
+//	provided streaming was used for passing a data.
+//	Informs the client (DM Tree Module) if there are unread statuses, results or mappings.
+//	@param aMessage. An object which encapsulates a client request. 
+//	@param aCommand. Needed to choose between Update and Execute commands. 
+// ------------------------------------------------------------------------------------------------
+//
+void CNSmlDMHostSession::UpdateLeafOrExecuteLargeL ( const RMessage2& aMessage, TNSmlDmHostOperationCodes aCommand )
+	{
+	_DBG_FILE("CNSmlDMHostSession::UpdateLeafOrExecuteLargeL(): begin");
+	ReadCmdParamsL ( aMessage );
+	CSmlDmAdapter* adapter = NULL;
+	for ( TInt i=0; i<iAdapters.Count(); i++ )
+		{
+		if ( iAdapters[i].adapterId == iAdapterId )
+			{
+			if ( !iAdapters[i].adapterPtr )
+				{
+				adapter = LoadNewAdapterL ( i, iAdapterId );
+				if ( !adapter )
+					{
+					User::Leave ( KErrArgument );								
+					}
+				}
+			if ( iStartAtomic && !iAdapters[i].startAtomicCalled )
+				{
+				iAdapters[i].startAtomicCalled = ETrue;
+				iAdapters[i].adapterPtr->StartAtomicL();
+				}				
+			if ( iAdapters[i].streamingLimit != KNSmlDmNotSupported )
+				{
+				CheckIfCorrectAdapterL();
+				if ( !iLargeWriteStream.streamPtr )
+					{
+					// FOTA
+					if ( iAdapterId == KNSmlDMFotaAdapterImplUid && aCommand == ENSmlDMUpdateLeafLarge )
+						{
+						// Call overloaded function of the FOTA adapter to tell the 
+						// total size of incoming large object.
+						// Note that in this context the third parameter holds the size
+						// information. Otherwise it contains the 'last package' information.
+						TInt totSizeOfLarge ( aMessage.Int2() );
+						iAdapters[i].adapterPtr->StreamingSupport ( totSizeOfLarge );
+						if ( totSizeOfLarge == KErrNoMemory )
+							{
+							User::Leave ( KErrTooBig );						
+							}
+						}					
+					// FOTA end
+					iLargeWriteStream.adapterId = iAdapterId;
+					CallAdapterCommandL ( aCommand, i, iLargeWriteStream.streamPtr );
+					if ( !iLargeWriteStream.streamPtr )
+						{
+						User::Leave ( KErrGeneral );						
+						}
+					iCommitStatus.iStreamingOngoing=ETrue;
+					iCommitStatus.iOldStatusRef = iStatusRef;
+					}
+				iLargeWriteStream.streamPtr->WriteL ( *iData );
+				iCommitStatus.iNewStatusRef = iStatusRef;
+				// FOTA
+				if ( aMessage.Int2() == KNSmlDmLastPackage )  //  Last package (TBool)
+				// FOTA end
+					{
+					iLargeWriteStream.streamPtr->Close();
+					iLargeWriteStream.streamPtr = NULL;									
+					iCommitStatus.iStreamCommitted = ETrue;
+					iAdapters[i].adapterPtr->StreamCommittedL();
+				    iCommitStatus.iStreamCommitted=EFalse;
+        		    iCommitStatus.iStreamingOngoing=EFalse;
+					}
+				TPckgBuf<TInt> cb = ( iCallbackList.Count() ) ? iCallbackList[0].callBack : ENSmlDmCallbackNone;
+				aMessage.WriteL ( 3, cb );
+				}
+			else 
+				{
+				UpdateOrExecuteLargeNoStreamL ( aMessage, i, aCommand );
+				}
+			return;
+			}
+		}
+	User::Leave ( KErrArgument );
+	_DBG_FILE("CNSmlDMHostSession::UpdateLeafOrExecuteLargeL(): end");
+	}
+
+// ------------------------------------------------------------------------------------------------
+// CNSmlDMHostSession::UpdateOrExecuteLargeNoStreamL
+//	Auxiliary function of UpdateLeafOrExecuteLargeL.
+//	Provided the dm plug-in adapter doesn't support streaming, this function
+//	takes care of appending large object piece by piece.
+//	When the last package arrives, calls the adapter and gives the built-up 
+//	large object as a parameter.
+//	@param aMessage. An object which encapsulates a client request. 
+//	@param aAdIndex. Identifies the assigned adapter. 
+//	@param aCommand. Needed to choose between Update and Execute commands. 
+// ------------------------------------------------------------------------------------------------
+//
+void CNSmlDMHostSession::UpdateOrExecuteLargeNoStreamL ( const RMessage2& aMessage, TInt aAdIndex, TNSmlDmHostOperationCodes aCommand )
+	{
+	_DBG_FILE("CNSmlDMHostSession::UpdateOrExecuteLargeNoStreamL(): begin");
+
+	if ( !iLargeObject )
+		{
+		iLargeObject = HBufC8::NewL(0);
+		}
+	iLargeObject = iLargeObject->ReAllocL ( iLargeObject->Length() + iData->Length() );
+	TPtr8 tmpPtr = iLargeObject->Des();	
+	tmpPtr.Append ( *iData );
+	
+	if ( aMessage.Int2() )  //  Last package (TBool)
+		{					
+		CallAdapterCommandL ( aCommand, aAdIndex, ETrue );
+		delete iLargeObject;
+		iLargeObject = NULL;
+		}		
+	_DBG_FILE("CNSmlDMHostSession::UpdateOrExecuteLargeNoStreamL(): end");
+	}
+
+// ------------------------------------------------------------------------------------------------
+// CNSmlDMHostSession::AddCopyOrDeleteL
+//	Common function for handling Add Interior Node, Copy Node, or Delete Object DM commands.
+//	Reads parameters from the chunk.
+//	Loads the requested adapter if this is a first command to it in this session.
+//	Checks the need to inform adapter at atomic command situation.
+//	Informs the client (DM Tree Module) if there are unread statuses, results or mappings.
+//	@param aMessage. An object which encapsulates a client request. 
+//	@param aCommand. Needed to choose between Add, Copy, and Delete commands. 
+// ------------------------------------------------------------------------------------------------
+//
+void CNSmlDMHostSession::AddCopyOrDeleteL ( const RMessage2& aMessage, TNSmlDmHostOperationCodes aCommand )
+	{
+	_DBG_FILE("CNSmlDMHostSession::AddCopyOrDeleteL(): begin");
+	
+	if ( aCommand == ENSmlDMCopy )
+		{
+		ReadCopyCmdParamsL ( aMessage );			
+		}
+	else
+		{
+		ReadCmdParamsL ( aMessage );		
+		}
+	CSmlDmAdapter* adapter = NULL;
+	for ( TInt i=0; i<iAdapters.Count(); i++ )
+		{
+		if ( iAdapters[i].adapterId == iAdapterId )
+			{
+			if ( !iAdapters[i].adapterPtr )
+				{
+				adapter = LoadNewAdapterL ( i, iAdapterId );
+				if ( !adapter )
+					{
+					User::Leave ( KErrArgument );					
+					}
+				}
+			if ( iStartAtomic && !iAdapters[i].startAtomicCalled )
+				{
+				iAdapters[i].startAtomicCalled = ETrue;
+				iAdapters[i].adapterPtr->StartAtomicL();
+				}				
+			CallAdapterCommandL ( aCommand, i );
+			TPckgBuf<TInt> cb = ( iCallbackList.Count() ) ? iCallbackList[0].callBack : ENSmlDmCallbackNone;
+			aMessage.WriteL ( 3, cb );		
+			return;
+			}
+		}
+	User::Leave ( KErrArgument );
+	_DBG_FILE("CNSmlDMHostSession::AddCopyOrDeleteL(): end");
+	}
+
+// ------------------------------------------------------------------------------------------------
+// CNSmlDMHostSession::FetchLeafChildUrisOrSizeL
+//	Common function for handling Fetch Leaf Object, Get Child URI List, or Fetch Leaf Object Size 
+//	DM commands.
+//	Reads parameters from the chunk.
+//	Loads the requested adapter if this is a first command to it in this session.
+//	Checks the need to inform adapter at atomic command situation.
+//	Informs the client (DM Tree Module) if there are unread statuses, results or mappings.
+//	@param aMessage. An object which encapsulates a client request. 
+//	@param aCommand. Needed to choose between Fetch, Get Child URI List, and Fetch Size commands. 
+// ------------------------------------------------------------------------------------------------
+//
+void CNSmlDMHostSession::FetchLeafChildUrisOrSizeL ( const RMessage2& aMessage,  TNSmlDmHostOperationCodes aCommand )
+	{
+	_DBG_FILE("CNSmlDMHostSession::FetchLeafChildUrisOrSizeL(): begin");
+	RPointerArray<HBufC8> prevLuids;
+	CleanupStack::PushL ( PtrArrCleanupItemRArr ( HBufC8, &prevLuids ) );
+	ReadCmdFetchParamsL ( aMessage, prevLuids );
+	CSmlDmAdapter* adapter = NULL;
+	for ( TInt i=0; i<iAdapters.Count(); i++ )
+		{
+		if ( iAdapters[i].adapterId == iAdapterId )
+			{
+			if ( !iAdapters[i].adapterPtr )
+				{
+				adapter = LoadNewAdapterL ( i, iAdapterId );
+				if ( !adapter )
+					{
+					CleanupStack::PopAndDestroy();  // prevLuids
+					User::Leave ( KErrArgument );
+					}
+				}
+			if ( iStartAtomic && !iAdapters[i].startAtomicCalled )
+				{
+				iAdapters[i].startAtomicCalled = ETrue;
+				iAdapters[i].adapterPtr->StartAtomicL();
+				}
+			CallAdapterCommandL ( aCommand, i );
+			CleanupStack::PopAndDestroy();  // prevLuids					
+			TPckgBuf<TInt> cb = ( iCallbackList.Count() ) ? iCallbackList[0].callBack : ENSmlDmCallbackNone;
+			aMessage.WriteL ( 3, cb );
+			return;
+			}
+		}
+	CleanupStack::PopAndDestroy();  // prevLuids			
+	User::Leave ( KErrNotFound );
+	_DBG_FILE("CNSmlDMHostSession::FetchLeafChildUrisOrSizeL(): end");
+	}
+
+// ------------------------------------------------------------------------------------------------
+// CNSmlDMHostSession::FetchLinkL
+//	Called only from other DM Host Servers when they need to cross-reference AP -adapter. 
+//	Loads the AP dm plug in adapter (i.e. Internet adapter).
+//	Asks the DDF structure from the AP adapter.
+//	Checks that the given URI is found from the DDF structure.
+//	If the above actions are successful, calls the Fetch Leaf Object or Get Child URI List 
+//	commands of AP adapter.
+//	Writes the returned result to the chunk.
+//	@param aMessage. An object which encapsulates a client (other DM Host Server in this case) request. 
+// ------------------------------------------------------------------------------------------------
+//
+void CNSmlDMHostSession::FetchLinkL ( const RMessage2& aMessage )
+	{
+	_DBG_FILE("CNSmlDMHostSession::FetchLinkL(): begin");
+	
+	RPointerArray<HBufC8> versions;
+	CleanupStack::PushL ( PtrArrCleanupItemRArr ( HBufC8, &versions ) );
+	RArray<TInt32> uids;
+	CleanupClosePushL ( uids );
+	
+	CSmlDmAdapter* adapter = NULL;
+	TUid uid = { GetAccessPointImplUid() };
+	
+	adapter = CSmlDmAdapter::NewL ( uid, *this );
+	CleanupStack::PushL(adapter);
+	AskInfoFromAdapterL ( adapter, versions, uids, uid.iUid );		
+	CleanupStack::PopAndDestroy(3); // adapter, uids, versions 
+	
+	HBufC8* uri = HBufC8::NewLC ( aMessage.GetDesLengthL(0) );
+    TPtr8 uriPtr = uri->Des();
+    aMessage.ReadL ( 0, uriPtr, 0 );    
+	
+	CBufBase* buf = CBufFlat::NewL ( 16 );
+	CleanupStack::PushL ( buf );
+	MSmlDmAdapter::TError status = MSmlDmAdapter::EOk;
+
+	TUint32 adId(0);
+	TNSmlDmDDFFormat nodeType;
+	TBool adapterFound = AdapterIdFromUriL ( *uri, adId, nodeType );
+	if ( adapterFound )
+		{
+		FetchLinkFromAdapterL ( *uri, adId, *buf, status, nodeType );
+		}
+	if ( !adapterFound || status != MSmlDmAdapter::EOk )
+		{
+		CleanupStack::PopAndDestroy(2); // buf, uri	
+		User::Leave ( KErrNotFound );
+		}
+	
+	// Write answer
+	iChunk.Adjust ( 2 + buf->Size() );
+	RMemWriteStream writeStream ( iChunk.Base(), iChunk.Size() );
+	CleanupClosePushL ( writeStream );
+	writeStream.WriteUint16L ( buf->Size() );
+	writeStream.WriteL ( buf->Ptr(0) );
+	CleanupStack::PopAndDestroy(3); // writestream, buf, uri
+	_DBG_FILE("CNSmlDMHostSession::FetchLinkL(): end");
+	}
+
+// ------------------------------------------------------------------------------------------------
+// void CNSmlDMHostSession::StartAtomicL()
+//	Sets a general atomic command state. 
+//	When this state is set, StartAtomicL function of the adapters
+//	is called when the first 'normal' command arrives.
+//	In addition informs the client (DM Tree Module) if there are unread statuses, results or mappings.
+//	@param aMessage. An object which encapsulates a client request. 
+// ------------------------------------------------------------------------------------------------
+//
+void CNSmlDMHostSession::StartAtomicL ( const RMessage2& aMessage )
+	{
+	_DBG_FILE("CNSmlDMHostSession::StartAtomicL(): begin");	
+	iStartAtomic = ETrue;
+	TPckgBuf<TInt> cb = ( iCallbackList.Count() ) ? iCallbackList[0].callBack : ENSmlDmCallbackNone;
+	aMessage.WriteL ( 3, cb );
+	_DBG_FILE("CNSmlDMHostSession::StartAtomicL(): end");
+	}
+
+// ------------------------------------------------------------------------------------------------
+// void CNSmlDMHostSession::CommitAtomicL()
+//	Resets the general atomic command state (When atomic commands were successful). 
+//	This command is forwarded only to those adapters which have received StartAtomicL call.
+//	In addition informs the client (DM Tree Module) if there are unread statuses, results or mappings.
+//	@param aMessage. An object which encapsulates a client request. 
+// ------------------------------------------------------------------------------------------------
+//
+void CNSmlDMHostSession::CommitAtomicL ( const RMessage2& aMessage )
+	{
+	_DBG_FILE("CNSmlDMHostSession::CommitAtomicL(): begin");
+	iStartAtomic = EFalse;
+	for ( TInt i=0; i<iAdapters.Count(); i++ )
+		{
+		if ( iAdapters[i].startAtomicCalled && iAdapters[i].adapterPtr )
+			{
+			iAdapters[i].startAtomicCalled = EFalse;	
+			iAdapters[i].adapterPtr->CommitAtomicL();	
+			}
+		}
+	TPckgBuf<TInt> cb = ( iCallbackList.Count() ) ? iCallbackList[0].callBack : ENSmlDmCallbackNone;
+	aMessage.WriteL ( 3, cb );		
+	_DBG_FILE("CNSmlDMHostSession::CommitAtomicL(): end");
+	}
+
+// ------------------------------------------------------------------------------------------------
+// void CNSmlDMHostSession::RollbackAtomicL()
+//	Resets the general atomic command state (When one or more atomic commands failed). 
+//	This command is forwarded only to those adapters which have received StartAtomicL call.
+//	In addition informs the client (DM Tree Module) if there are unread statuses, results or mappings.
+//	@param aMessage. An object which encapsulates a client request. 
+// ------------------------------------------------------------------------------------------------
+//
+void CNSmlDMHostSession::RollbackAtomicL ( const RMessage2& aMessage )
+	{
+	_DBG_FILE("CNSmlDMHostSession::RollbackAtomicL(): begin");
+	iStartAtomic = EFalse;	
+	for ( TInt i=0; i<iAdapters.Count(); i++ )
+		{
+		if ( iAdapters[i].startAtomicCalled && iAdapters[i].adapterPtr )
+			{
+			iAdapters[i].startAtomicCalled = EFalse;	
+			iAdapters[i].adapterPtr->RollbackAtomicL();	
+			}
+		}
+	TPckgBuf<TInt> cb = ( iCallbackList.Count() ) ? iCallbackList[0].callBack : ENSmlDmCallbackNone;
+	aMessage.WriteL ( 3, cb );		
+	_DBG_FILE("CNSmlDMHostSession::RollbackAtomicL(): end");
+	}
+
+// ------------------------------------------------------------------------------------------------
+// void CNSmlDMHostSession::CompleteCommandsL()
+//	Calls CompleteOutstandingCmdsL -function of the DM plug-in adapters.
+//	This command is issued only to those adapters which have received some adapter 
+//	commands during the session.
+//	In addition informs the client (DM Tree Module) if there are unread statuses, results or mappings.
+//	@param aMessage. An object which encapsulates a client request. 
+// ------------------------------------------------------------------------------------------------
+//
+void CNSmlDMHostSession::CompleteCommandsL ( const RMessage2& aMessage )
+	{	
+	_DBG_FILE("CNSmlDMHostSession::CompleteCommandsL(): begin");
+	for ( TInt i=0; i<iAdapters.Count(); i++ )
+		{
+		if ( iAdapters[i].commandsCalled && iAdapters[i].adapterPtr )
+			{
+			iAdapters[i].commandsCalled = EFalse;	
+			iAdapters[i].adapterPtr->CompleteOutstandingCmdsL();
+			}
+		}
+	TPckgBuf<TInt> cb = ( iCallbackList.Count() ) ? iCallbackList[0].callBack : ENSmlDmCallbackNone;
+	aMessage.WriteL ( 3, cb );		
+	_DBG_FILE("CNSmlDMHostSession::CompleteCommandsL(): end");
+	}
+
+// ------------------------------------------------------------------------------------------------
+// CNSmlDMHostSession::SetChunkHandleL
+//	Sets a handle to the global memory chunk. 
+//	The chunk is a common data area between the client (DM Tree Module) and the server
+//	(DM Host Server).
+//	Additionally, a server id is sent in the message.
+//	This id tells to the (common) session class which server session is serving.  
+//	@param aMessage. An object which encapsulates a client request. 
+// ------------------------------------------------------------------------------------------------
+//
+void CNSmlDMHostSession::SetChunkHandleL ( const RMessage2& aMessage )
+	{
+	_DBG_FILE("CNSmlDMHostSession::SetChunkHandleL(): begin");
+	iOwnId = aMessage.Int1();
+	iChunk.Close();
+	TInt err=iChunk.Open ( aMessage, 0, EFalse );	
+	if(err != KErrNone)
+	{
+		User::Leave (err);		
+	}
+	if ( iChunk.MaxSize() <= KNSmlDmChunkMarginal )
+		{
+		User::Leave ( KErrGeneral );		
+		}
+	_DBG_FILE("CNSmlDMHostSession::SetChunkHandleL(): end");
+	}
+
+// ------------------------------------------------------------------------------------------------
+// CNSmlDMHostSession::GetMappingsL
+//	Gets the URI / Luid mappings which have been received from the dm adapters 
+//	via callback function calls. 
+//	These mappings are buffered by the session class, and - during this call,
+//	all written to the chunk at once.
+//	Additionally informs the client (DM Tree Module) if there are also unread statuses or results.
+//	@param aMessage. An object which encapsulates a client request. 
+// ------------------------------------------------------------------------------------------------
+//
+void CNSmlDMHostSession::GetMappingsL ( const RMessage2& aMessage )
+	{
+	_DBG_FILE("CNSmlDMHostSession::GetMappingsL(): begin");
+	if ( !iMapUris || !iMapLuids )
+		{
+		User::Leave ( KErrNotFound );		
+		}
+	
+	iChunk.Adjust ( SizeOfMappings() );
+	RMemWriteStream writeStream ( iChunk.Base(), iChunk.Size() );
+	CleanupClosePushL ( writeStream );
+	NSmlDmCmdArgHandler::PacketMappingsL ( writeStream, *iMapUris, *iMapLuids );			
+	
+	iMapUris->ResetAndDestroy();
+	delete iMapUris;
+	iMapUris = NULL;
+	iMapLuids->ResetAndDestroy();
+	delete iMapLuids;
+	iMapLuids = NULL;
+	for ( TInt i=0; i<iCallbackList.Count(); i++ )
+		{
+		if ( iCallbackList[i].callBack == ENSmlDmCallbackMappings )
+			{
+			iCallbackList.Remove(i);
+			i--;				
+			}
+		}
+	TPckgBuf<TInt> cb = ( iCallbackList.Count() ) ? iCallbackList[0].callBack : ENSmlDmCallbackNone;
+	aMessage.WriteL ( 3, cb );	
+	CleanupStack::PopAndDestroy();  // writeStream	
+	_DBG_FILE("CNSmlDMHostSession::GetMappingsL(): end");
+	}
+
+// ------------------------------------------------------------------------------------------------
+// CNSmlDMHostSession::GetStatusesL
+//	Gets the DM command statuses received from the dm adapters via callback function calls. 
+//	These statuse are buffered by the session class, and - during this call,
+//	all written to the chunk at once.
+//	Additionally informs the client (DM Tree Module) if there are also unread mappings or results.
+//	@param aMessage. An object which encapsulates a client request. 
+// ------------------------------------------------------------------------------------------------
+//
+void CNSmlDMHostSession::GetStatusesL ( const RMessage2& aMessage )
+	{
+	_DBG_FILE("CNSmlDMHostSession::GetStatusesL(): begin");
+	if ( !iStatusCodeList.Count() )
+		{
+		User::Leave ( KErrNotFound );		
+		}
+
+	iChunk.Adjust ( SizeOfStatuses() );
+	RMemWriteStream writeStream ( iChunk.Base(), iChunk.Size() );
+	CleanupClosePushL ( writeStream );
+	NSmlDmCmdArgHandler::PacketStatusesL ( writeStream, iStatusCodeList );			
+	
+	iStatusCodeList.Close();
+	
+	for ( TInt i=0; i<iCallbackList.Count(); i++ )
+		{
+		if ( iCallbackList[i].callBack == ENSmlDmCallbackStatuses )
+			{
+			iCallbackList.Remove(i);
+			i--;			
+			}
+		}
+	
+	TPckgBuf<TInt> cb = ( iCallbackList.Count() ) ? iCallbackList[0].callBack : ENSmlDmCallbackNone;
+	aMessage.WriteL ( 3, cb );	
+	CleanupStack::PopAndDestroy();  // writeStream
+	_DBG_FILE("CNSmlDMHostSession::GetStatusesL(): end");
+	}
+
+// ------------------------------------------------------------------------------------------------
+// CNSmlDMHostSession::GetResultsL
+//	Gets the DM command results received from the dm adapters via callback function calls.
+//	In practice, these are the results from the 'FetchLeafObject', 'FecthLeafObjectSize', 
+//	and 'GetChildURIList' commands.
+//	The results are all written to the chunk at once if they just fit there.
+//	In case of large objects the result item is cut into pieces by writing one 'chunkfull' at time.
+//	Informs the client (DM Tree Module) if the result is cut up and needs thus additional 
+//	GetResultsL -function calls. Additionally, informs the client if there are unread mappings 
+//	or statuses.
+//	@param aMessage. An object which encapsulates a client request. 
+// ------------------------------------------------------------------------------------------------
+//
+void CNSmlDMHostSession::GetResultsL ( const RMessage2& aMessage )
+	{
+	_DBG_FILE("CNSmlDMHostSession::GetResultsL(): begin");
+	TInt okToWrite(0);
+	TInt adjustChunkSize(0);	
+	TInt largeTotSize(0);
+	TNSmlDmResultAnalysis conclusion = AnalyzeResultList ( okToWrite, adjustChunkSize );
+	
+	iChunk.Adjust ( adjustChunkSize );
+	RMemWriteStream writeStream ( iChunk.Base(), iChunk.Size() );
+	CleanupClosePushL ( writeStream );
+	
+	if ( conclusion == ENSmlDmAllWillFit )
+		{
+		NSmlDmCmdArgHandler::PacketResultsL ( writeStream, iResultList );			
+		RemoveResultCallbacksL ( iResultList.Count() );
+		}
+	else if ( conclusion == ENSmlDmSomeWillFit )
+		{
+		RPointerArray<CNSmlDmResultElement> someResults;
+		CleanupClosePushL ( someResults );
+		for ( TInt i(0); i<okToWrite; i++ )
+			{
+			someResults.Append ( iResultList[i] );			
+			}
+		NSmlDmCmdArgHandler::PacketResultsL ( writeStream, someResults );
+		CleanupStack::PopAndDestroy();  // someResults
+		RemoveResultCallbacksL ( okToWrite );
+		}
+	else if ( conclusion == ENSmlDmStreamed )
+		{
+		if ( !iResultList[0]->iStreamed )
+			{
+			User::Leave ( KErrGeneral );			
+			}
+		
+		RPointerArray<CNSmlDmResultElement> result;
+		CleanupClosePushL ( result );
+		result.Append ( iResultList[0] );			
+		NSmlDmCmdArgHandler::PacketResultsL ( writeStream, result );
+
+		largeTotSize = iResultReadStream->Source()->SizeL();
+		TInt leftToRead = largeTotSize - iResultOffset;
+		TInt available = RoomForLargeData ( *iResultList[0]->iMimeType );
+		delete iResultList[0]->iResult;
+		iResultList[0]->iResult = NULL;
+
+		RBufWriteStream writeBufStream;
+		CleanupClosePushL ( writeBufStream );
+		if ( leftToRead > available )
+			{
+			iResultList[0]->iResult = CBufFlat::NewL ( available );
+			writeBufStream.Open ( *iResultList[0]->iResult );
+			iResultReadStream->ReadL ( writeBufStream, available );
+			iResultOffset += available;
+			}
+		else
+			{
+			iResultList[0]->iResult = CBufFlat::NewL ( leftToRead );
+			writeBufStream.Open ( *iResultList[0]->iResult );
+			iResultReadStream->ReadL ( writeBufStream, leftToRead );
+			iResultReadStream->Close();
+			iResultList[0]->iStreamed = EFalse;
+			iResultReadStream = NULL;
+			iResultOffset = 0;
+			}
+		CleanupStack::PopAndDestroy ( 2 );  // writeBufStream, result
+		}
+	else if ( conclusion == ENSmlDmLargeDoesntFit )
+		{
+		largeTotSize = iResultList[0]->iResult->Size();
+		TInt available = iChunk.Size() - KNSmlDmChunkMarginal;
+		CBufBase* newBuffer = CBufFlat::NewL ( available );
+		CleanupStack::PushL ( newBuffer );
+		newBuffer->InsertL ( 0, iResultList[0]->iResult->Ptr(0).Left ( available ) );
+		
+		CBufBase* oldBuffer = iResultList[0]->iResult;
+		iResultList[0]->iResult = newBuffer;
+				
+		RPointerArray<CNSmlDmResultElement> truncResult;
+		CleanupClosePushL ( truncResult );
+		truncResult.Append ( iResultList[0] );			
+		NSmlDmCmdArgHandler::PacketResultsL ( writeStream, truncResult );
+		
+		CleanupStack::PopAndDestroy(2);  // truncResult, newBuffer
+		oldBuffer->Delete ( 0, available );
+		iResultList[0]->iResult = oldBuffer;
+		}
+	
+	CleanupStack::PopAndDestroy();  // writeStream
+	TPckgBuf<TInt> cb;
+	if ( conclusion == ENSmlDmStreamed || conclusion == ENSmlDmLargeDoesntFit )
+		{
+		cb = ENSmlDmCallbackChunkFull;
+		TPckgBuf<TInt> totalSize ( largeTotSize );
+		aMessage.Write ( 2, totalSize );		
+		}
+	else 
+		{
+		cb = ( iCallbackList.Count() ) ? iCallbackList[0].callBack : ENSmlDmCallbackNone;		
+		}
+	aMessage.WriteL ( 3, cb );	
+		
+	_DBG_FILE("CNSmlDMHostSession::GetResultsL(): end");
+	}
+
+// ------------------------------------------------------------------------------------------------
+// CNSmlDMHostSession::AnalyzeResultList
+//	Auxiliary function called by GetResultsL.
+//	This function analyzes whether all the results will fit into the chunk
+//	or not. 
+//	@param aOkToWrite. A reference parameter which is used only in case of
+//	                  'some will fit' for telling how many results can be
+//	                   written at once.
+//	@param aAdjustChunkSize. A reference parameter for adjusting the chunk to 
+//	    				     adequate size before writing takes place.
+//	@return TNSmlDmResultAnalysis. Possible return values are: 1) 'all will fit',
+//	                               2) 'some will fit', 3) 'large object (streamed) -
+//	     						   won't fit', and 4) 'large object (not streamed)
+//	 							   - won't fit'.
+// ------------------------------------------------------------------------------------------------
+//
+CNSmlDMHostSession::TNSmlDmResultAnalysis CNSmlDMHostSession::AnalyzeResultList ( TInt& aOkToWrite, TInt& aAdjustChunk  )
+	{
+	TInt occupied(2);  // 2 = count 16bits
+	for ( TInt i(0); i<iResultList.Count(); i++ )
+		{
+		occupied += ResultItemSize ( i );
+		TInt maximum ( KNSmlDmHostChunkMaxSize - KNSmlDmChunkMarginal );
+		if (  occupied <= maximum )
+			{
+			aOkToWrite++;
+			if ( iResultList[i]->iStreamed )
+				{
+				aAdjustChunk = KNSmlDmHostChunkMaxSize;				
+				return ENSmlDmStreamed;
+				}
+			}
+		else 
+			{
+			if ( aOkToWrite )
+				{
+				aAdjustChunk = occupied - ResultItemSize(i);				
+				return ENSmlDmSomeWillFit;
+				}
+			else
+				{
+				aAdjustChunk = KNSmlDmHostChunkMaxSize;				
+				return ENSmlDmLargeDoesntFit;			
+				}
+			}
+		}
+	aAdjustChunk = occupied;
+	return ENSmlDmAllWillFit;
+	}
+
+
+// ------------------------------------------------------------------------------------------------
+// CNSmlDMHostSession::RemoveResultCallbacksL
+//	Auxiliary function for removing the 'read' results from the internal list.
+//	This function is called from GetResultsL after some (or all) results 
+//	are written to the chunk. 
+//	@param aNumber. The number of the results which are needed to be 
+//	  			    removed from the internal list.
+// ------------------------------------------------------------------------------------------------
+//
+void CNSmlDMHostSession::RemoveResultCallbacksL ( TInt aNumber )
+	{
+	if ( aNumber > iCallbackList.Count() || aNumber > iResultList.Count() || aNumber < 0 )
+		{
+		User::Leave ( KErrGeneral );		
+		}
+	
+	for ( TInt i(0); i<aNumber; i++ )
+		{
+		for ( TInt u(0); u<iCallbackList.Count(); u++ )
+			{
+			if ( iCallbackList[u].callBack == ENSmlDmCallbackResults )
+				{
+				iCallbackList.Remove(u);
+				break;				
+				}
+			}
+		delete iResultList[0];
+		iResultList.Remove(0);
+		}
+	}
+
+// ------------------------------------------------------------------------------------------------
+// CNSmlDMHostSession::LoadNewAdapterL
+//	Auxiliary function called by the command handling functions (e.g. AddCopyOrDeleteL).
+//	Loads the ECom plug-in Dm Adapter.
+//	The adapter is identified with the given implementation UID.
+//	@param aIndex. A place in the internal list where the adpater pointer is stored. 
+//	@param aAdapterId. The implementation UID of the requested DM adapter. 
+//	@return CSmlDmAdapter*. New instance of the ECom plug-in DM adapter.
+// ------------------------------------------------------------------------------------------------
+//
+CSmlDmAdapter* CNSmlDMHostSession::LoadNewAdapterL ( TInt aIndex, TUint32 aAdapterId )
+	{
+	_DBG_FILE("CNSmlDMHostSession::LoadNewAdapterL(): begin");	
+	CSmlDmAdapter* adapter = NULL;
+	TUid uid = { aAdapterId };
+	adapter = CSmlDmAdapter::NewL ( uid, *this );
+	iAdapters[aIndex].adapterPtr = adapter;
+	_DBG_FILE("CNSmlDMHostSession::LoadNewAdapterL(): end");	
+	return adapter;
+	}
+
+// ------------------------------------------------------------------------------------------------
+// CNSmlDMHostSession::ReadCmdParamsL
+//	Auxiliary function called by the command handling functions (e.g. UpdateLeafOrExecuteL).
+//	Reads the DM command parameters from the message and from the chunk.
+//	Utilizes the DM Utils services for parsing data in the chunk.
+//	@param aMessage. An object which encapsulates a client request. 
+// ------------------------------------------------------------------------------------------------
+//
+void CNSmlDMHostSession::ReadCmdParamsL ( const RMessage2& aMessage )
+	{
+	_DBG_FILE("CNSmlDMHostSession::ReadCmdParamsL(): begin");
+	DeletePrevParams();
+	RMemReadStream readStream ( iChunk.Base(), iChunk.Size() );
+	CleanupClosePushL ( readStream );
+	NSmlDmCmdArgHandler::ParseDataL ( readStream, iLuid, iData, iUri, iType );
+	iAdapterId = aMessage.Int0();
+	iStatusRef = aMessage.Int1();
+	CleanupStack::PopAndDestroy();	// readStream	
+	_DBG_FILE("CNSmlDMHostSession::ReadCmdParamsL(): end");
+	}
+
+// ------------------------------------------------------------------------------------------------
+// CNSmlDMHostSession::ReadCmdFetchParamsL
+//	Auxiliary function called by the FetchLeafChildUrisOrSizeL.
+//	Reads the DM command parameters from the message and from the chunk.
+//	Utilizes the DM Utils services for parsing data in the chunk.
+//	@param aMessage. An object which encapsulates a client request. 
+//	@param aPreviousLuids. A reference parameter, needed for freeing the reserved 
+//	                       heap memory when the luids can be destroyed. 
+// ------------------------------------------------------------------------------------------------
+//
+void CNSmlDMHostSession::ReadCmdFetchParamsL ( const RMessage2& aMessage, RPointerArray<HBufC8>& aPreviousLuids )
+	{
+	_DBG_FILE("CNSmlDMHostSession::ReadCmdFetchParamsL(): begin");	
+	DeletePrevParams();
+	RMemReadStream readStream ( iChunk.Base(), iChunk.Size() );
+	CleanupClosePushL ( readStream );
+	iPrevSegURIList = new (ELeave) CArrayFixFlat<TSmlDmMappingInfo>(KNSmlDmGranularity);
+	NSmlDmCmdArgHandler::ParseFetchArgumentsL ( readStream, iLuid, iUri, iType, *iPrevSegURIList, aPreviousLuids );
+	iAdapterId = aMessage.Int0();
+	iStatusRef = aMessage.Int1();
+	iResultRef = aMessage.Int2();
+	CleanupStack::PopAndDestroy();	// readStream	
+	_DBG_FILE("CNSmlDMHostSession::ReadCmdFetchParamsL(): end");
+	}
+
+// ------------------------------------------------------------------------------------------------
+// CNSmlDMHostSession::ReadCopyCmdParamsL
+//	Auxiliary function called by the AddCopyOrDeleteL.
+//	Reads the DM command parameters from the message and from the chunk.
+//	Utilizes the DM Utils services for parsing data in the chunk.
+//	@param aMessage. An object which encapsulates a client request. 
+// ------------------------------------------------------------------------------------------------
+//
+void CNSmlDMHostSession::ReadCopyCmdParamsL ( const RMessage2& aMessage )
+	{
+	_DBG_FILE("CNSmlDMHostSession::ReadCopyCmdParamsL(): begin");
+	DeletePrevParams();
+	RMemReadStream readStream ( iChunk.Base(), iChunk.Size() );
+	CleanupClosePushL ( readStream );
+	NSmlDmCmdArgHandler::ParseCopyArgumentsL ( readStream, iTargetLuid, iTargetURI, iLuid, iUri, iType );
+	iAdapterId = aMessage.Int0();
+	iStatusRef = aMessage.Int1();
+	CleanupStack::PopAndDestroy();	// readStream	
+	_DBG_FILE("CNSmlDMHostSession::ReadCopyCmdParamsL(): end");
+	}
+
+// ------------------------------------------------------------------------------------------------
+// CNSmlDMHostSession::DeletePrevParams
+//	Auxiliary function for deleting previous set of DM command parameters.
+// ------------------------------------------------------------------------------------------------
+//
+void CNSmlDMHostSession::DeletePrevParams()
+	{
+	_DBG_FILE("CNSmlDMHostSession::DeletePrevParams(): begin");	
+	delete iLuid;
+	iLuid = NULL;
+	delete iUri;
+	iUri = NULL;
+	delete iData;
+	iData = NULL;
+	delete iType;
+	iType = NULL;
+	delete iTargetLuid;
+	iTargetLuid = NULL;
+	delete iTargetURI;
+	iTargetURI = NULL;
+    if ( iPrevSegURIList )
+    	{
+    	iPrevSegURIList->Reset();    	
+    	}
+    delete iPrevSegURIList;
+    iPrevSegURIList = NULL;
+	_DBG_FILE("CNSmlDMHostSession::DeletePrevParams(): end");	
+	}
+
+// ------------------------------------------------------------------------------------------------
+// CNSmlDMHostSession::CheckIfCorrectAdapterL
+//	Auxiliary function called by the UpdateLeafOrExecuteLargeL.
+//	Checks that the arrived command is not to different adapter,
+//	during the large object update to the other. 
+// ------------------------------------------------------------------------------------------------
+//
+void CNSmlDMHostSession::CheckIfCorrectAdapterL() const
+	{
+	_DBG_FILE("CNSmlDMHostSession::CheckIfCorrectAdapterL(): begin");	
+	if ( iLargeWriteStream.streamPtr && iLargeWriteStream.adapterId != iAdapterId )
+		{
+		User::Leave ( KErrArgument );		
+		}
+	_DBG_FILE("CNSmlDMHostSession::CheckIfCorrectAdapterL(): end");	
+	}
+
+// ------------------------------------------------------------------------------------------------
+// CNSmlDMHostSession::CallAdapterCommandL
+//	Auxiliary function called by the the command handling functions, 
+//	when the streaming is not used.
+//	Calls the chosen DM adapter function of the given adapter.
+//	The function parameters are set from the internal member variables.
+//	@param aCommand. Identifies the chosen adapter command. 
+//	@param aAdIndex. Identifies the chosen DM plug-in adapter. 
+//	@param aLargeObject. If the data is a large object, a different 
+//	                     internal variable is chosen. 
+// ------------------------------------------------------------------------------------------------
+//
+void CNSmlDMHostSession::CallAdapterCommandL ( TNSmlDmHostOperationCodes aCommand, TInt aAdIndex, TBool aLargeObject )
+	{
+	_DBG_FILE("CNSmlDMHostSession::CallAdapterCommandL(): begin");
+	iAdapters[aAdIndex].commandsCalled = ETrue;
+	switch ( aCommand ) 
+		{
+		case ENSmlDMAddNode:
+			iAdapters[aAdIndex].adapterPtr->AddNodeObjectL ( *iUri, *iLuid, iStatusRef );				
+			break;
+		case ENSmlDMCopy:
+			iAdapters[aAdIndex].adapterPtr->CopyCommandL ( *iTargetURI, *iTargetLuid, *iUri, *iLuid, *iType, iStatusRef );
+			break;
+		case ENSmlDMDelete:
+			iAdapters[aAdIndex].adapterPtr->DeleteObjectL ( *iUri, *iLuid, iStatusRef );			
+			break;
+		case ENSmlDMFetchLeaf:
+			iAdapters[aAdIndex].adapterPtr->FetchLeafObjectL ( *iUri, *iLuid, *iType, iResultRef, iStatusRef );
+			break;	
+		case ENSmlDMChildUriList:
+			iAdapters[aAdIndex].adapterPtr->ChildURIListL ( *iUri, *iLuid, *iPrevSegURIList, iResultRef, iStatusRef );
+			break;
+		case ENSmlDMFetchLeafSize:
+			iAdapters[aAdIndex].adapterPtr->FetchLeafObjectSizeL ( *iUri, *iLuid, *iType, iResultRef, iStatusRef );
+			break;
+		case ENSmlDMUpdateLeaf:
+		case ENSmlDMUpdateLeafLarge:
+			if ( !aLargeObject )
+				{
+				iAdapters[aAdIndex].adapterPtr->UpdateLeafObjectL ( *iUri, *iLuid, *iData, *iType, iStatusRef );				
+				}
+			else
+				{
+				iAdapters[aAdIndex].adapterPtr->UpdateLeafObjectL ( *iUri, *iLuid, *iLargeObject, *iType, iStatusRef );				
+				}			
+			break;
+		case ENSmlDMExecute:
+		case ENSmlDMExecuteLarge:
+			if ( !aLargeObject )
+				{
+				iAdapters[aAdIndex].adapterPtr->ExecuteCommandL ( *iUri, *iLuid, *iData, *iType, iStatusRef );
+				}
+			else
+				{
+				iAdapters[aAdIndex].adapterPtr->ExecuteCommandL ( *iUri, *iLuid, *iLargeObject, *iType, iStatusRef );				
+				}
+			break;
+		default:
+			User::Leave ( KErrNotSupported );			
+		}
+	_DBG_FILE("CNSmlDMHostSession::CallAdapterCommandL(): end");
+	}
+
+// ------------------------------------------------------------------------------------------------
+// CNSmlDMHostSession::CallAdapterCommandL
+//	Auxiliary function called by the the command handling functions, 
+//	when the streaming is used.
+//	Calls the chosen DM adapter function of the given adapter.
+//	The function parameters are set from the internal member variables.
+//	@param aCommand. Identifies the chosen adapter command. 
+//	@param aAdIndex. Identifies the chosen DM plug-in adapter. 
+//	@param aWriteStream. A reference parameter. The adapter sets this parameter to point
+//	                     to the correct place. 
+// ------------------------------------------------------------------------------------------------
+//
+void CNSmlDMHostSession::CallAdapterCommandL ( TNSmlDmHostOperationCodes aCommand, TInt aAdIndex, RWriteStream*& aWriteStream )
+	{
+	_DBG_FILE("CNSmlDMHostSession::CallAdapterCommandL( writeStream ): begin");
+	iAdapters[aAdIndex].commandsCalled = ETrue;	
+	switch ( aCommand )
+		{
+		case ENSmlDMUpdateLeaf:
+		case ENSmlDMUpdateLeafLarge:
+			iAdapters[aAdIndex].adapterPtr->UpdateLeafObjectL ( *iUri, *iLuid, aWriteStream, *iType, iStatusRef );
+			break;
+		case ENSmlDMExecute:
+		case ENSmlDMExecuteLarge:
+			iAdapters[aAdIndex].adapterPtr->ExecuteCommandL ( *iUri, *iLuid, aWriteStream, *iType, iStatusRef );
+			break;		
+		default:
+			User::Leave ( KErrNotSupported );
+		}
+
+	_DBG_FILE("CNSmlDMHostSession::CallAdapterCommandL( writeStream ): end");
+	}
+
+// ------------------------------------------------------------------------------------------------
+// CNSmlDMHostSession::ResultItemSize
+//	Auxiliary function for calculating how much memory does one particular result item reserve.
+//	This function is called from AnalyzeResultList. 
+//	@param aIndex. The place of the item in the internal result list.
+//	@return TInt. Needed memory area in bytes for the given result item.
+// ------------------------------------------------------------------------------------------------
+//
+inline TInt CNSmlDMHostSession::ResultItemSize ( TInt aIndex )
+	{
+	_DBG_FILE("CNSmlDMHostSession::ResultItemSize: begin");
+	// (iResultRef=2bytes) + (iResult->Size=4) + (iResult) + (iMimeType->Lenght=2) + (iMimeType)
+	TInt bytes = iResultList[aIndex]->iResult->Size() + iResultList[aIndex]->iMimeType->Size() + KNSmlDmConstItemSize;
+	_DBG_FILE("CNSmlDMHostSession::ResultItemSize: end");
+	return bytes;
+	}
+
+// ------------------------------------------------------------------------------------------------
+// CNSmlDMHostSession::SizeOfMappings
+//	Auxiliary function for calculating how much memory do the mappings need.
+//	This function is called from GetMappingsL in order to adjust the chunk 
+//	to adequate size before the mappings are written to the chunk. 
+//	@return TInt. Needed memory area in bytes for all the unread mappings.
+// ------------------------------------------------------------------------------------------------
+//
+TInt CNSmlDMHostSession::SizeOfMappings()
+	{
+	_DBG_FILE("CNSmlDMHostSession::SizeOfMappings: begin");
+	TInt bytes(2);  // 2 = count 16bits
+	for ( TInt i(0); i<iMapUris->Count(); i++ )
+		{
+		bytes += 2 + iMapUris->At(i)->Size() + 2 + iMapLuids->At(i)->Size();
+		}
+	_DBG_FILE("CNSmlDMHostSession::SizeOfMappings: end");
+	return bytes;
+	}
+
+// ------------------------------------------------------------------------------------------------
+// CNSmlDMHostSession::SizeOfStatuses
+//	Auxiliary function for calculating how much memory do the arrived statuse need.
+//	This function is called from GetStatusesL in order to adjust the chunk 
+//	to adequate size before the statuses are written to the chunk. 
+//	@return TInt. Needed memory area in bytes for all the unread statuses.
+// ------------------------------------------------------------------------------------------------
+//
+TInt CNSmlDMHostSession::SizeOfStatuses() const
+	{
+	_DBG_FILE("CNSmlDMHostSession::SizeOfStatuses: begin");
+	TInt bytes(2);  // 2 = count 16 bits
+	for ( TInt i(0); i<iStatusCodeList.Count(); i++ )
+		{
+		bytes += 2 + 1;		
+		}
+	_DBG_FILE("CNSmlDMHostSession::SizeOfStatuses: end");
+	return bytes;
+	}
+
+
+
+// ------------------------------------------------------------------------------------------------
+// Callbacks from the dm adapters
+// ------------------------------------------------------------------------------------------------
+
+// ------------------------------------------------------------------------------------------------
+// CNSmlDMHostSession::SetResultsL
+//	MSmlDmCallback - callback interface.
+// 	For returning fetch results from dm plug-in adapters.
+//	@param aResultsRef. Reference to correct command.
+//	@param aObject. The data which should be returned.
+//	@param aType. MIME type of the object.
+// ------------------------------------------------------------------------------------------------
+//
+void CNSmlDMHostSession::SetResultsL ( TInt aResultsRef, CBufBase& aObject, const TDesC8& aType )
+	{
+	_DBG_FILE("CNSmlDMHostSession::SetResultsL ( CBufBase ): begin");
+	
+	if ( !iFetchLinkResult )
+		{
+		TNSmlDmCallbackRef newCallback;
+		newCallback.callBack = ENSmlDmCallbackResults;
+		newCallback.reference = aResultsRef;
+
+		CNSmlDmResultElement* newResult = new (ELeave) CNSmlDmResultElement;
+		CleanupStack::PushL ( newResult );
+		newResult->iResultRef = aResultsRef;
+		newResult->iResult = CBufFlat::NewL ( aObject.Size() );
+		newResult->iResult->InsertL ( 0, aObject.Ptr(0), aObject.Size() );
+		newResult->iMimeType = aType.AllocL();
+		if ( iResultList.Append ( newResult ) == KErrNone )
+			{
+			CleanupStack::Pop();  // newResult
+			if ( iCallbackList.Append ( newCallback ) != KErrNone )
+				{
+				delete iResultList[iResultList.Count()-1];
+				iResultList.Remove(iResultList.Count()-1);
+				}
+			}
+		else
+			{
+			CleanupStack::PopAndDestroy();  // newResult			
+			}
+		}
+	else
+		{
+		delete iResultOtherAdapter;
+		iResultOtherAdapter = NULL;
+		iResultOtherAdapter = aObject.Ptr(0).AllocL();
+		}
+	_DBG_FILE("CNSmlDMHostSession::SetResultsL ( CBufBase ): end");
+	}
+
+// ------------------------------------------------------------------------------------------------
+// CNSmlDMHostSession::SetResultsL
+//	MSmlDmCallback - callback interface.
+// 	For returning fetch results from dm plug-in adapters (using streaming).
+//	@param aResultsRef. Reference to correct command.
+//	@param aStream. Large data which should be returned.
+//	@param aType. MIME type of the object.
+// ------------------------------------------------------------------------------------------------
+//
+void CNSmlDMHostSession::SetResultsL ( TInt aResultsRef, RReadStream*& aStream, const TDesC8& aType )
+	{
+	_DBG_FILE("CNSmlDMHostSession::SetResultsL ( RReadStream ): begin");
+	if ( !iFetchLinkResult )
+		{	
+		iResultReadStream = NULL;
+		iResultOffset = 0;
+	
+		TNSmlDmCallbackRef newCallback;
+		newCallback.callBack = ENSmlDmCallbackResults;
+		newCallback.reference = aResultsRef;
+
+		CNSmlDmResultElement* newResult = new (ELeave) CNSmlDmResultElement;
+		CleanupStack::PushL ( newResult );
+		newResult->iResultRef = aResultsRef;
+		newResult->iMimeType = aType.AllocL();
+	
+		TInt available = RoomForLargeData ( aType );
+	
+		RBufWriteStream writeStream;
+		CleanupClosePushL ( writeStream );
+		if ( aStream->Source()->SizeL() >  available )
+			{
+			newResult->iStreamed = ETrue;
+			iResultReadStream = aStream;
+			newResult->iResult = CBufFlat::NewL ( available );
+			writeStream.Open ( *newResult->iResult );
+			aStream->ReadL ( writeStream, available );
+			iResultOffset = available;
+			}
+		else
+			{
+			newResult->iResult = CBufFlat::NewL ( aStream->Source()->SizeL() );
+			writeStream.Open ( *newResult->iResult );
+			aStream->ReadL ( writeStream, aStream->Source()->SizeL() );
+			aStream->Close();
+			}
+		CleanupStack::PopAndDestroy();  // writeStream
+		if ( iResultList.Append ( newResult ) == KErrNone )
+			{
+			CleanupStack::Pop();   // newResult
+			if ( iCallbackList.Append ( newCallback ) != KErrNone )
+				{
+				delete iResultList[iResultList.Count()-1];
+				iResultList.Remove(iResultList.Count()-1);				
+				}
+			}
+		else
+			{
+			CleanupStack::PopAndDestroy();   // newResult			
+			}
+		}
+	else
+		{
+		delete iResultOtherAdapter;
+		iResultOtherAdapter = NULL;
+		iResultOtherAdapter = HBufC8::NewL ( aStream->Source()->SizeL() );
+		TPtr8 tmpPtr = iResultOtherAdapter->Des();
+		aStream->ReadL ( tmpPtr );
+		aStream->Close();
+		}
+		
+	_DBG_FILE("CNSmlDMHostSession::SetResultsL ( RReadStream ): end");
+	}
+
+// ------------------------------------------------------------------------------------------------
+// CNSmlDMHostSession::SetStatusL
+//	MSmlDmCallback - callback interface.
+// 	For returning statuses for dm adapter commands.
+//	@param aStatusRef. Reference to correct command.
+//	@param aErrorCode. Information about the command success.
+// ------------------------------------------------------------------------------------------------
+//
+void CNSmlDMHostSession::SetStatusL ( TInt aStatusRef, MSmlDmAdapter::TError aErrorCode )
+	{
+	_DBG_FILE("CNSmlDMHostSession::SetStatusL(): begin");
+		
+	if(aErrorCode  )
+		{
+		RProperty::Set(KPSUidNSmlDMSyncAgent, 
+				KNSmlDMCmdAddNodeSuccess, EFailed );
+		}
+		else 
+		{
+		RProperty::Set(KPSUidNSmlDMSyncAgent, 
+				KNSmlDMCmdAddNodeSuccess, EAdded );
+		}
+	if ( !iFetchLinkResult )
+		{		
+		TNSmlDmCallbackRef newCallback;
+		newCallback.callBack = ENSmlDmCallbackStatuses;
+		newCallback.reference = aStatusRef;
+
+		TNSmlDmStatusElement newStatus;
+		newStatus.iStatusRef = aStatusRef;
+		newStatus.iStatus = aErrorCode;	
+    	if(iCommitStatus.iStreamingOngoing&&iCommitStatus.iStreamCommitted)
+		    {
+		    if(aStatusRef==iCommitStatus.iOldStatusRef)
+		        {
+		        newStatus.iStatusRef = iCommitStatus.iNewStatusRef;
+		        }
+		    }
+
+		if ( iStatusCodeList.Append ( newStatus ) == KErrNone )
+			{
+			if ( iCallbackList.Append ( newCallback ) != KErrNone )
+				{
+				iStatusCodeList.Remove ( iStatusCodeList.Count()-1 );
+				}
+			}
+		}
+	else 
+		{
+		iStatusOtherAdapter = aErrorCode;
+		}
+	_DBG_FILE("CNSmlDMHostSession::SetStatusL(): end");
+	}
+
+// ------------------------------------------------------------------------------------------------
+// CNSmlDMHostSession::SetMappingL
+//	MSmlDmCallback - callback interface.
+// 	This function is called for a new management object, 
+//	both for node objects and for leaf objects by dm adapter.
+//	@param aURI. URI of the object. 
+//	@param aLUID. Typically this is ID for the database table.
+// ------------------------------------------------------------------------------------------------
+//
+void CNSmlDMHostSession::SetMappingL ( const TDesC8& aURI, const TDesC8& aLUID )
+	{
+	_DBG_FILE("CNSmlDMHostSession::SetMappingL(): begin");
+	if ( !iFetchLinkResult )
+		{
+		if ( !iMapUris )
+			{
+			iMapUris = new (ELeave) CArrayPtrSeg<HBufC8>(KNSmlDmGranularity);			
+			}
+		if ( !iMapLuids )
+			{
+			iMapLuids = new (ELeave) CArrayPtrSeg<HBufC8>(KNSmlDmGranularity);			
+			}
+
+		HBufC8* newUri = aURI.AllocLC();
+		iMapUris->AppendL ( newUri );
+		CleanupStack::Pop();  // newUri
+		 
+		HBufC8* newLuid = aLUID.AllocLC();
+		iMapLuids->AppendL ( newLuid );
+		CleanupStack::Pop();  // newLuid 
+
+		TNSmlDmCallbackRef newCallback;
+		newCallback.callBack = ENSmlDmCallbackMappings;
+		newCallback.reference = 0;
+		iCallbackList.Append ( newCallback );	
+		}
+	else
+		{
+		if ( iCbSessConnected && ( aURI.Find ( KNSmlDmApAdapterURI1 ) == 0 || aURI.Find ( KNSmlDmApAdapterURI2 ) == 0 ) )
+			{
+			iCbSession.AddMappingInfoL ( KNSmlInternetAdapterImplUid, aURI, aLUID );			
+			}
+		}
+	_DBG_FILE("CNSmlDMHostSession::SetMappingL(): end");
+	}
+
+// ------------------------------------------------------------------------------------------------
+// CNSmlDMHostSession::FetchLinkL
+//	MSmlDmCallback - callback interface.
+// 	The function is used to make a fetch to other adapters. 
+//	@param aURI. URI of the object. 
+//	@param aData. Reference to data, i.e. data is returned here
+//	@param aStatus. The status of fetch command is returned here
+// ------------------------------------------------------------------------------------------------
+//
+void CNSmlDMHostSession::FetchLinkL ( const TDesC8& aURI, CBufBase& aData, MSmlDmAdapter::TError& aStatus )
+	{
+	_DBG_FILE("CNSmlDMHostSession::FetchLinkL(): begin");
+	// Remove possible ./ from the beginning
+	TPtrC8 uri = NSmlDmURI::RemoveDotSlash ( aURI );
+	
+	// Check the ACL rights
+	if ( !iCbSessConnected )
+		{
+		if ( iCbSession.Connect() != KErrNone )
+			{
+			aData.InsertL ( 0, KNullDesC8 );
+			aStatus = MSmlDmAdapter::EError;
+			return;			
+			}
+		else 
+			{
+			iCbSessConnected = ETrue;			
+			}
+		}
+	
+	if ( iCbSession.CheckDynamicAclL( uri, EAclGet, iMgmtTree ) ) //tarm
+		{
+		// Check if this server has access to the required adapter
+		TUint32 adId(0);
+		TNSmlDmDDFFormat nodeType;
+		if ( AdapterIdFromUriL ( uri, adId, nodeType ) )
+			{	
+			FetchLinkFromAdapterL ( uri, adId, aData, aStatus, nodeType );
+			}
+		else
+			{
+			// Help from other servers needed
+			FetchLinkViaIPCL ( uri, aData, aStatus );		
+			}
+		}
+	else 
+		{
+		aData.InsertL ( 0, KNullDesC8 );
+		aStatus = MSmlDmAdapter::EError;
+		}
+	
+	_DBG_FILE("CNSmlDMHostSession::FetchLinkL(): end");
+	}
+
+// ------------------------------------------------------------------------------------------------
+// CNSmlDMHostSession::FetchLinkViaIPCL
+//	Serves the FetchLink callback when the AP adapter is not found from the server.
+//	Issues an IPC -FetchLink command to the other DM Host Server 
+//	using RNSmlDMFetchLink -client API.
+//	@param aURI. A path to the requested interior node object or leaf object. 
+//	@param aData. A reference parameter, i.e. a place for fetch result. 
+//	@param aStatus. A reference parameter telling the command success (e.g. EOk or ENotFound).
+// ------------------------------------------------------------------------------------------------
+//
+void CNSmlDMHostSession::FetchLinkViaIPCL ( const TDesC8& aURI, CBufBase& aData, MSmlDmAdapter::TError& aStatus ) const
+	{
+	_DBG_FILE("CNSmlDMHostSession::FetchLinkViaIPCL(): begin");
+	if ( ( aURI.Find ( KNSmlDmApAdapterURI1 ) == 0 || aURI.Find ( KNSmlDmApAdapterURI2 ) == 0 )
+	      && iOwnId != KNSmlDmApAdapterServerId )
+		{
+		RNSmlDMFetchLink fetchLink;
+		TInt openErr ( KErrNone );
+		switch ( KNSmlDmApAdapterServerId )
+			{
+			case 1:
+				TRAP ( openErr, fetchLink.OpenL ( KNSmlDmHostServer1Name ) );				
+				break;
+			case 2:
+				TRAP ( openErr, fetchLink.OpenL ( KNSmlDmHostServer2Name ) );				
+				break;
+			case 3:
+				TRAP ( openErr, fetchLink.OpenL ( KNSmlDmHostServer3Name ) );				
+				break;
+			case 4:
+				TRAP ( openErr, fetchLink.OpenL ( KNSmlDmHostServer4Name ) );				
+				break;
+			default:
+				break;
+			}
+		TRAPD ( chunkErr, fetchLink.SendChunkHandleL ( iChunk ) );
+		if ( openErr == KErrNone && chunkErr == KErrNone )
+			{
+			HBufC8* answer = NULL;
+			RMemReadStream readStream ( iChunk.Base(), iChunk.Size() );
+			CleanupClosePushL ( readStream );
+			TRAPD ( connErr, ( answer = fetchLink.FetchL ( aURI, readStream ) ) );
+			CleanupStack::PopAndDestroy();  // readStream
+			fetchLink.Close();
+			if ( answer && connErr == KErrNone )
+				{
+				aStatus = MSmlDmAdapter::EOk;
+				aData.InsertL ( 0, *answer );
+				delete answer;
+				answer = 0;
+				return;				
+				}
+			}
+		}
+	aData.InsertL ( 0, KNullDesC8 );
+	aStatus = MSmlDmAdapter::EError;		
+	_DBG_FILE("CNSmlDMHostSession::FetchLinkViaIPCL(): end");
+	}
+
+// ------------------------------------------------------------------------------------------------
+// CNSmlDMHostSession::FetchLinkFromAdapterL
+//	Serves the FetchLink callback when the AP adapter is owned this server.
+//	Asks first a luid from the callback server.
+//	Calls FetchLeafObjectL -function of the DM adapter if the requested object is a leaf. 
+//	Calls ChildURIListL -function of the DM adapter if the requested object is an interior node. 
+//	@param aURI. A path to the requested interior node object or leaf object. 
+//	@param aAdapterId. Identifies the requested adapter. 
+//	@param aData. A reference parameter, i.e. a place for fetch result. 
+//	@param aStatus. A reference parameter telling the command success (e.g. EOk or ENotFound).
+//	@param aNodeType. Defines whether the object is a leaf or a node.
+// ------------------------------------------------------------------------------------------------
+//
+void CNSmlDMHostSession::FetchLinkFromAdapterL ( const TDesC8& aURI, TUint32 aAdapterId, CBufBase& aData, MSmlDmAdapter::TError& aStatus, TNSmlDmDDFFormat aNodeType )
+	{
+	_DBG_FILE("CNSmlDMHostSession::FetchLinkFromAdapterL(): begin");
+	delete iResultOtherAdapter;
+	iResultOtherAdapter = NULL;
+	CSmlDmAdapter* adapter = NULL;
+	for ( TInt i(0); i<iAdapters.Count(); i++ )
+		{
+		if ( iAdapters[i].adapterId == aAdapterId )
+			{
+			if ( !iAdapters[i].adapterPtr )
+				{
+				adapter = LoadNewAdapterL ( i, aAdapterId );
+				if ( !adapter )
+					{
+					break;					
+					}
+				}
+			HBufC8* luid = GetLuidAllocL ( aURI );
+			CleanupStack::PushL ( luid );
+			if ( aNodeType == ENSmlDmDDFLeaf )
+				{
+				iFetchLinkResult = ETrue;
+				iAdapters[i].adapterPtr->FetchLeafObjectL ( aURI, *luid, KNullDesC8, KNSmlDmNoRef, KNSmlDmNoRef );
+				iFetchLinkResult = EFalse;
+				}
+			else if ( aNodeType == ENSmlDmDDFNode )
+				{
+				CArrayFixFlat<TSmlDmMappingInfo>* prevURISegList = new ( ELeave ) CArrayFixFlat<TSmlDmMappingInfo> ( KNSmlDmGranularity );
+				CleanupStack::PushL ( prevURISegList ); 
+				PrevURISegListL ( aAdapterId, aURI, *prevURISegList );
+				iFetchLinkResult = ETrue;
+				iAdapters[i].adapterPtr->ChildURIListL ( aURI, *luid, *prevURISegList, KNSmlDmNoRef, KNSmlDmNoRef );			
+				iFetchLinkResult = EFalse;
+				CleanupStack::PopAndDestroy();  // prevURISegList
+				}
+			CleanupStack::PopAndDestroy();  // luid
+			if ( !iResultOtherAdapter )
+				{
+				break;				
+				}
+			aData.InsertL ( 0, *iResultOtherAdapter );
+			aStatus = iStatusOtherAdapter;
+			return;
+			}
+		}
+	aData.InsertL ( 0, KNullDesC8 );
+	aStatus = MSmlDmAdapter::EError;
+	_DBG_FILE("CNSmlDMHostSession::FetchLinkFromAdapterL(): end");
+	}
+
+// ------------------------------------------------------------------------------------------------
+// CNSmlDMHostSession::GetLuidAllocL
+//	MSmlDmCallback - callback interface.
+// 	The function returns the LUID which is mapped to aURI. 
+//	@param aURI. URI of the object. 
+//	@return HBufC8*. If LUID is not found, the function allocates a null length string.
+// ------------------------------------------------------------------------------------------------
+//
+HBufC8* CNSmlDMHostSession::GetLuidAllocL ( const TDesC8& aURI )
+	{
+	_DBG_FILE("CNSmlDMHostSession::GetLuidAllocL()");
+	DBG_ARGS8( _S8("GetLuidAllocL(): aURI = %S "), &aURI );	
+	HBufC8* luid = NULL;
+	
+	// Search matching URI from the internal buffer,
+	// in case a mapping information is not yet written to db.
+	TBool foundInternally(EFalse);
+	if ( iMapUris && iMapLuids )
+	    {
+	    for ( TInt i(0); i<iMapUris->Count(); i++ )
+	        {
+	        if ( *iMapUris->At(i) == aURI )
+	            {
+            	_DBG_FILE("CNSmlDMHostSession::GetLuidAllocL() LUID found from internal buffer");	            
+	            foundInternally = ETrue;
+	            luid = iMapLuids->At(i)->AllocL();
+	            }
+	        }
+	    }
+	if ( !foundInternally )
+	    {
+    	if ( !iCbSessConnected )
+	    	{
+		    if ( iCbSession.Connect() != KErrNone )
+			    {
+            	_DBG_FILE("ERROR!!! Connect to Callback server FAILED!!!!");			    
+			    luid = HBufC8::NewL(0);
+			    return luid;
+			    }
+		    else 
+			    {
+			    iCbSessConnected = ETrue;
+			    }
+		    }
+        TUint32 adId(0);
+        TNSmlDmDDFFormat nodeType;
+	    if ( AdapterIdFromUriL ( aURI, adId, nodeType ) )
+	        {
+		    luid = iCbSession.GetLuidAllocL ( adId, aURI );
+	        }
+	    else
+		    {
+            _DBG_FILE("ERROR!!! AdapterId could not be found using URI");		    
+		    luid = HBufC8::NewL(0);	
+		    }							
+	    }
+	DBG_ARGS8( _S8("GetLuidAllocL(): returned luid = %S "), luid );	    
+    return luid;			
+	}
+
+// ------------------------------------------------------------------------------------------------
+// CNSmlDMHostSession::PrevURISegListL
+//	Auxiliary function which is called from FetchLinkFromAdapterL.
+//	Gets a previous URI segment list from the callback server. 
+//	This function is called only during the fetchlink callback and when
+//	the requested object is an interior node object.
+//	@param aAdapterId. Identifies the requested adapter. 
+//	@param aURI. A path to the requested interior node object. 
+//	@param aURISegList. A reference parameter where callback server writes a list of the child nodes.
+// ------------------------------------------------------------------------------------------------
+//
+void CNSmlDMHostSession::PrevURISegListL ( TUint32 aAdapterId, const TDesC8& aURI, CArrayFixFlat<TSmlDmMappingInfo>& aURISegList )
+	{
+	_DBG_FILE("CNSmlDMHostSession::PrevURISegListL(): begin");
+	if ( !iCbSessConnected )
+		{
+		if ( iCbSession.Connect() != KErrNone )
+			{
+			return;			
+			}
+		else 
+			{
+			iCbSessConnected = ETrue;			
+			}
+		}
+	iCbSession.GetUriSegListL ( aAdapterId, aURI, aURISegList );
+	_DBG_FILE("CNSmlDMHostSession::PrevURISegListL(): end");
+	}
+
+// ------------------------------------------------------------------------------------------------
+// CNSmlDMHostSession::AdapterIdFromUriL
+//	Checks if the given URI can be found from the combined DDF structure.
+//	If not, most probably the URI belongs to some other DM adapter which this server
+//	is not capable of loading.  
+//	@param aURI. A path to the requested interior node object or leaf object. 
+//	@param aAdapterId. A reference parameter, to which DM Utils service writes the implementation
+//	                   UID of the adapter - if the URI was found. 
+//	@param aNodeType. A reference parameter defining whether the object is a leaf or a node.
+//	@return TBool. ETrue if both the URI and the adapter id were found, EFalse otherwise.
+// ------------------------------------------------------------------------------------------------
+//
+TBool CNSmlDMHostSession::AdapterIdFromUriL ( const TDesC8& aURI, TUint32& aAdapterId, TNSmlDmDDFFormat& aNodeType )
+	{
+	_DBG_FILE("CNSmlDMHostSession::GetAdapterIdL(): begin");
+	CNSmlDmNodeList* finalPtr = NULL;
+	aNodeType = iMgmtTree->FindNameFromNodeListL ( aURI, finalPtr );
+	if ( finalPtr )
+		{
+		TUint8 sessId(0);
+		finalPtr->GetImplUid ( aAdapterId, sessId );
+		if ( aAdapterId || sessId )
+			{
+			return ETrue;			
+			}
+		}
+	_DBG_FILE("CNSmlDMHostSession::GetAdapterIdL(): end");
+	return EFalse;
+	}
+
+// ------------------------------------------------------------------------------------------------
+// CNSmlDMHostSession::RoomForLargeData
+//	Auxiliary function for defining how much there is room in the chunk for actual
+//	data of the large object.
+//	@param aType. MIME type of the result item.
+//	@return TInt. The available size in bytes.
+// ------------------------------------------------------------------------------------------------
+//
+inline TInt CNSmlDMHostSession::RoomForLargeData ( const TDesC8& aType ) const
+	{
+	return ( ( ( ( KNSmlDmHostChunkMaxSize - KNSmlDmChunkMarginal ) - KNSmlDmConstItemSize ) - aType.Size() ) - 2 );
+	}
+
+// ------------------------------------------------------------------------------------------------
+// void CNSmlDMHostSession::GetAccessPointImplUid()
+//	This function is called for getting the accesspoint implementation uid.  
+//	@return TUint. The Implementationuid.
+// ------------------------------------------------------------------------------------------------
+//
+	TUint CNSmlDMHostSession::GetAccessPointImplUid()
+	{
+	if(FeatureManager::FeatureSupported(KFeatureIdFfDmConnmoAdapter))
+		{
+			return KNSmlDMConnMOAdapterImplUid;
+		}
+	else
+		{
+			return KNSmlInternetAdapterImplUid;
+		}	
+	}
+
+// ------------------------------------------------------------------------------------------------
+// Client code to access other dm host servers
+// ------------------------------------------------------------------------------------------------
+
+
+// ------------------------------------------------------------------------------------------------
+// RNSmlDMFetchLink::RNSmlDMFetchLink()
+//	C++ constructor.
+// ------------------------------------------------------------------------------------------------
+//
+RNSmlDMFetchLink::RNSmlDMFetchLink()
+	: RSessionBase()
+	{
+	}
+
+// ------------------------------------------------------------------------------------------------
+// RNSmlDMFetchLink::OpenL()
+//	Creates a session (i.e. a connection) to the other DM Host Server.
+//	@param aServer. The server name (e.g. "nsmldmhostserver2").	
+// ------------------------------------------------------------------------------------------------
+//
+void RNSmlDMFetchLink::OpenL ( const TDesC& aServer )
+	{
+	_DBG_FILE("RNSmlDMFetchLink::OpenL(): begin");
+	TVersion version ( KNSmlDmHostServerVerMajor, KNSmlDmHostServerVerMinor, KNSmlDmHostServerVerBuild );
+	TInt res = CreateSession ( aServer, version );
+	User::LeaveIfError( res );	
+	_DBG_FILE("RNSmlDMFetchLink::OpenL(): end");
+	}
+
+// ------------------------------------------------------------------------------------------------
+// RNSmlDMFetchLink::SendChunkHandleL
+//	Sets a handle to the global memory chunk. 
+//	The client DM Host Server will send a handle of the already existing chunk.
+//	In other words, no new chunks are created for the FetchLink IPC command. 
+//	Additionally, a server id is sent in the message.
+//	This id tells to the common session class that it is acting as a 'FetchLink server'.
+//	This information is needed in order to avoid destroying the chunk still in use.
+//	@param aHandle. A handle to the existing global memory chunk. 
+// ------------------------------------------------------------------------------------------------
+//
+void RNSmlDMFetchLink::SendChunkHandleL ( const RChunk& aChunk ) const
+	{
+	_DBG_FILE("RNSmlDMFetchLink::SendChunkHandleL(): begin");
+	TIpcArgs args;
+ 	args.Set ( 0, aChunk );
+ 	args.Set ( 1, KNSmlDmFetchLinkServerId );
+ 	TInt error = SendReceive ( ENSmlDMChunkHandle, args );
+	User::LeaveIfError ( error );		
+	_DBG_FILE("RNSmlDMFetchLink::SendChunkHandleL(): end");
+	}
+
+
+// ------------------------------------------------------------------------------------------------
+// void RNSmlDMFetchLink::FetchL()
+//	Issues a fetch IPC command to the other DM Host Server.  
+//	@param aURI. A path to the requested interior node object or the leaf object. 
+//	@param aReadStream. A reference to the stream in the chunk from where the result
+//	  				    can be read. 
+//	@return HBufC8*. The result of the fetch link command.
+// ------------------------------------------------------------------------------------------------
+//
+HBufC8* RNSmlDMFetchLink::FetchL ( const TDesC8& aURI, RReadStream& aReadStream ) const
+	{
+	_DBG_FILE("RNSmlDMFetchLink::FetchL(): begin");	
+    User::LeaveIfError ( SendReceive ( ENSmlDMFetchLink, TIpcArgs( &aURI ) ) );
+
+	TInt ansLength = aReadStream.ReadUint16L();
+    HBufC8* answer = HBufC8::NewLC ( ansLength );
+    TPtr8 answerPtr = answer->Des();
+    if ( ansLength )
+    	{
+    	aReadStream.ReadL ( answerPtr );    	
+    	}
+    CleanupStack::Pop();  // answer
+    _DBG_FILE("RNSmlDMFetchLink::FetchL(): end");
+    return answer;
+	}
+	
+
+
+// ------------------------------------------------------------------------------------------------
+// void RNSmlDMFetchLink::Close()
+//	Closes a session to the other DM Host Server.  
+// ------------------------------------------------------------------------------------------------
+//
+void RNSmlDMFetchLink::Close()
+	{
+	_DBG_FILE("RNSmlDMFetchLink::Close(): begin");
+	// close session	
+	RSessionBase::Close();
+	_DBG_FILE("RNSmlDMFetchLink::Close(): end");
+	}