homescreenpluginsrv/hspsmanager/src/hspsmaintenancehandler.cpp
author Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
Wed, 31 Mar 2010 22:04:35 +0300
branchRCL_3
changeset 51 15e4dd19031c
parent 19 502e5d91ad42
child 59 a0713522ab97
permissions -rw-r--r--
Revision: 201011 Kit: 201013

/*
* Copyright (c) 2002-2008 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:  Implementation of HSPS MhspsMaintenanceService interface defined
*                in hspsThemeManagement.h. For details, see header file.
*
*/


#include <centralrepository.h>

#include "hsps_builds_cfg.hrh"
#include "hspsthememanagement.h"
#include "hspsdefinitionrepository.h"
#include "hspsresource.h"
#include "hspsresult.h"
#include "hspspluginidlist.h"
#include "hspsodt.h"
#include "hspsmaintenancehandler.h"
#include "hspsthemeserver.h"
#include "hspsinstallationhandler.h"
#include "hspssecurityenforcer.h"
#include "hspsconfiguration.h"
#include "hspsdomdocument.h"
#include "hspsdomlist.h"
#include "hspsdomdepthiterator.h"
#include "hspsdomnode.h"
#include "hspsdomattribute.h"
#include "hspsmanifest.h"
#include "hspsserverutil.h"
#include "hspsthemeserversession.h"

#ifdef HSPS_LOG_ACTIVE
#include <hspsodtdump.h>
#include <hspslogbus.h>
#endif


_LIT(KSourcesFolder, "\\sources\\");
_LIT(KLocalesFolder, "\\locales\\");

const TInt KAdditionalRequiredDiskSpace = 256 * 1024; /// 256KB in bytes.

// ============================= LOCAL FUNCTIONS ===============================

// -----------------------------------------------------------------------------
// Callback function for removing repository lock if error occurs while repository is locked
// Returns: void
// -----------------------------------------------------------------------------
//
LOCAL_C void UnlockRepository( TAny* aObject )
    {
    ChspsDefinitionRepository* DefRep = reinterpret_cast<ChspsDefinitionRepository*>( aObject );
        
    if( DefRep->Locked() )
        {
        DefRep->Unlock();
        }
    }

// -----------------------------------------------------------------------------
// ResetAndDestroyArray Callback function for cleaning up the CArrayPtr.
// Returns: void
// -----------------------------------------------------------------------------
//
LOCAL_C void ResetAndDestroyArray( TAny* aArray )
    {
    reinterpret_cast<CArrayPtrSeg<HBufC>*>( aArray )->ResetAndDestroy();
    }
    

// ============================ MEMBER FUNCTIONS ===============================

// -----------------------------------------------------------------------------
// ChspsMaintenanceHandler::ChspsMaintenanceHandler
// C++ default constructor can NOT contain any code, that
// might leave.
// -----------------------------------------------------------------------------
//
ChspsMaintenanceHandler::ChspsMaintenanceHandler( 
        ChspsThemeServer& aThemeServer, 
        const TUint aSecureId ): 
    CTimer(EPriorityLow), 
    iThemeServer( aThemeServer ), 
    iSecureId( aSecureId ),
    iCentralRepository( aThemeServer.CentralRepository() ),    
    iDefinitionRepository( aThemeServer.DefinitionRepository() ),
    iSecurityEnforcer( aThemeServer.SecurityEnforcer() ),
    iHeaderListCache( aThemeServer.HeaderListCache() ),
    iServerSession( NULL ),         
    iFileMan( NULL ),
    iMaintainLogoResources( EFalse )
    { 
    iDeliveryCount = 0;
    iSubscription = EFalse;
    }
    
// -----------------------------------------------------------------------------
// ChspsMaintenanceService::NewL
// Two-phased constructor.
// -----------------------------------------------------------------------------
//
ChspsMaintenanceHandler* ChspsMaintenanceHandler::NewL( 
        ChspsThemeServer& aThemeServer,
        const TUint aSecureId )
    {
    ChspsMaintenanceHandler* h = ChspsMaintenanceHandler::NewLC( 
            aThemeServer, aSecureId );
    CleanupStack::Pop(h);
    return (h);
    }

// -----------------------------------------------------------------------------
// ChspsMaintenanceService::NewLC
// Two-phased constructor.
// -----------------------------------------------------------------------------
//
ChspsMaintenanceHandler* ChspsMaintenanceHandler::NewLC( 
        ChspsThemeServer& aThemeServer,
        const TUint aSecureId )
    {
    ChspsMaintenanceHandler* h = new (ELeave) ChspsMaintenanceHandler( 
            aThemeServer, aSecureId );
    CleanupStack::PushL(h);
    h->ConstructL();
    return (h);
    }

// Destructor
ChspsMaintenanceHandler::~ChspsMaintenanceHandler()
    {
    Cancel();
    if (iHeaderDataList)
        {
        iHeaderDataList->ResetAndDestroy();
        }
    delete iHeaderDataList;
    delete iSearchMask;
    delete iSetMask;
    delete iResult;
    delete iFileMan;
    iDefinitionRepository.UnregisterObserver( *this );
    }


// -----------------------------------------------------------------------------
// ChspsMaintenanceHandler::ConstructL
// Symbian 2nd phase constructor can leave.
// -----------------------------------------------------------------------------
//
void ChspsMaintenanceHandler::ConstructL()
    {
    // call the base class ConstructL
    CTimer::ConstructL();
    iHeaderDataList = new( ELeave ) CArrayPtrSeg<HBufC8>(KHeaderListGranularity);
    iResult = ChspsResult::NewL();
    // add this timer to the active scheduler   
    CActiveScheduler::Add(this);
    iDefinitionRepository.RegisterObserverL( *this );
    }

// -----------------------------------------------------------------------------
// ChspsMaintenanceHandler::ServiceGetListHeadersL
// Fetches the header list from repository and writes the first header back to the caller 
// (other items were commented in a header).
// -----------------------------------------------------------------------------
//
void ChspsMaintenanceHandler::ServiceGetListHeadersL(const RMessage2& aMessage)
    {
    // only allow one request to be submitted at a time
    // all synch call must use local message pointer variable
    RMessagePtr2 messagePtr = aMessage;
    ThspsServiceCompletedMessage ret = EhspsGetListHeadersFailed;
    iDeliveryCount = 0;
        
    if (!IsActive() && !iSubscription)    // first request
        {
        TBuf8<KMaxHeaderDataLength8> searchMaskData;// save a search mask
        messagePtr.ReadL(1,searchMaskData,0);
        // constructing iSearcMask -object
        if (iSearchMask)
            {
            delete iSearchMask;
            iSearchMask = NULL;
            }
        iSearchMask = ChspsODT::NewL();
        iSearchMask->UnMarshalHeaderL(searchMaskData);
                
        iMaintainLogoResources = EFalse;
        TPckg<TInt> intPkg( iMaintainLogoResources );                                    
        messagePtr.ReadL(3, intPkg );
                                                           
        // now there is a subscription
        iSubscription = ETrue;
        // fetch the header list from repository
        ret = hspsGetListHeaders(searchMaskData, *iHeaderDataList);
        if (ret == EhspsGetListHeadersSuccess)
            {
            TInt count = iHeaderDataList->Count();
            // result informs list count in query
            iResult->iIntValue1 = count;
            if ( !count )
                {
                ret = EhspsGetListHeadersEmpty;
                }
            }
            
        CompleteRequest(ret, messagePtr);    
        }
    else
        {
        iResult->iSystemError = KErrInUse;
        iResult->iSystemError = KErrInUse;
        CompleteRequest( EhspsServiceRequestError, iMessagePtr );
        }
    }

// -----------------------------------------------------------------------------
// ChspsMaintenanceHandler::ServiceGetNextHeaderL
// Writes back to the caller the next headers in the header list one at a time
// (other items were commented in a header).
// -----------------------------------------------------------------------------
//
void ChspsMaintenanceHandler::ServiceGetNextHeaderL(const RMessage2& aMessage)
    {
    // only allow one request to be submitted at a time
    iRequestMessage = (ThspsServiceRequestMessage) aMessage.Function();
    iCompletedMessage = EhspsGetListHeadersUpdate;
    // now using message pointer as member variable because of asynch call
    iMessagePtr = aMessage;
    if ( !IsActive() && iSubscription)  // requesting next as should
        {
        // is there headers to delivere left
        if (iHeaderDataList->Count() > iDeliveryCount)
            {                                    
            // at least one header on the list
            TPtr8 bufPtr( iHeaderDataList->At(iDeliveryCount)->Des() );
            iMessagePtr.WriteL(2, bufPtr, 0);
            // add list count
            iDeliveryCount++;
            // deliver a list item
            CompleteRequest( EhspsGetListHeadersUpdate, iMessagePtr );
            }
        }
    else
        {
        iResult->iSystemError = KErrInUse;
        iResult->iXuikonError = KErrPermissionDenied;
        CompleteRequest( EhspsServiceRequestError, iMessagePtr );
        }
    }
    

// -----------------------------------------------------------------------------
// ChspsMaintenanceHandler::SetServerSession
// -----------------------------------------------------------------------------
//
void ChspsMaintenanceHandler::SetServerSession(
        ChspsThemeServerSession* aServerSession )
    {
    iServerSession = aServerSession;
    }

// -----------------------------------------------------------------------------
// ChspsMaintenanceHandler::ServiceSetActiveThemeL
// Sets the active theme and writes back that themes header data
// (other items were commented in a header).
// -----------------------------------------------------------------------------
//    
void ChspsMaintenanceHandler::ServiceSetActiveThemeL(const RMessage2& aMessage)
    {
    ThspsServiceCompletedMessage ret = EhspsSetActiveThemeFailed;
    // using message pointer as a local variable because of a synch call
    RMessagePtr2 messagePtr = aMessage;

    TBuf8<KMaxHeaderDataLength8> setMaskData;
    messagePtr.ReadL(1,setMaskData,0);
    //constructing setMask -object
    if( iSetMask )
        {
        delete iSetMask;
        iSetMask = NULL;
        }
    iSetMask = ChspsODT::NewL();
    iSetMask->UnMarshalHeaderL( setMaskData );
    
    // calling actual activation
    ChspsODT* odt;
    odt = ChspsODT::NewL();
    CleanupStack::PushL(odt);
    
    
    iDefinitionRepository.Lock();
    // In case of error. repository is unlocked    
    CleanupStack::PushL( TCleanupItem( UnlockRepository, &iDefinitionRepository ) );
    ret = hspsSetActiveTheme( *iSetMask, *odt );
    if ( ret == EhspsSetActiveThemeSuccess )
        {                
        // Store updated ODT to definition repository
        iDefinitionRepository.SetOdtL( *odt );
        
        HBufC8* headerdata;
        headerdata = odt->MarshalHeaderL();
        if (headerdata != NULL)
            {
            // Write activated ODT header data to client
            CleanupStack::PushL(headerdata);
            messagePtr.WriteL(2,headerdata->Des(),0);
            CleanupStack::PopAndDestroy(headerdata);
            
            ThspsRepositoryInfo info( EhspsODTActivated );
            iDefinitionRepository.RegisterNotification( info );
        }
    }
    iDefinitionRepository.Unlock();
    CleanupStack::Pop(&iDefinitionRepository);
        

    CleanupStack::Pop(odt);
    if (odt)
        {
        delete odt;
        odt = NULL;
        }
        
    // complete the message
    CompleteRequest(ret, messagePtr );        
    }


// -----------------------------------------------------------------------------
// ChspsMaintenanceHandler::ServiceRestoreDefaultL
// Restores the default theme according to the information in aMessage and writes 
// back restored themes header data. 
// (other items were commented in a header).
// -----------------------------------------------------------------------------
//    
void ChspsMaintenanceHandler::ServiceRestoreDefaultL( const RMessage2& aMessage )
    {
    ThspsServiceCompletedMessage ret = EhspsRestoreDefaultFailed;
    // using message pointer as a local variable because of synch call
    RMessagePtr2 messagePtr = aMessage;
    // TIpcArgs(TInt aAppUid, &aSetMaskData, &aHeaderData)
    TBuf8<KMaxHeaderDataLength8> setMaskData;
    messagePtr.ReadL( 1, setMaskData, 0 );
    //constructing setMask -object
    if ( iSetMask )
        {
        delete iSetMask;
        iSetMask = NULL;
        }
    iSetMask = ChspsODT::NewL();
    iSetMask->UnMarshalHeaderL( setMaskData );
    ChspsODT* odt;
    odt = ChspsODT::NewL();
    CleanupStack::PushL( odt );
    
    if ( !iDefinitionRepository.Locked() )
        {
        iDefinitionRepository.Lock();
        // In case of error. repository is unlocked    
        CleanupStack::PushL( TCleanupItem( UnlockRepository, &iDefinitionRepository ) );
        // calling actual restoration
        ret = hspsRestoreDefault( *iSetMask, *odt );
        if ( ret == EhspsRestoreDefaultSuccess )
            {
            HBufC8* headerdata;
            headerdata = odt->MarshalHeaderL();
            if (headerdata != NULL)
                {
                CleanupStack::PushL( headerdata );
                messagePtr.WriteL( 2, headerdata->Des(), 0 );
                CleanupStack::PopAndDestroy( headerdata );
                
                // inform for cache update to the repository so that everyone will know 
                // about the change
                ThspsRepositoryInfo info( EhspsCacheUpdate );
                iDefinitionRepository.RegisterNotification( info );
                }
            }
        iDefinitionRepository.Unlock();
        CleanupStack::Pop(&iDefinitionRepository);
        }
    else
        {
        ret = EhspsRestoreDefaultFailed;

#ifdef HSPS_LOG_ACTIVE  
        if( iLogBus )
            {
            iLogBus->LogText( _L( "ChspsMaintenanceHandler::ServiceRestoreDefaultL(): - failed, repository is locked." ) );
            }
#endif            
        }
        
    
    CleanupStack::PopAndDestroy( odt );
    // complete the message
    CompleteRequest( ret, messagePtr );
    }

// -----------------------------------------------------------------------------
// ChspsMaintenanceHandler::ServiceRemoveThemeL
// Reads ODT from RMessage2 and calls the actual removal method.
// (other items were commented in a header).
// -----------------------------------------------------------------------------
//    
void ChspsMaintenanceHandler::ServiceRemoveThemeL( const RMessage2& aMessage )
    {
    ThspsServiceCompletedMessage ret = EhspsRemoveThemeFailed;
    // using message pointer as a local variable because of synch call
    RMessagePtr2 messagePtr = aMessage;
    
    // TIpcArgs(TInt aAppUid, &aSetMaskData, &aHeaderData)
    TBuf8<KMaxHeaderDataLength8> setMaskData;
    messagePtr.ReadL( 1, setMaskData, 0 );
    
    //constructing setMask -object
    if ( iSetMask )
        {
        delete iSetMask;
        iSetMask = NULL;
        }
    
    iSetMask = ChspsODT::NewL();
    iSetMask->UnMarshalHeaderL( setMaskData );
   
    // calling actual removal
    ret = hspsRemoveThemeL( *iSetMask );
            
    // complete the message
    CompleteRequest( ret, messagePtr );
    }

// -----------------------------------------------------------------------------
// Appends an application configuration with the provided plugin configuration
// -----------------------------------------------------------------------------
//    
void ChspsMaintenanceHandler::ServiceAddPluginL( const RMessage2& aMessage )
    {
    // Defaults
    ThspsServiceCompletedMessage ret = EhspsAddPluginFailed;
    iResult->iXuikonError = KErrNotFound;
    TInt err = KErrNone;
    
    // Parameters
    RMessagePtr2 messagePtr = aMessage;
    
    // IPC slots: 
    // #0) output: externalized ChspsResult for error handling
    // #1) input: ThpsParamAddPlugin struct
    // #2) output: added plugin id
    
    // Get service parameters from IPC slot #1
    ThpsParamAddPlugin params;        
    TPckg<ThpsParamAddPlugin> packagedStruct(params);    
    aMessage.ReadL(1, packagedStruct);                        
    const TInt appUid = params.appUid;
    const TInt configurationId = params.configurationId;
    const TInt pluginUid = params.pluginUid;
    const TInt newPos = params.positionIndex;    
          
    // Application configuration
    ChspsODT *appODT = NULL;
    if ( !err )
        {    
        // Get active application configuration from the central repository
        TInt appConfUid;       
        err = iCentralRepository.Get( appUid, appConfUid );
        if ( err || appConfUid < 1 )
            {
            err = KErrNotFound;         
            }
        else
            {
            // Get application configuration
            appODT = ChspsODT::NewL();
            CleanupStack::PushL( appODT );
            err = iThemeServer.GetConfigurationL( 
                    appUid, 
                    appConfUid,
                    *appODT );                                    
            }
        }
        
    // Plugin configuration
    ChspsODT* pluginODT = NULL;
    if ( !err )
        {
        // Find the plugin configuration (interface is unknown, so 1st argument is set to zero)
        pluginODT = ChspsODT::NewL();
        CleanupStack::PushL( pluginODT );        
        err = iThemeServer.GetConfigurationL( 
                0, 
                pluginUid,
                *pluginODT );
        }
           
    // Check needed space for addition. Returns system wide error code.
    if( !err )
        {    
        err = hspsServerUtil::EnoughDiskSpaceAvailableL(
                *pluginODT, 
                iThemeServer.DeviceLanguage(),
                iServerSession->FileSystem(),
                EDriveC,
                KAdditionalRequiredDiskSpace );
        }
    
    // Modifications
    TInt usedConfId = 0;
    TInt usedPluginId = 0;
    if ( !err && appODT && pluginODT )
       {       
           if ( iDefinitionRepository.Locked() )
               {
            // Repository locked
               err = KErrAccessDenied;
               }
           else
               {
               // Lock the Plugin Repository (a.k.a. Def.rep)
               iDefinitionRepository.Lock();                                
            CleanupStack::PushL( TCleanupItem( UnlockRepository, &iDefinitionRepository ) );
                                                        
            // Get used conf & plugin ids
            GetUsedIdsL( 
                appODT->DomDocument(),
                usedConfId,
                usedPluginId );            
                
            // Add the plugin configuration into the application configuration
            err = AppendConfigurationL( 
                *appODT, 
                *pluginODT, 
                configurationId,                    
                newPos,
                usedConfId,
                usedPluginId );
        
#ifdef HSPS_LOG_ACTIVE            
            if( appODT && iLogBus )
                {
                ChspsOdtDump::Dump( *appODT, *iLogBus );
                }
#endif            
    
            // Stores the new application configuration into the repository
            if ( !err )
                {
                err = iDefinitionRepository.SetOdtL( *appODT );
                if ( err )
                    {
#ifdef HSPS_LOG_ACTIVE  
                    if( iLogBus )
                        {
                        iLogBus->LogText( _L( "ChspsMaintenanceHandler::ServiceAddPluginL(): - Updating failed with code: %d" ), err );
                        }
#endif
                    }
                }
            
            // Unlock after the changes have been done
            iDefinitionRepository.Unlock();
            CleanupStack::Pop(&iDefinitionRepository);

            if ( !err )
                {
                // Inform clients that the ODT has been modified
                ThspsRepositoryInfo info( 
                    ThspsRepositoryEvent(EhspsODTModified),
                    appODT->RootUid(),
                    appODT->ThemeUid(),
                    aMessage.SecureId().iId,
                    appODT->ProviderUid(),
                    0,
                    0,
                    pluginUid,usedPluginId,ETrue,
                    pluginODT->ThemeFullName(),
                    (TLanguage)(appODT->OdtLanguage() ) );                                
                iDefinitionRepository.RegisterNotification( info );
                }                                        
            }       
       }    
    
    // Cleaning
    if ( pluginODT )
        {
        CleanupStack::PopAndDestroy( pluginODT );
        pluginODT = NULL;
        }
    if ( appODT )
        {
        CleanupStack::PopAndDestroy( appODT );
        appODT = NULL;
        }
    
    // Error handling
    iResult->iXuikonError = err;
    if ( !err )
        {
        // Get plugin configuration
        ret = EhspsAddPluginSuccess;
        }

    // Return id of the added plugin    
    TPckg<TInt> packagedInt(usedPluginId);                                    
    messagePtr.WriteL(2, packagedInt );
    
    // Completion 
    CompleteRequest( ret, messagePtr );
    }

// -----------------------------------------------------------------------------
// Finds last id value from the provided DOM.
// -----------------------------------------------------------------------------
//
void ChspsMaintenanceHandler::GetUsedIdsL(
        ChspsDomDocument& aDom,
        TInt& aLastUsedConfId,
        TInt& aLastUsedPluginId )        
    {
    aLastUsedConfId = 0;
    aLastUsedPluginId = 0;
    
    ChspsDomDepthIterator* iter = ChspsDomDepthIterator::NewL( *aDom.RootNode() );
    CleanupStack::PushL( iter );
        
    // Find a plugin node with an id attribute that matches the provided parent plugin id
    ChspsDomNode* node = iter->First();    
    while( node )
        {                
        const TDesC8& name = node->Name();
        
        // A Configuration element was found
        if ( name == KConfigurationElement )
            {
            // Get value of the id attribute (should exist)
            ChspsDomList& attrList = node->AttributeList();
            ChspsDomAttribute* attr = static_cast<ChspsDomAttribute*>( attrList.FindByName(KConfigurationAttrId) );
            if ( !attr )
                {
#ifdef HSPS_LOG_ACTIVE  
                if( iLogBus )
                    {
                    iLogBus->LogText( _L( "ChspsMaintenanceHandler::GetUsedIdsL(): Id attribute is missing!" ) );
                    }
#endif                
                User::Leave( KErrCorrupt );                
                }
            
            TInt id(0);
            const TDesC8& idDesc = attr->Value();
            TLex8 lex( idDesc );                                
            if ( lex.Val( id ) )
                {
#ifdef HSPS_LOG_ACTIVE  
                if( iLogBus )
                    {
                    iLogBus->LogText( _L( "ChspsMaintenanceHandler::GetUsedIdsL(): Invalid id" ) );
                    }
#endif                
                User::Leave( KErrCorrupt );                    
                }
            if ( id > aLastUsedConfId )
                {
                aLastUsedConfId = id;
                }    
            }
        
        // A Plugin element was found 
        else if ( name == KPluginElement )
            {
            // Get value of the id attribute (should exist)
            ChspsDomList& attrList = node->AttributeList();
            ChspsDomAttribute* attr = static_cast<ChspsDomAttribute*>( attrList.FindByName(KPluginAttrId) );
            if ( !attr )
                {
#ifdef HSPS_LOG_ACTIVE  
                if( iLogBus )
                    {
                    iLogBus->LogText( _L( "ChspsMaintenanceHandler::GetUsedIdsL(): Id attribute is missing!" ) );
                    }
#endif                
                User::Leave( KErrCorrupt );                
                }
            
            TInt id(0);
            const TDesC8& idDesc = attr->Value();
            TLex8 lex( idDesc );                                
            if ( lex.Val( id ) )
                {
#ifdef HSPS_LOG_ACTIVE  
                if( iLogBus )
                    {
                    iLogBus->LogText( _L( "ChspsMaintenanceHandler::GetUsedIdsL(): Invalid id" ) );
                    }
#endif                
                User::Leave( KErrCorrupt );                    
                }
            if ( id > aLastUsedPluginId )
                {
                aLastUsedPluginId = id;
                }                                
            }
        node = iter->NextL();      
        }
    CleanupStack::PopAndDestroy( iter );        
    }

// -----------------------------------------------------------------------------
// Appends an application configuration with an instance of a plugin configuration.
// -----------------------------------------------------------------------------
//
TInt ChspsMaintenanceHandler::AppendConfigurationL(
        ChspsODT& aAppODT,
        const ChspsODT& aPluginODT,
        const TInt aConfigurationId,        
        const TInt aNewPosition,
        TInt& aConfId,
        TInt& aPluginId )
    {            
    TInt ret = KErrNone;
    
    // Input validation
    if ( aPluginODT.ConfigurationType() == EhspsAppConfiguration 
            || aConfigurationId < 0 
            || aPluginODT.ThemeUid() < 1             
            || aConfId < 0
            || aPluginId < 0 )
        {
        return KErrArgument;
        }
                
    // Find a specific configuration node
     ChspsDomNode* confNode = hspsServerUtil::FindConfigurationNodeL( 
            aAppODT, 
            aConfigurationId );
    if ( !confNode )
        {
        return KErrNotFound;        
        }
    
    // Find first plugins node under the searchFromNode node
    ChspsDomNode* pluginsNode = FindPluginsNode( *confNode );                      
    if ( !pluginsNode )
        {
        // If there is no plugins node, it means we cannot add plugins!
        return KErrAccessDenied;
        }
    
    // Find plugin references from the plugin configuration being added,
    // generate ids and update the plugin dom accordingly (changes are not saved)    
    ret = HandlePluginReferencesL(
            aAppODT,
            (ChspsODT&)aPluginODT, 
            aConfId,
            aPluginId );            
    if ( !ret )
        {
        // Get new unique id
        aPluginId++;
        
        // Append the application configuration with the full plugin configuration dom
        ret = AppendPluginConfigurationL(
                aAppODT,
                *pluginsNode,
                aPluginODT,                         
                aNewPosition,
                aPluginId );                                                                            
        }                    
               
    return ret;
    }

// -----------------------------------------------------------------------------
// Finds the plugins node of the provided plugin node.
// -----------------------------------------------------------------------------
//
ChspsDomNode* ChspsMaintenanceHandler::FindPluginsNode(
        ChspsDomNode& aPluginNode )                
    {        
    ChspsDomNode* pluginsNode = NULL;
    ChspsDomNode* confNode = &aPluginNode;    
    if ( aPluginNode.Name() != KConfigurationElement )
        {
        ChspsDomList& childList = aPluginNode.ChildNodes();    
        confNode = (ChspsDomNode*)childList.FindByName( KConfigurationElement );
        }
    if ( confNode )
        {        
        ChspsDomNode* controlNode = (ChspsDomNode*)confNode->ChildNodes().FindByName( KControlElement );
        if ( controlNode )
            {            
            pluginsNode = (ChspsDomNode*)controlNode->ChildNodes().FindByName( KPluginsElement );
            }
        }

#ifdef HSPS_LOG_ACTIVE  
    if ( !pluginsNode )
        {
        if( iLogBus )
            {
            iLogBus->LogText( _L( "ChspsMaintenanceHandler::FindPluginsNode(): failed to find a plugins node" ) );
            }
        }
#endif
        
    return pluginsNode;
    }

// -----------------------------------------------------------------------------
// Appends a plugins list with a new plugin node
// -----------------------------------------------------------------------------
//
TInt ChspsMaintenanceHandler::AppendPluginConfigurationL(
        ChspsODT& aAppODT,
        ChspsDomNode& aPluginsNode,        
        const ChspsODT& aPluginODT,                
        const TInt aNewPosition,
        const TInt aNewPluginId )        
    {          
    TInt err = KErrGeneral;
    
    // Input validation
    if ( aPluginODT.ThemeUid() < 1 || aNewPluginId < 1 )
        {
        return KErrArgument;
        }
        
    // Find a node to be added, step over any optional xml elements 
    // (start cloning from the configuration element onwards)    
    ChspsDomDocument& appDom = aAppODT.DomDocument();
    ChspsDomDepthIterator* pluginIter = ChspsDomDepthIterator::NewL( *aPluginODT.DomDocument().RootNode() );
    CleanupStack::PushL( pluginIter );                                
    ChspsDomNode* node = pluginIter->First();                              
    TBool steppingtoConfNode(EFalse);                     
    while(node && !steppingtoConfNode)
        {
        const TDesC8& pluginNodeName = node->Name();
         
        // Find the Configuration element
        if( pluginNodeName == KConfigurationElement )
            {            
            steppingtoConfNode=ETrue;
            }
        else
            {
            node = pluginIter->NextL();
            }                 
        }
    CleanupStack::PopAndDestroy( pluginIter );
    
    if ( node )
        {
        // The node instance should now hold the configuration element etc        
        ChspsDomNode* confNode = node->CloneL( aPluginsNode.StringPool());
        CleanupStack::PushL( confNode );
                
        // Create a new plugin node with mandatory attributes
        ChspsDomNode* pluginNode = appDom.CreateElementNSL( 
            KPluginElement,         
            aPluginsNode.Namespace()            
            );
        CleanupStack::PushL( pluginNode );
                                       
        // Attach to the plugin node
        pluginNode->AddChildL( confNode );
        confNode->SetParent( pluginNode );
        
        // Set attributes of the plugin node                
        hspsServerUtil::AddAttributeNumericL( *pluginNode, KPluginAttrId, aNewPluginId );
        hspsServerUtil::AddAttributeNumericL( *pluginNode, KPluginAttrUid, aPluginODT.ThemeUid(), EHex );

        // Add active attribute.
        // If first plugin in list, then set as active.
        // Otherwise other plugin should already be active at this level.
        if( aPluginsNode.ChildNodes().Length() == 0 )
            {
            hspsServerUtil::AddAttributeDescL( *pluginNode, KPluginAttrActive, KPluginActiveStateActive );
            }
        else
            {
            hspsServerUtil::AddAttributeDescL( *pluginNode, KPluginAttrActive, KPluginActiveStateNotActive );
            }
        
        // Also make sure that if new node has child nodes, that they get active parameter also.
        hspsServerUtil::EditPluginNodeActivityL( pluginNode,
                                                 hspsServerUtil::EActivateFirst );
        
        // Check when to insert and when to add to the end
        if ( aNewPosition < 0 || aNewPosition >= aPluginsNode.ChildNodes().Length() )
            {
            // Append the plugin node to the end
            aPluginsNode.AddChildL( pluginNode );
            }
        else
            {
            // Insert the plugin node to the position
            aPluginsNode.AddChildL( pluginNode, aNewPosition );    
            }        
        pluginNode->SetParent( &aPluginsNode );
        
        CleanupStack::Pop( pluginNode );
        CleanupStack::Pop( confNode );
        err = KErrNone;
        }
                             
    return err;
    }

// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------
// ChspsMaintenanceHandler::HandlePluginReferencesL()
// ImportPlugins phase.
// -----------------------------------------------------------------------------
//
TInt ChspsMaintenanceHandler::HandlePluginReferencesL( 
        ChspsODT& aAppODT,
        ChspsODT& aPluginODT,        
        TInt& aLastConfId,
        TInt& aLastPluginId )
    {   
    
    ChspsDomDocument& pluginDom = aPluginODT.DomDocument(); 
    ChspsDomDepthIterator* iter = ChspsDomDepthIterator::NewL( *pluginDom.RootNode() );
    CleanupStack::PushL( iter );
            
    // Each configuration element get's an unique id value - same applies to the plugin elements.
    // The ids are then used to reference a specific configuration or plugin instance 
    // in the whole application configuration
        
    ChspsDomNode* node = iter->First();
    while( node )
        {            
        const TDesC8& name = node->Name();
        
        // Configuration element 
        if ( name == KConfigurationElement )
            {                                    
            // Generate an ID attribute for the configuration element
            aLastConfId++;
            hspsServerUtil::AddAttributeNumericL( *node, KConfigurationAttrId, aLastConfId );            
            }
        
        // Plugin element
        else if ( name == KPluginElement )
            {            
            // Check parent element
            ChspsDomNode* parentNode = node->Parent();
            const TDesC8& parentName = parentNode->Name();
            if( parentName == KPluginsElement )
                { 
                ChspsDomList& attrList = node->AttributeList();
                
                // Get configuration attribute from the plugin configuration                                                               
                ChspsDomAttribute* pluginUidAttr = 
                    static_cast<ChspsDomAttribute*> ( attrList.FindByName(KPluginAttrUid) );                                                
                if( !pluginUidAttr )
                    {
#ifdef HSPS_LOG_ACTIVE  
                    if( iLogBus )
                        {
                        iLogBus->LogText( _L( "ChspsMaintenanceHandler::HandlePluginReferencesL(): - Invalid XML" ) );
                        }
#endif                    
                    User::Leave( KErrCorrupt );
                    }         
                
                // Convert uids from string to numeric format                                        
                const TDesC8& pluginUidValue = pluginUidAttr->Value();                    
                const TUid pluginUid = hspsServerUtil::ConvertDescIntoUid(pluginUidValue);
                               
                // Get plugin configuration                                 
                ChspsODT* pluginOdt = ChspsODT::NewL();
                CleanupStack::PushL( pluginOdt );
                TInt err = iThemeServer.GetConfigurationL( 
                        0, 
                        pluginUid.iUid,
                        *pluginOdt );                
                if ( err )
                    {
#ifdef HSPS_LOG_ACTIVE  
                    if( iLogBus )
                        {
                        iLogBus->LogText( _L( "ChspsMaintenanceHandler::HandlePluginReferencesL(): - Failed to find a plugin" ) );
                        }
#endif

                    // Append an empty configuration with error status
                    AddErrorConfigurationL( 
                            pluginDom,
                            *node,
                            pluginUid.iUid );
                    
                    // Generate an ID attribute for the plugin element
                    aLastPluginId++;
                    hspsServerUtil::AddAttributeNumericL( *node, KPluginAttrId, aLastPluginId );                                        
                    }
                else
                    {
                    // Set value of the ID attribute
                    aLastPluginId++;
                    hspsServerUtil::AddAttributeNumericL( *node, KPluginAttrId, aLastPluginId );
                    
                                    
                    // Copy resources of the referenced plug-in instance to the application configuration
                    TInt resourceCount = pluginOdt->ResourceCount();
                    for ( TInt index=0; index < resourceCount; index++ )
                        {                    
                        ChspsResource& pluginResource = pluginOdt->ResourceL(index);
                        // Add only those that are located under the sources folder                                            
                        if ( pluginResource.FileName().FindF( KSourcesFolder ) > 0
                            || pluginResource.FileName().FindF( KLocalesFolder ) > 0 )
                                                
                            {                                                
                            ChspsResource* r = pluginResource.CloneL();
                            CleanupStack::PushL( r );
                            aAppODT.AddResourceL( r ); 
                            CleanupStack::Pop( r );
                            }
                        }
                    
                    ChspsDomDocument& document = pluginOdt->DomDocument();   
                    if ( !document.RootNode() )
                        {
                        User::Leave( KErrGeneral );
                        }
                    
                    // Find the KConfigurationElement to step over any optional xml elements 
                    ChspsDomDepthIterator* pluginIter = ChspsDomDepthIterator::NewL( *document.RootNode() );
                    CleanupStack::PushL( pluginIter );                                
                    ChspsDomNode* pluginNode =  pluginIter->First();                              
                    TBool steppingtoConfNode(EFalse);                     
                    while(pluginNode && !steppingtoConfNode)
                        {
                        const TDesC8& pluginNodeName = pluginNode->Name();
                         
                        if( pluginNodeName == KConfigurationElement )
                            {
                            steppingtoConfNode=ETrue;
                            }
                        else
                            {
                            pluginNode = pluginIter->NextL();
                            }                 
                        }
                    CleanupStack::PopAndDestroy( pluginIter );
                    
                    // Copy the plugin configuration to the main document.
                    ChspsDomNode* rootCopy = pluginNode->CloneL( node->StringPool());
                    rootCopy->SetParent( node );
                    node->AddChildL( rootCopy );
                    }
               
                CleanupStack::PopAndDestroy( pluginOdt );
                }
            }
        node = iter->NextL();      
        }
    CleanupStack::PopAndDestroy( iter );
    
    // Copy resources of the plugin to the application configuration    
    TInt resourceCount = aPluginODT.ResourceCount();
    for ( TInt index=0; index < resourceCount; index++ )
        {                    
        ChspsResource& pluginResource = aPluginODT.ResourceL(index);
        
        // Add only those that are located under the sources folder
        if ( pluginResource.FileName().FindF( KSourcesFolder ) > 0
              || pluginResource.FileName().FindF( KLocalesFolder ) > 0 )
            {                                                
            ChspsResource* r = pluginResource.CloneL();
            CleanupStack::PushL( r );
            aAppODT.AddResourceL( r ); 
            CleanupStack::Pop( r );
            }
        }
    
    return KErrNone;
    }


// -----------------------------------------------------------------------------
// Service for removing a plugin
// -----------------------------------------------------------------------------
//    
void ChspsMaintenanceHandler::ServiceRemovePluginL( const RMessage2& aMessage )
    {
    // Defaults
    ThspsServiceCompletedMessage ret = EhspsRemovePluginFailed;
    iResult->iXuikonError = KErrNotFound;
    TInt err = KErrNone;
    
    // Parameters
    RMessagePtr2 messagePtr = aMessage;
    
    // IPC slots: 
    // #0) output: externalized ChspsResult for error handling
    // #1) input: ThpsParamRemovePlugin struct
    
    // Get service parameters from IPC slot #1
    ThpsParamRemovePlugin params;        
    TPckg<ThpsParamRemovePlugin> packagedStruct(params);    
    aMessage.ReadL(1, packagedStruct);                        
    const TInt appUid = params.appUid;    
    const TInt pluginId = params.pluginId;               
        
    if ( pluginId < 1 )
        {
        err = KErrArgument;
        }
    
    // Application configuration
    ChspsODT *appODT = NULL;
    if ( !err )
        {    
        // Get active application configuration from the central repository
        TInt appConfUid;       
        err = iCentralRepository.Get( appUid, appConfUid );
        if ( err || appConfUid < 1 )
            {
            err = KErrNotFound;         
            }
        else
            {
            appODT = ChspsODT::NewL();
            CleanupStack::PushL( appODT );
            err = iThemeServer.GetConfigurationL( 
                    appUid, 
                    appConfUid,
                    *appODT );                                        
            }
        }

    // Modifications    
    if ( !err )
        {       
        if ( iDefinitionRepository.Locked() )
            {
            // Repository locked
            err = KErrAccessDenied;
            }
        else
            {
            TInt pluginUid;
            TBuf<KMaxFileName> pluginName;
            err = GetConfigurationNodeDataL(*appODT, 
                    pluginId,pluginUid, pluginName);
            // Lock the Plugin Repository (a.k.a. Def.rep)
            iDefinitionRepository.Lock();                                
            CleanupStack::PushL( TCleanupItem( UnlockRepository, &iDefinitionRepository ) );
            if( !err )
                {
                // Remove the plugin configuration from the application configuration
                err = RemoveConfigurationL( 
                    *appODT, 
                    pluginId );                                            
                }
            if ( !err )
                {

#ifdef HSPS_LOG_ACTIVE                
                if( appODT && iLogBus )
                    {
                    ChspsOdtDump::Dump( *appODT, *iLogBus );
                    }
#endif                
                // Stores the new application configuration into the repository
                err = iDefinitionRepository.SetOdtL( *appODT );
                if ( err )
                    {
#ifdef HSPS_LOG_ACTIVE  
                    if( iLogBus )
                        {
                        iLogBus->LogText( _L( "ChspsMaintenanceHandler::ServiceRemovePluginL(): - Updating failed" ) );
                        }
#endif                    
                    }
                }
            
            // Unlock after the changes have been done
            iDefinitionRepository.Unlock();
            CleanupStack::Pop(&iDefinitionRepository);

            if ( !err )
                {
                // Inform clients that the ODT has been modified
                ThspsRepositoryInfo info( 
                    ThspsRepositoryEvent(EhspsODTRemoved),
                    appODT->RootUid(),
                    appODT->ThemeUid(),
                    aMessage.SecureId().iId,
                    appODT->ProviderUid(),
                    0,0,
                    pluginUid,pluginId,ETrue,
                    pluginName,
                    (TLanguage)(appODT->OdtLanguage())
                    );                                
                iDefinitionRepository.RegisterNotification( info );
                }                                        
            }       
       }    
    
    // Cleaning
    if ( appODT )
        {
        CleanupStack::PopAndDestroy( appODT );
        appODT = NULL;
        }
    
    // Error handling
    iResult->iXuikonError = err;
    if ( !err )
        {        
        ret = EhspsRemovePluginSuccess;
        }
    
    // Completion 
    CompleteRequest( ret, messagePtr );
    }

// -----------------------------------------------------------------------------
// Service for setting plugin active.
// -----------------------------------------------------------------------------
//    
void ChspsMaintenanceHandler::ServiceSetActivePluginL( const RMessage2& aMessage )
    {
    // Init output parameters.       
    iResult->ResetData();
    
    // Read input parameters.
    ThpsParamSetActivePlugin params;
    TPckg<ThpsParamSetActivePlugin> packagedStruct( params );
    aMessage.ReadL( 1, packagedStruct );
    
    // Get uid of active application configuration.        
    TInt appConfUid = 0;       
    TInt err = iCentralRepository.Get( params.appUid, appConfUid );
    if ( err != KErrNone || appConfUid < 1 )
        {
        err = KErrNotFound;
        }
    
    // Load configuration from repository.
    ChspsODT* appODT = NULL;
    if( err == KErrNone )
        {
        appODT = ChspsODT::NewL();
        CleanupStack::PushL( appODT );
        err = iThemeServer.GetConfigurationL( 
                params.appUid, 
                appConfUid,
                *appODT );
        }

    // Initialize notification structure.
    ThspsRepositoryInfo notification( EhspsPluginActivated );
    if( err == KErrNone && appODT )
        {
        notification.iAppUid = appODT->RootUid();
        notification.iAppConfUid = appODT->ThemeUid();
        notification.iSecureId = 0;
        notification.iAppConfProviderUid = 0;
        notification.iPluginIfUid = 0;
        notification.iPluginProviderUid = 0;
        notification.iPluginUid = 0;
        notification.iPluginId = 0;
        notification.iLastNotification = ETrue;
        notification.iName = KNullDesC();
        notification.iLanguage = ELangTest;        
        }
    
    // Find required node and set it active.
    if( err == KErrNone )
        {
        // Find a plugin node with the provided id.
        ChspsDomNode* pluginNode = hspsServerUtil::FindPluginNodeL( *appODT,
                                                                    params.pluginId );
        if ( pluginNode )
            {        
            // Get parent node.
            ChspsDomNode* parentNode = pluginNode->Parent();
            if ( parentNode )
                {
                // Deactivate all plugins at defined level. Do not recurse.
                const TInt KDepth = 1;
                hspsServerUtil::EditPluginNodeActivityL( parentNode,
                                                         hspsServerUtil::EDeactivateAll,
                                                         KDepth );
    
                // Activate defined plugin.
                hspsServerUtil::AddAttributeDescL( *pluginNode,
                                                    KPluginAttrActive,
                                                    KPluginActiveStateActive ); 
                
                // Fill notification up2date.
                notification.iPluginUid = hspsServerUtil::GetPluginUid( pluginNode ).iUid;
                notification.iPluginId = hspsServerUtil::GetPluginId( pluginNode );
                }
            else
                {
                err = KErrCorrupt;
                }
            }
        else
            {
            err = KErrNotFound;
            }
        }
    
    if( err == KErrNone )
        {
        if ( iDefinitionRepository.Locked() )
            {
            // Repository locked
            err = KErrAccessDenied;
            }
        }
    
    if( err == KErrNone )
        {
        // Lock and push to cleanup stack.
        iDefinitionRepository.Lock();                                
        CleanupStack::PushL( TCleanupItem( UnlockRepository, &iDefinitionRepository ) );
        
        // Stores the new application configuration into the repository
        err = iDefinitionRepository.SetOdtL( *appODT );

        // Unlock and remove from cleanupstack.
        iDefinitionRepository.Unlock();
        CleanupStack::Pop( &iDefinitionRepository );
        }
    
    // Notify.
    if( err == KErrNone )
        {
        iDefinitionRepository.RegisterNotification( notification );
        }
    
    // Set output parameter values and complete request.    
    iResult->iSystemError = err;
    iResult->iXuikonError = err;
    
    // Complete the message.    
    RMessagePtr2 messagePtr = aMessage;    
    if( err == KErrNone )
        {
        CompleteRequest( EhspsSetActivePluginSuccess, messagePtr );
        }
    else
        {
        CompleteRequest( EhspsSetActivePluginFailed, messagePtr );
        }    
    
#ifdef HSPS_LOG_ACTIVE                
        if( iLogBus )
            {
            ChspsOdtDump::Dump( *appODT, *iLogBus );
            }
#endif    
        
    // Cleanup.
    if ( appODT )
        {
        CleanupStack::PopAndDestroy( appODT );
        appODT = NULL;
        }    

#ifdef HSPS_LOG_ACTIVE                
    if( iLogBus )
        {
        if( err == KErrNone )
            {
            iLogBus->LogText( _L( "ChspsMaintenanceHandler::ServiceSetActivePluginL: - OK" ) );
            }
        else
            {
            iLogBus->LogText( _L( "ChspsMaintenanceHandler::ServiceSetActivePluginL: - Error" ) );
            }
        }
#endif      
    }

// -----------------------------------------------------------------------------
// Get plugin's configuration node attributes(plugin name, pluginUid ) 
// Can expanded to get configuration Id and plugin type also
// -----------------------------------------------------------------------------
//
TInt ChspsMaintenanceHandler::GetConfigurationNodeDataL(
        ChspsODT& aAppODT,
        const TInt aPluginId,
        TInt& aPluginUid,
        TDes& aPluginName )
    {
    TInt err = KErrNotFound;
    ChspsDomNode *node = hspsServerUtil::FindPluginNodeL( aAppODT, aPluginId );
    if ( node )
        {
        ChspsDomDepthIterator* iter = ChspsDomDepthIterator::NewL( *node );
        CleanupStack::PushL( iter );

            // Find a configuration node with an id attribute that matches the provided id
        ChspsDomNode* node2 = iter->First();
        TBool jobDone = EFalse;
        while( node2 && !jobDone )
           {               
           const TDesC8& name = node2->Name();
                
            // An element was found 
            if ( name == KConfigurationElement )
                {
                TInt pluginUid = 0;
                TBuf<KMaxFileName> pluginName;
                ChspsDomList& attrList = node2->AttributeList();                 
                ChspsDomAttribute* pluginUidAttr = 
                static_cast<ChspsDomAttribute*> ( attrList.FindByName(KConfigurationAttrUid) );                                                
                if( !pluginUidAttr )
                    {
#ifdef HSPS_LOG_ACTIVE  
                    if( iLogBus )
                        {
                        iLogBus->LogText( _L( "ChspsMaintenanceHandler::GetConfigurationNodeDataL(): - Invalid XML" ) );
                        }
#endif                    
                    err = KErrGeneral;
                    }         
                else            
                    {
                                    // Convert uids from string to numeric format                                        
                    const TDesC8& pluginUidValue = pluginUidAttr->Value();                    
                    const TUid uid = hspsServerUtil::ConvertDescIntoUid(pluginUidValue);               
                    if ( uid.iUid > 0 )
                       {                   
                       pluginUid = uid.iUid;
                       // Override default status
                       err = KErrNone;
                       }
                    }
                if( !err )
                    {
                    ChspsDomAttribute* pluginUidNameAttr = 
                    static_cast<ChspsDomAttribute*> ( attrList.FindByName(KConfigurationAttrName) );                                                
                    if( !pluginUidNameAttr )
                        {
#ifdef HSPS_LOG_ACTIVE  
                        if( iLogBus )
                            {
                            iLogBus->LogText( _L( "ChspsMaintenanceHandler::GetConfigurationNodeDataL(): - Invalid XML" ) );
                            }
#endif                        
                        err = KErrGeneral;
                        }         
                    else            
                        {
                        // Convert uids from string to numeric format                                        
                        const TDesC8& pluginNameValue = pluginUidNameAttr->Value();                                   
                        if ( pluginNameValue.Length() > 0 )
                            {                   
                            pluginName.Copy( pluginNameValue );
                            err = KErrNone;
                            }
                        }            
                    }
                if( !err )
                    {
                    aPluginUid = pluginUid;
                    aPluginName.Copy( pluginName );
                    jobDone = ETrue;
                    }
                }
            node2 = iter->NextL();
           }
        CleanupStack::PopAndDestroy( iter );
        }

         
    return err;
    }
    
// -----------------------------------------------------------------------------
// ChspsMaintenanceHandler::ServiceReplacePluginL()
// -----------------------------------------------------------------------------
//
void ChspsMaintenanceHandler::ServiceReplacePluginL( const RMessage2& aMessage )
    {
    // Defaults
    ThspsServiceCompletedMessage ret = EhspsReplacePluginFailed;
    iResult->iXuikonError = KErrNotFound;
    TInt err = KErrNone;
    
    // Parameters
    RMessagePtr2 messagePtr = aMessage;
    
    // IPC slots: 
    // #0) output: externalized ChspsResult for error handling
    // #1) input: ThpsParamReplacePlugin struct                
    ThspsParamReplacePlugin params;        
    TPckg<ThspsParamReplacePlugin> packagedStruct(params);    
    aMessage.ReadL(1, packagedStruct);
    const TInt appUid( params.appUid );
    const TInt pluginId( params.pluginId );    
    const TInt confUid( params.confUid );                              
    if ( pluginId < 1 || confUid  < 1 )
        {
        err = KErrArgument;
        }
    
    // Application configuration
    ChspsODT *appODT = NULL;
    if ( !err )
        {    
        // Get active application configuration from the central repository
        TInt appConfUid;       
        err = iCentralRepository.Get( appUid, appConfUid );
        if ( err || appConfUid < 1 )
            {
            err = KErrNotFound;         
            }
        else
            {
            appODT = ChspsODT::NewL();
            CleanupStack::PushL( appODT );
            err = iThemeServer.GetConfigurationL( 
                    appUid, 
                    appConfUid,
                    *appODT );                                        
            }
        }
        
    // Plugin configuration
    ChspsODT *pluginODT = NULL;
    if ( !err )
        {
        // Find the plugin configuration (interface is unknown, so 1st argument is set to zero)
        pluginODT = ChspsODT::NewL();
        CleanupStack::PushL( pluginODT );        
        err = iThemeServer.GetConfigurationL( 
                0, 
                confUid,
                *pluginODT );
        }

    // Check needed space for replace. Returns system wide error code.
    if( !err )
        {
        err = hspsServerUtil::EnoughDiskSpaceAvailableL(
                *pluginODT, 
                iThemeServer.DeviceLanguage(),
                iServerSession->FileSystem(),
                EDriveC,
                KAdditionalRequiredDiskSpace );
        }
    
    // Modifications    
    if ( !err )
        {       
        if ( iDefinitionRepository.Locked() )
            {
            // Repository locked
            err = KErrAccessDenied;
            }
        else
            {                        
            // Lock the Plugin Repository (a.k.a. Def.rep)
            iDefinitionRepository.Lock();                                
            CleanupStack::PushL( TCleanupItem( UnlockRepository, &iDefinitionRepository ) );            
            
            // Remove the plugin configuration from the application configuration
            err = ReplaceConfigurationL( 
                *appODT, 
                pluginId,
                *pluginODT );                                            
            if ( !err )
                {

#ifdef HSPS_LOG_ACTIVE                
                if( appODT && iLogBus )
                    {
                    ChspsOdtDump::Dump( *appODT, *iLogBus );
                    }
#endif                
                // Stores the new application configuration into the repository
                err = iDefinitionRepository.SetOdtL( *appODT );
                // Unlock after the changes have been done
                iDefinitionRepository.Unlock();
                if ( err )
                    {
#ifdef HSPS_LOG_ACTIVE  
                    if( iLogBus )
                        {
                        iLogBus->LogText( _L( "ChspsMaintenanceHandler::ServiceReplacePluginL(): - Updating failed" ) );
                        }
#endif                    
                    }
                else
                    {
                    // Inform clients that the ODT has been modified
                    ThspsRepositoryInfo info( 
                        ThspsRepositoryEvent(EhspsPluginReplaced),
                        appODT->RootUid(),
                        appODT->ThemeUid(),
                        aMessage.SecureId().iId,
                        0,
                        0,
                        0,
                        confUid,
                        pluginId,
                        ETrue,
                        KNullDesC(),
                        (TLanguage)(appODT->OdtLanguage())
                        );                                
                    iDefinitionRepository.RegisterNotification( info );
                    }
                }
            else
                {
                // Unlock repository
                iDefinitionRepository.Unlock();
                }
            
            CleanupStack::Pop(&iDefinitionRepository);
            }       
        }
    
    // Cleaning
    if ( pluginODT )
        {
        CleanupStack::PopAndDestroy( pluginODT );
        }    
    if ( appODT )
        {
        CleanupStack::PopAndDestroy( appODT );
        appODT = NULL;
        }

    // Error handling
    iResult->iXuikonError = err;
    if ( !err )
        {
        ret = EhspsReplacePluginSuccess;
        }
    
    // Completion 
    CompleteRequest( ret, messagePtr );
    }

// -----------------------------------------------------------------------------
// ChspsMaintenanceHandler::ReplaceConfigurationL()
// -----------------------------------------------------------------------------
//
TInt ChspsMaintenanceHandler::ReplaceConfigurationL(
        ChspsODT& aAppODT,
        const TInt aPluginId,
        const ChspsODT& aPluginODT )
    {           
    // Input validation
    if ( aAppODT.ConfigurationType() != EhspsAppConfiguration 
            || aAppODT.ThemeUid() < 1
            || aPluginId < 1
            || aPluginODT.ConfigurationType() == EhspsAppConfiguration            
            || aPluginODT.ThemeUid() < 1 )
        {
        return KErrArgument;
        }
    
    TInt err = KErrNotFound;
    
    // Find a plugin node with the provided plugin id    
    ChspsDomNode* pluginNode = hspsServerUtil::FindPluginNodeL( aAppODT, aPluginId);
    if ( pluginNode )
        {
        ChspsDomNode* pluginsNode = pluginNode->Parent();
        
        // Get current position in the plugins list
        TInt currentPosition = FindPluginPosition( *pluginNode );
        if ( currentPosition < 0 )
            {
            User::Leave( KErrGeneral );
            }
        
        // Get configuration id from existing configuration
        ChspsDomNode* oldConfNode = (ChspsDomNode *)pluginNode->ChildNodes().Item( 0 );
        if ( !oldConfNode )
            {
            User::Leave( KErrGeneral );
            }                                        
        ChspsDomList& attrList = oldConfNode->AttributeList();
        ChspsDomAttribute* attr = static_cast<ChspsDomAttribute*>( attrList.FindByName(KConfigurationAttrId) );
        if ( !attr )
           {               
           User::Leave( KErrGeneral );
           }                
        const TInt oldConfId = hspsServerUtil::DecString2Int( attr->Value() );
        oldConfNode = 0;
                
        // Remove old plugin configuration instance and it's resources from the application configuration
        err = RemoveConfigurationL( aAppODT, aPluginId );        
        if ( err )
            {
            User::Leave( KErrGeneral );
            }
        pluginNode = 0;
        
        // Find configuration node from the plugin ODT        
        ChspsDomNode* confNode = aPluginODT.DomDocument().RootNode();
        if ( confNode->Name().CompareF(KConfigurationElement) != 0 )
            {
            User::Leave( KErrGeneral ); 
            }                                       
                                             
        // Add configuration id attribute        
        hspsServerUtil::AddAttributeNumericL( *confNode, KConfigurationAttrId, oldConfId );                               
        
        // Append new plugin configuration node to the application configuration
        err = AppendPluginConfigurationL(                              
                aAppODT, 
                *pluginsNode,
                aPluginODT,
                currentPosition,
                aPluginId );            
        
        if( !err )
            {
            // Add resources of the new plugin into the application configuration
            AddPluginResourcesL( 
                    aAppODT, 
                    aPluginODT.ThemeUid() );
            }            
        }
        
    return err;
    }

TInt ChspsMaintenanceHandler::FindPluginPosition(     
        ChspsDomNode& aPluginNode )
    {
    TInt pos = -1;        
    ChspsDomList& childList = aPluginNode.Parent()->ChildNodes();
    for( TInt nodeIndex=0; nodeIndex < childList.Length(); nodeIndex++ )
        {
        ChspsDomNode* node = (ChspsDomNode *)childList.Item( nodeIndex );
        
        if ( node == &aPluginNode )
            {
            pos = nodeIndex;            
            break;
            }
        }
    return pos;
    }


// -----------------------------------------------------------------------------
// ChspsMaintenanceHandler::SetLogBus()
// -----------------------------------------------------------------------------
//
#ifdef HSPS_LOG_ACTIVE        
void ChspsMaintenanceHandler::SetLogBus( ChspsLogBus* aLogBus )
    {
    iLogBus = aLogBus;
    }
#endif

// -----------------------------------------------------------------------------
// ChspsMaintenanceHandler::IsViewConfiguration()
// -----------------------------------------------------------------------------
//
TBool ChspsMaintenanceHandler::IsViewConfiguration(
        ChspsDomNode& aPluginNode )
    {
    TBool isView = EFalse;
    
    ChspsDomNode* confNode = static_cast<ChspsDomNode*>(
            aPluginNode.ChildNodes().FindByName( KConfigurationElement ));
    
    if( confNode )
        {
        ChspsDomAttribute* typeAttr = static_cast<ChspsDomAttribute*>(
                confNode->AttributeList().FindByName( KConfigurationAttrType ));
        
        if( typeAttr )
            {
            isView = ( typeAttr->Value().CompareF( KConfTypeView ) == 0 ); 
            }     
        }
    
    return isView;
    }

// -----------------------------------------------------------------------------
// ChspsMaintenanceHandler::RemoveConfigurationL()
// -----------------------------------------------------------------------------
//
TInt ChspsMaintenanceHandler::RemoveConfigurationL(
        ChspsODT& aAppODT,
        const TInt aPluginId )
    {
    TInt err = KErrNotFound;
    
    // Find a plugin node with the provided id
    ChspsDomNode *pluginNode = hspsServerUtil::FindPluginNodeL( aAppODT, aPluginId );
    if ( pluginNode )
        {
        // Remove the node
        err = RemoveConfigurationL( aAppODT, *pluginNode );
        }
    
    return err;    
    }

// -----------------------------------------------------------------------------
// Removes an plugin instance from the provided application configuration
// -----------------------------------------------------------------------------
//
TInt ChspsMaintenanceHandler::RemoveConfigurationL(
        ChspsODT& aAppODT,
        ChspsDomNode& aPluginNode )
    {
    TInt err = KErrNotFound;
                   
    // Get parent node
    ChspsDomNode *parentNode = aPluginNode.Parent();
    if ( parentNode )
        {                                            
        ChspsDomList& attrList = aPluginNode.AttributeList();
                   
        // Get uid attribute from the node
        TInt pluginUid = 0;            
        ChspsDomAttribute* pluginUidAttr = 
            static_cast<ChspsDomAttribute*> ( attrList.FindByName(KPluginAttrUid) );                                                
        if( !pluginUidAttr )
            {
#ifdef HSPS_LOG_ACTIVE  
            if( iLogBus )
                {
                iLogBus->LogText( _L( "ChspsMaintenanceHandler::RemoveConfigurationL(): - Invalid XML" ) );
                }
#endif
            
            err = KErrGeneral;
            }         
        else            
            {
            // Convert uids from string to numeric format                                        
            const TDesC8& pluginUidValue = pluginUidAttr->Value();                    
            const TUid uid = hspsServerUtil::ConvertDescIntoUid(pluginUidValue);                
            if ( uid.iUid > 0 )
                {                    
                pluginUid = uid.iUid;
                // Override default status
                err = KErrNone;
                }
            }

        // Store activity state for use after deletion.
        TBool pluginWasActive = EFalse;
        ChspsDomAttribute* pluginActivityAttr = 
            static_cast<ChspsDomAttribute*>( attrList.FindByName( KPluginAttrActive ) );                                                
        if( pluginActivityAttr )
            {
            if( pluginActivityAttr->Value().CompareF( KPluginActiveStateActive ) == 0 )
                {
                pluginWasActive = ETrue;
                }
            }
                        
        if ( !err )
            {            
            // If user is removing a view plugin
            if( IsViewConfiguration( aPluginNode ) )
                {
                // first all subplugins need to be removed, so that the application's resource array 
                // (visible in ODT dump) contains only valid resources
                ChspsDomNode* confNode = 
                    (ChspsDomNode*)aPluginNode.ChildNodes().FindByName( KConfigurationElement );
                if( confNode )
                    {
                    ChspsDomNode* controlNode = 
                            (ChspsDomNode*)confNode->ChildNodes().FindByName( KControlElement );
                    if( controlNode )
                        {
                        ChspsDomNode *pluginsNode = 
                                (ChspsDomNode*)controlNode->ChildNodes().FindByName( KPluginsElement );
                        if( pluginsNode )
                            {
                            RPointerArray<ChspsDomNode> nodeArray;
                            CleanupClosePushL( nodeArray );
                            
                            // Get plugin nodes
                            TInt pluginCount = pluginsNode->ChildNodes().Length();
                            for( TInt pluginIndex=0; pluginIndex < pluginCount; pluginIndex++ )                                    
                                {
                                nodeArray.Append( (ChspsDomNode*)pluginsNode->ChildNodes().Item( pluginIndex ) );
                                }                                
                            
                            // Remove the nodes and related resources
                            for( TInt pluginIndex=0; pluginIndex < pluginCount; pluginIndex++ )
                                {
                                RemoveConfigurationL( aAppODT, *nodeArray[pluginIndex ] );
                                }
                            
                            nodeArray.Reset();
                            CleanupStack::PopAndDestroy( 1, &nodeArray );
                            }                                                            
                        }
                    }                
                }
        
            // Get number of plugin instances with the plugin uid
            TInt instanceCount = 0;
            GetPluginInstanceCountL( 
                aAppODT, 
                pluginUid, 
                instanceCount );                                                        
                
            // Remove plugin resources from the application configuration:
            // By default remove all plugin's resources from all instances
            // - otherwise, after upgrades, there might be various versions of the same resources
            err = RemovePluginResourcesL( aAppODT, pluginUid );
            if ( !err )
                {
                // If the application configuration holds other instances of the same plugin                     
                if ( instanceCount > 1 )
                    {
                    // Put back the resources
                    AddPluginResourcesL( 
                            aAppODT,
                            pluginUid );
                    }
                
                // Remove the plugin node from the plugins node    
                parentNode->DeleteChild( &aPluginNode );
                }                
            }

        // If plugin was succesfully deleted and was active ->
        // need set another plugin active.
        // ( Choose to activate topmost item. )
        // ( Use depth of 1 to affect only one level. )
        if ( !err && pluginWasActive )
            {
            const TInt KDepth = 1;
            hspsServerUtil::EditPluginNodeActivityL( parentNode,
                                                     hspsServerUtil::EActivateFirst,
                                                     KDepth );       
            }
        }        

    return err;
    }

//----------------------------------------------------------------------------
// Finds a plugin node with the provided id which is also a children of 
// the provided plugins node 
// ----------------------------------------------------------------------------
//
ChspsDomNode* ChspsMaintenanceHandler::FindChildPluginNode(
        ChspsDomNode& aPluginsNode,
        const TInt aPluginId )
    {
    ChspsDomNode* pluginNode = NULL;
    
    // Loop child nodes
    ChspsDomList& childList = aPluginsNode.ChildNodes();
    for( TInt nodeIndex=0; nodeIndex < childList.Length(); nodeIndex++ )
        {
        // Find a specific node with the provided id value
        ChspsDomNode* node = (ChspsDomNode *)childList.Item( nodeIndex );
        if ( node )
            {
            // Find the ID attribute
            ChspsDomList& attrList = node->AttributeList();
            ChspsDomAttribute* attr = static_cast<ChspsDomAttribute*>( attrList.FindByName(KPluginAttrId) );
            if ( attr )
                {
                TInt id = 0;
                const TDesC8& idValue = attr->Value();
                TLex8 lex( idValue );                                
                if ( lex.Val( id ) == 0 && id == aPluginId )
                    {                                    
                    pluginNode = node;
                    break;
                    }
                }
            }
        }
    
    return pluginNode;
    }

// -----------------------------------------------------------------------------
// Returns a count of plugin instances.
// -----------------------------------------------------------------------------
//
void ChspsMaintenanceHandler::GetPluginInstanceCountL(
        const ChspsODT& aAppODT,        
        const TInt aPluginUid,
        TInt& aInstanceCount )
                
    {        
    aInstanceCount = 0;
    
    ChspsDomDocument& dom = aAppODT.DomDocument();
    ChspsDomDepthIterator* iter = ChspsDomDepthIterator::NewL( *dom.RootNode() );
    CleanupStack::PushL( iter );

    // Find a plugin node with the provided id attribute
    ChspsDomNode* node = iter->First();
    ChspsDomNode* prevNode = NULL;
    TBool jobDone = EFalse;
    while( node && !jobDone && prevNode != node )
        {                
        const TDesC8& name = node->Name();
        
        // Plugin element was found 
        if ( name == KPluginElement )
            {           
            ChspsDomList& attrList = node->AttributeList();                    
            ChspsDomAttribute* attr = static_cast<ChspsDomAttribute*>( attrList.FindByName(KPluginAttrUid) );            
            if ( !attr )
                {
                // Mandatory information is missing for some reason (should be set at installation handler)!
                // Exit with NULL
                jobDone = ETrue;                
                }
            else
                {
                // Convert from (hex?) string into TUid presentation
                const TUid uid = hspsServerUtil::ConvertDescIntoUid( attr->Value() );                            
                if ( aPluginUid == uid.iUid )
                    {
                    aInstanceCount++;
                    }
                }
            }
        
        prevNode = node;        
        node = iter->NextL();        
        }
    CleanupStack::PopAndDestroy( iter );    
    }

// -----------------------------------------------------------------------------
// Removes plugin resources from the provided ODT
// -----------------------------------------------------------------------------
//
TInt ChspsMaintenanceHandler::RemovePluginResourcesL(
        ChspsODT& aAppODT,
        const TInt aPluginUid )        
    {            
    // Loop resources of the application configuration            
    for(TInt aresIndex = 0; aresIndex < aAppODT.ResourceCount(); aresIndex++ )
        {
        ChspsResource& ares = aAppODT.ResourceL( aresIndex );
                                
        // If the plugin resource was found at  resource list of the application configuration                        
        if ( ares.ConfigurationUid() == aPluginUid )
            {
            // Deletes resource from the application configuration
            aAppODT.DeleteResourceL( aresIndex );
            aresIndex--;
            }
        
        }                
    
    return KErrNone;
    }

// -----------------------------------------------------------------------------
// Adds plugin resources to the provided application ODT
// -----------------------------------------------------------------------------
//
void ChspsMaintenanceHandler::AddPluginResourcesL(
        ChspsODT& aAppODT,
        const TInt aPluginUid )
    {    
    // Get plugin ODT
    ChspsODT* pluginODT = ChspsODT::NewL();         
    CleanupStack::PushL( pluginODT );
    TInt ret = iThemeServer.GetConfigurationL( 
            0, 
            aPluginUid,
            *pluginODT );
    
    if ( !ret && pluginODT->ThemeUid() )
        {                   
        // Copy resources of the referenced plug-in instance to the application configuration
        TInt resourceCount = pluginODT->ResourceCount();
        for ( TInt index=0; index < resourceCount; index++ )
            {                    
            ChspsResource& pluginResource = pluginODT->ResourceL(index);
            // Add only those that are located under the sources folder                                            
            if ( pluginResource.FileName().FindF( KSourcesFolder ) > 0
                || pluginResource.FileName().FindF( KLocalesFolder ) > 0 )                               
                {                                                
                ChspsResource* r = pluginResource.CloneL();
                CleanupStack::PushL( r );
                aAppODT.AddResourceL( r ); 
                CleanupStack::Pop( r );
                }
            }
        }
    
    if ( pluginODT )
        {
        CleanupStack::PopAndDestroy( pluginODT );        
        }
    }

// -----------------------------------------------------------------------------
// Service for personalizing settings
// -----------------------------------------------------------------------------
//    
void ChspsMaintenanceHandler::ServiceSetPluginSettingsL( const RMessage2& aMessage )
    {
    // Defaults
    ThspsServiceCompletedMessage ret = EhspsSetPluginSettingsFailed;
    iResult->iXuikonError = KErrNotFound;
    TInt err = KErrNone;
    
    // Parameters
    RMessagePtr2 messagePtr = aMessage;
     
    TBuf8<KMaxHeaderDataLength8> setMaskData;
  
    
    ChspsODT* odt = NULL;   
    TInt appConfUid;
    TInt pluginId;
    TBool storingStatus(EFalse);
    
    // Checking active congiruation and security
    messagePtr.ReadL(1,setMaskData,0);
    
    if (iSetMask)
         {
         delete iSetMask;
         iSetMask = NULL;
         }
    
    iSetMask = ChspsODT::NewL();
    iSetMask->UnMarshalHeaderL( setMaskData );
      
    iCentralRepository.Get( iSetMask->RootUid(), appConfUid );
                         
    // Getting active configuration
    odt = ChspsODT::NewL();
    CleanupStack::PushL(odt);
       
    err = iThemeServer.GetConfigurationL( 
                        iSetMask->RootUid(), 
                        appConfUid,
                        *odt );  
    
    if (iSetMask)
        {
        delete iSetMask;
        iSetMask = NULL;
        }
    
    // Set settings to active configuration
    if( !err  )
        {
        if( iDefinitionRepository.Locked() )
            {
            // Repository locked
            err = KErrAccessDenied;
            }
        else
            {
            // Lock the Plugin Repository (a.k.a. Def.rep)
            iDefinitionRepository.Lock();
            CleanupStack::PushL( TCleanupItem( UnlockRepository, &iDefinitionRepository ) );
            //Read pluginID
            // Get configuration
            ThspsParamSetPluginSettings params;        
            TPckg<ThspsParamSetPluginSettings> packagedStruct(params);    
                
            messagePtr.ReadL( 2, packagedStruct );
                
            pluginId = params.pluginId ;
            storingStatus = params.storingStatus ;
            
            
            
            // read Domdata
            HBufC8* domData = HBufC8::NewL( messagePtr.GetDesLengthL( 3 ) );
            CleanupStack::PushL( domData );
            TPtr8 domPtr = domData->Des();
            messagePtr.ReadL( 3, domPtr, 0 );
            RDesReadStream readBuf( *domData );
            CleanupClosePushL( readBuf );
            
            ChspsDomDocument* domDocument = ChspsDomDocument::NewL( readBuf );
            
            CleanupStack::PopAndDestroy( &readBuf );
            CleanupStack::PopAndDestroy( domData );
            
            CleanupStack::PushL( domDocument );
            err = hspsSetPluginSettingsL( *odt, pluginId, *domDocument );
            
            if( !err )
                {

#ifdef HSPS_LOG_ACTIVE             
                if( odt && iLogBus )
                    {
                    ChspsOdtDump::Dump( *odt, *iLogBus );
                    }
#endif
                // Stores the new application configuration into the repository
                err = iDefinitionRepository.SetOdtL( *odt );               
                
                if( !err )
                    {
#ifdef HSPS_LOG_ACTIVE  
                    if( iLogBus )
                        {
                        iLogBus->LogText( _L( "ChspsMaintenanceHandler::ServiceSetPluginSettingsL(): - Updating Success" ) );
                        }
#endif                    
                    }
                }
            CleanupStack::PopAndDestroy( domDocument );
            
            // Unlock after the changes have been done
            iDefinitionRepository.Unlock();
            CleanupStack::Pop(&iDefinitionRepository);
            
            if( storingStatus )
                {
                // Lock the Plugin Repository (a.k.a. Def.rep)
                iDefinitionRepository.Lock();
                CleanupStack::PushL( TCleanupItem( UnlockRepository, &iDefinitionRepository ) );
                
                ChspsDomNode* pluginNode = hspsServerUtil::FindPluginNodeL( *odt, pluginId );
        
                if( pluginNode )
                    { 
                      
                    ChspsDomList& attrList = pluginNode->AttributeList();
                    // Get configuration attribute from the plugin configuration                                                               
                    ChspsDomAttribute* pluginUidAttr = static_cast<ChspsDomAttribute*> ( attrList.FindByName(KPluginAttrUid) );                                                
                    
                    if( pluginUidAttr )
                        {               
                         
                        // Convert uids from string to numeric format                                        
                        const TDesC8& pluginUidValue = pluginUidAttr->Value();                    
                        const TUid pluginUid = hspsServerUtil::ConvertDescIntoUid(pluginUidValue);
                        // Get plugin configuration                                 
                        ChspsODT* pluginOdt = ChspsODT::NewL();
                        CleanupStack::PushL( pluginOdt );
                          
                        err = iThemeServer.GetConfigurationL( 
                                          0, 
                                          pluginUid.iUid,
                                          *pluginOdt ); 
                          
                        if( !err )
                            {
                            // read Domdata
                             HBufC8* domData = HBufC8::NewL( messagePtr.GetDesLengthL( 3 ) );
                             CleanupStack::PushL( domData );
                             TPtr8 domPtr = domData->Des();
                             messagePtr.ReadL( 3, domPtr, 0 );
                             RDesReadStream readBuf( *domData );
                             CleanupClosePushL( readBuf );
                              
                             ChspsDomDocument* domDocument = ChspsDomDocument::NewL( readBuf );
                              
                             CleanupStack::PopAndDestroy( &readBuf );
                             CleanupStack::PopAndDestroy( domData );
                              
                             CleanupStack::PushL( domDocument );
                              
                             err = hspsSavePluginSettingsL( *pluginOdt, *domDocument );
                                                        
                             if( !err )
                                 {
#ifdef HSPS_LOG_ACTIVE                             
                                 if( odt && iLogBus )
                                      {
                                      ChspsOdtDump::Dump( *pluginOdt, *iLogBus );
                                      }
#endif
                                  // Stores the new application configuration into the repository
                                 err = iDefinitionRepository.SetOdtL( *pluginOdt );               
                                                  
                                 if( !err )
                                     {
#ifdef HSPS_LOG_ACTIVE                  
                                      if( iLogBus )
                                          {
                                          iLogBus->LogText( _L( "ChspsMaintenanceHandler::ServiceSetPluginSettingsL(): - Updating plugin reference Success" ) );
                                          }
#endif                    
                                     }
                                  }                     
                              CleanupStack::PopAndDestroy( domDocument );
                              }
                          if ( pluginOdt )
                              {
                              CleanupStack::PopAndDestroy( pluginOdt );
                              pluginOdt = NULL;
                              }
                                                  
                          }
                      else
                          {
                          err = KErrCorrupt;
                          }
                      }
                  else
                      {
                      err = KErrNotFound;
                      }
                
                // Unlock after the changes have been done
                iDefinitionRepository.Unlock();
                CleanupStack::Pop(&iDefinitionRepository);
                }
           
            if ( !err )
                {
                // Inform clients that the ODT has been modified
                ThspsRepositoryInfo info( 
                   ThspsRepositoryEvent(EhspsSettingsChanged),
                   odt->RootUid(),
                   odt->ThemeUid(),
                   aMessage.SecureId().iId, //=Any file
                   odt->ProviderUid(),
                   0,0,
                   0,pluginId,ETrue,odt->ThemeFullName(),
                   (TLanguage)(odt->OdtLanguage())
                    );                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          
                iDefinitionRepository.RegisterNotification( info );         
                }
            }     
        }

    // Cleaning
    if (odt)
        {
        CleanupStack::PopAndDestroy( odt );
        odt = NULL;
        }
    
    // Error handling
    iResult->iXuikonError = err;
    if ( !err )
        {       
        ret = EhspsSetPluginSettingsSuccess;
        }
    
    // Completion 
    CompleteRequest( ret, messagePtr );
    }

// -----------------------------------------------------------------------------
//
// Service to get plugin Odt according plugin uid
// packed parameters 
// -----------------------------------------------------------------------------
//
void ChspsMaintenanceHandler::ServiceGetPluginOdtL( const RMessage2& aMessage )
    {
#ifdef HSPS_LOG_ACTIVE  
    if( iLogBus )
        {
        iLogBus->LogText( _L( "ChspsMaintenanceHandler::ServiceGetPluginOdtL: - service called" ) );
        }
#endif
    
    iMessagePtr = aMessage;
    TInt err = KErrNone;

    // Get configuration
    ThspsParamGetPluginOdt params;        
    TPckg<ThspsParamGetPluginOdt> packagedStruct(params);    
    iMessagePtr.ReadL(1, packagedStruct); 
    
    ChspsODT* odt = ChspsODT::NewL();
    CleanupStack::PushL( odt );
    err = iThemeServer.GetConfigurationL( 0, params.pluginUid, *odt );

    if( !err )
        {
        TPath odtPath;
        // Resolve odt path if no errors were occured 
        iDefinitionRepository.GetResourcePathL( *odt, EResourceODT, odtPath );
        TPckg<ThspsParamGetPluginOdt> packagedStruct( params ); 
        iMessagePtr.WriteL(2, odtPath);
        }
#ifdef HSPS_LOG_ACTIVE
    else
        {
        if( iLogBus )
            {
            iLogBus->LogText( _L( "ChspsMaintenanceHandler::ServiceGetPluginOdtL: - error occured during GetConfigurationL()" ) );
            }
        }
#endif            
    
    CleanupStack::PopAndDestroy( odt );

    // Error handling
    iResult->iXuikonError = err;

    if ( err )
        {
#ifdef HSPS_LOG_ACTIVE  
        if( iLogBus )
            {
            iLogBus->LogText( _L( "ChspsMaintenanceHandler::ServiceGetPluginOdtL: - EhspsGetPluginOdtFailed code: %d" ), err );
            }
#endif
        
        CompleteRequest( EhspsGetPluginOdtFailed, iMessagePtr );
        }
    else
        {
#ifdef HSPS_LOG_ACTIVE  
        if( iLogBus )
            {
            iLogBus->LogText( _L( "ChspsMaintenanceHandler::ServiceGetPluginOdtL: - EhspsGetPluginOdtSuccess" ) );
            }
#endif

        CompleteRequest( EhspsGetPluginOdtSuccess, iMessagePtr );
        }
        
    } 


// -----------------------------------------------------------------------------
// hspsMaintenanceHandler::hspsSetPluginSettings

// -----------------------------------------------------------------------------
//
TInt ChspsMaintenanceHandler::hspsSetPluginSettingsL(  ChspsODT& aOdt,
                               TInt aPluginId,  ChspsDomDocument&  aDom )
    {
    TInt error = KErrNotFound;
    
    
    TUint value = aPluginId;
   
        // Find a plugin node with the provided id
        ChspsDomNode* pluginNode = hspsServerUtil::FindPluginNodeL( aOdt, value );
        if( !pluginNode )
            {
            error =  KErrNotFound;
            return error;
            }
        ChspsDomNode* controlNode = &(FindNodeByTagL(KControlElement, *pluginNode )); 
        if( !controlNode )
            {
            error =  KErrNotFound;
            return error;
            }        
        ChspsDomList& childList = controlNode->ChildNodes();
        ChspsDomNode* settingsNode = (ChspsDomNode*)childList.FindByName( KSettingsElement );
        if( !settingsNode )
            {
            error =  KErrNotFound;
            return error;
            }
        TInt index = controlNode->ItemIndex( *settingsNode );
        controlNode->DeleteChild(settingsNode);
       
        ChspsDomDepthIterator* iter = ChspsDomDepthIterator::NewL( *aDom.RootNode() );
        CleanupStack::PushL( iter );                                
        ChspsDomNode* node = iter->First();
        ChspsDomNode* prevNode = NULL;
        TBool jobDone = EFalse;
        while( node && !jobDone && node != prevNode)
            {
            const TDesC8& name = node->Name();
            if( name == KSettingsElement )
                {
                // Attach to the plugin node
                
                ChspsDomNode* clone = node->CloneL( aOdt.DomDocument().StringPool() );
                CleanupStack::PushL( clone  );
                controlNode->AddChildL( clone, index );
                clone->SetParent( controlNode );
                CleanupStack::Pop( clone );
                jobDone=ETrue;
                error=KErrNone;
                }
            prevNode=node;
            node=iter->NextL();
            }
        CleanupStack::PopAndDestroy( iter ); 
        
    
         
    return error;
   
    }

// -----------------------------------------------------------------------------
// Finds a node from a dom document.
// Looks for the next node tag.
// -----------------------------------------------------------------------------
ChspsDomNode& ChspsMaintenanceHandler::FindNodeByTagL( 
        const TDesC8& aNodeTag,
        ChspsDomNode& aDomNode )
    {
    ChspsDomDepthIterator* iter = ChspsDomDepthIterator::NewL( aDomNode );
    CleanupStack::PushL( iter );
    ChspsDomNode* targetNode( NULL );
    ChspsDomNode* node = iter->First();
    TBool found = EFalse;
    while( !found && node )
        {
        const TDesC8& name = node->Name();
        if ( name.Compare( aNodeTag ) == 0 )
            {  
            found = ETrue;
            targetNode = node;
            }
        node = iter->NextL();
        }   
    CleanupStack::PopAndDestroy( iter );
    return *targetNode;
    }        

// -----------------------------------------------------------------------------
// ChspsMaintenanceHandler::hspsSavePluginSettingsL

// -----------------------------------------------------------------------------
//
TInt ChspsMaintenanceHandler::hspsSavePluginSettingsL(  
        ChspsODT& aOdt,
        ChspsDomDocument&  aDom )
    {
    ChspsDomNode* node =  aOdt.DomDocument().RootNode();
    ChspsDomNode* controlNode = &(FindNodeByTagL(KControlElement, *node )); 
        
    if( !controlNode )    
        {
        return KErrNotFound;
        }
    
    ChspsDomList& childList = controlNode->ChildNodes();
    ChspsDomNode* settingsNode = (ChspsDomNode*)childList.FindByName( KSettingsElement );
    
    if( !settingsNode )
        {
        return KErrNotFound;
        }

    TInt index = controlNode->ItemIndex( *settingsNode );
    controlNode->DeleteChild(settingsNode);
   
    ChspsDomDepthIterator* iter = ChspsDomDepthIterator::NewL( *aDom.RootNode() );
    CleanupStack::PushL( iter );                                
    ChspsDomNode* iterNode = iter->First();
    ChspsDomNode* prevNode = NULL;
    TBool jobDone = EFalse;

    TInt error( KErrNotFound );

    while( iterNode && !jobDone && iterNode != prevNode)
        {
        const TDesC8& name = iterNode->Name();
        if( name == KSettingsElement )
            {
            // Attach to the plugin node
            
            ChspsDomNode* clone = iterNode->CloneL( aOdt.DomDocument().StringPool() );
            CleanupStack::PushL( clone  );
            controlNode->AddChildL( clone, index );
            clone->SetParent( controlNode );
            CleanupStack::Pop( clone );
            jobDone=ETrue;
            error=KErrNone;
            }
        prevNode=iterNode;
        iterNode=iter->NextL();
        }
    CleanupStack::PopAndDestroy( iter ); 

    return error;
    }

// Service for updating plugin positions
// -----------------------------------------------------------------------------
//
void ChspsMaintenanceHandler::ServiceMovePluginsL( const RMessage2& aMessage )
    {
    // Defaults
    ThspsServiceCompletedMessage ret = EhspsMovePluginsFailed;
    iResult->iXuikonError = KErrNotFound;
    TInt err = KErrNone;
    
    // Parameters
    RMessagePtr2 messagePtr = aMessage;
    
    // IPC slots: 
    // #0) output: externalized ChspsResult for error handling
    // #1) input: a struct
    
    // Get service parameters from IPC slot #1
    ThpsParamMovePlugins params;        
    TPckg<ThpsParamMovePlugins> packagedStruct(params);    
    aMessage.ReadL(1, packagedStruct);                        
    const TInt appUid = params.appUid;
    const TInt confId = params.configurationId;        
    TPtrC8 bufPtr( params.pluginIdsBuf );
    
    // Internalize the plugin ids array from a descriptor
    const TInt KGranularity = 6;
    ChspsPluginIdList* idArray = new (ELeave)ChspsPluginIdList( KGranularity );
    CleanupStack::PushL( idArray );
    RDesReadStream readStream( bufPtr );
    CleanupClosePushL( readStream );
    TRAP( err, idArray->InternalizeL(readStream) );        
    CleanupStack::PopAndDestroy( &readStream );

    if ( err || appUid < 1 || confId < 1 || idArray->Count() < 1 )
        {
#ifdef HSPS_LOG_ACTIVE  
        if( iLogBus )
            {
            iLogBus->LogText( _L( "ChspsMaintenanceHandler::ServiceMovePluginsL(): invalid input" ) );
            }
#endif
        
        err = KErrArgument;
        }

    // Application configuration
    ChspsODT *appODT = NULL;
    if ( !err )
        {    
        // Get active application configuration from the central repository
        TInt appConfUid;       
        err = iCentralRepository.Get( appUid, appConfUid );
        if ( err || appConfUid < 1 )
            {
            err = KErrNotFound;         
            }
        else
            {
            appODT = ChspsODT::NewL();
            CleanupStack::PushL( appODT );
            err = iThemeServer.GetConfigurationL( 
                    appUid, 
                    appConfUid,
                    *appODT );                                        
            }
        }

    // Modifications    
    if ( !err )
       {       
           if ( iDefinitionRepository.Locked() )
               {
            // Repository locked
               err = KErrAccessDenied;
               }
           else
               {
               // Lock the Plugin Repository (a.k.a. Def.rep)
               iDefinitionRepository.Lock();                                
            CleanupStack::PushL( TCleanupItem( UnlockRepository, &iDefinitionRepository ) );
            
            // Update the provided configuration  
            err = UpdatePluginListL( 
                    *appODT, 
                    confId, 
                    *idArray );                
            if ( !err )            
                {

#ifdef HSPS_LOG_ACTIVE                
                if( appODT && iLogBus )
                    {
                    iLogBus->LogText( _L( "ChspsMaintenanceHandler::ServiceRemovePluginL() - plugins moved:" ) );
                    ChspsOdtDump::Dump( *appODT, *iLogBus );
                    }
#endif
                // Stores the new application configuration into the repository
                err = iDefinitionRepository.SetOdtL( *appODT );
                if ( err )
                    {
#ifdef HSPS_LOG_ACTIVE  
                    if( iLogBus )
                        {
                        iLogBus->LogText( _L( "ChspsMaintenanceHandler::ServiceRemovePluginL(): - Updating failed" ) );
                        }
#endif                    
                    }
                }
            else
                {
#ifdef HSPS_LOG_ACTIVE  
                if( iLogBus )
                    {
                    iLogBus->LogText( _L( "ChspsMaintenanceHandler::ServiceRemovePluginL(): - UpdatePluginListL failed" ) );
                    }
#endif
                }
            
            // Unlock after the changes have been done
            iDefinitionRepository.Unlock();
            CleanupStack::Pop(&iDefinitionRepository);

            if ( !err )
                {
                // Inform clients that the ODT has been modified
                ThspsRepositoryInfo info( 
                    ThspsRepositoryEvent(EhspsODTModified),
                    appODT->RootUid(),
                    appODT->ThemeUid(),
                    0, //=Any file
                    appODT->ProviderUid(),
                    (TLanguage)(appODT->OdtLanguage())
                    );                                
                iDefinitionRepository.RegisterNotification( info );
                }                                        
               }       
       }    
    
    // Cleaning
    if ( appODT )
        {
        CleanupStack::PopAndDestroy( appODT );
        appODT = NULL;
        }
    
    CleanupStack::PopAndDestroy( idArray );
        
    // Error handling
    iResult->iXuikonError = err;
    if ( !err )
        {        
        ret = EhspsMovePluginsSuccess;
        }
    
    // Completion 
    CompleteRequest( ret, messagePtr );    
    }

// -----------------------------------------------------------------------------
// Service for updating configuration state
// -----------------------------------------------------------------------------
//
void ChspsMaintenanceHandler::ServiceSetConfStateL( const RMessage2& aMessage )
    {
    // Parameters
    RMessagePtr2 messagePtr = aMessage;
    
    // Get service parameters from IPC slot #1
    ThspsParamSetConfState params;        
    TPckg<ThspsParamSetConfState> packagedStruct( params );    
    aMessage.ReadL( 1, packagedStruct );                      
       
    // Reserve definition repository
    if ( iDefinitionRepository.Locked() )
        {
        // Definition repository reserved
        User::Leave( KErrAccessDenied );
        }
    iDefinitionRepository.Lock();                               
    CleanupStack::PushL( TCleanupItem( UnlockRepository, &iDefinitionRepository ) );

    // Get application configuration
    TInt appConfUid;       
    User::LeaveIfError( iCentralRepository.Get( params.appUid, appConfUid ) );                    
    ChspsODT* appODT = ChspsODT::NewL();
    CleanupStack::PushL( appODT );
    User::LeaveIfError( iThemeServer.GetConfigurationL( 
        params.appUid, 
        appConfUid,
        *appODT ) );                                      
    
    // Update configuration state
    SetConfStateL( *appODT, params.confId, params.state, params.filter );
    
    // Store updated configuration
    User::LeaveIfError( iDefinitionRepository.SetOdtL( *appODT ) );
    CleanupStack::PopAndDestroy( appODT );
    
    // Release definition repository
    iDefinitionRepository.Unlock();
    CleanupStack::Pop( &iDefinitionRepository );
    
    // Completion 
    CompleteRequest( EhspsSetConfStateSuccess, messagePtr ); 
    }

// -----------------------------------------------------------------------------
// Service for restoring active application configuration
// -----------------------------------------------------------------------------
//
void ChspsMaintenanceHandler::ServiceRestoreActiveAppConfL( const RMessage2& aMessage )
    {
    // Parameters
    RMessagePtr2 messagePtr = aMessage;
    ThspsServiceCompletedMessage ret( EhspsRestoreActiveAppConfFailed );
    TInt err( KErrNone );
    
    // Get service parameters from IPC slot #1
    ThspsParamRestoreActiveAppConf params;        
    TPckg<ThspsParamRestoreActiveAppConf> packagedStruct( params );    
    aMessage.ReadL( 1, packagedStruct );                      
    
    // Create search criteria
    ChspsODT* searchMask = ChspsODT::NewL();
    CleanupStack::PushL( searchMask );
    searchMask->SetRootUid( params.appUid );
    searchMask->SetThemeUid( params.confUid );

    // Get configuration header
    ChspsODT* confHeader( NULL );
    TInt pos( 0 );
    iThemeServer.GetConfigurationHeader( *searchMask, confHeader, pos );

    if ( confHeader &&
         !iDefinitionRepository.Locked() )
        {            
        // Lock definition repository
        iDefinitionRepository.Lock();                               
        // Restore backup configuration if it exists
        err = iDefinitionRepository.RestoreBackupConfiguration( *confHeader );
        // Release definition repository
        iDefinitionRepository.Unlock();

        if ( err != KErrNone )
            {
            // Configuration backup not found - Restore default configuration
            ChspsODT* odt = ChspsODT::NewL();
            CleanupStack::PushL( odt );
            RestoreDefaultAppConfL( confHeader, *odt );
            iDefinitionRepository.SetOdtL( *odt );
            CleanupStack::PopAndDestroy( odt );
            }
        ret = EhspsRestoreActiveAppConfSuccess;
        }
    
    CleanupStack::PopAndDestroy( searchMask );

    // Completion 
    CompleteRequest( ret, messagePtr ); 
    }

//----------------------------------------------------------------------------
// ChspsMaintenanceHandler::UpdatePluginListL()
// ----------------------------------------------------------------------------
//
TInt ChspsMaintenanceHandler::UpdatePluginListL(
        ChspsODT& aAppODT,
        const TInt aConfigurationId, 
        const CArrayFixFlat<TInt>& aPluginIdList )       
    {
    TInt err = KErrNone;
    
    // Find the configuration node
    ChspsDomNode* confNode = hspsServerUtil::FindConfigurationNodeL( aAppODT, aConfigurationId );
    if ( !confNode )
        {        
#ifdef HSPS_LOG_ACTIVE  
        if( iLogBus )
            {
            iLogBus->LogText( _L( "ChspsMaintenanceHandler::UpdatePluginListL(): - configuration node was not found" ) );
            }
#endif
        
        err = KErrNotFound;
        }
    
    ChspsDomNode* controlNode = NULL;
    if ( !err )
        {
        // Find a control node under the configuration node
        controlNode = (ChspsDomNode *)confNode->ChildNodes().FindByName( KControlElement );
        if ( !controlNode )
            {            
#ifdef HSPS_LOG_ACTIVE  
            if( iLogBus )
                {
                iLogBus->LogText( _L( "ChspsMaintenanceHandler::UpdatePluginListL(): - control node was not found" ) );
                }
#endif
            
            err = KErrNotFound;
            }    
        }
    
    ChspsDomNode* oldPluginsNode = NULL;
    if ( !err )
        {
        // Find a plugins node under the control node
        oldPluginsNode = (ChspsDomNode *)controlNode->ChildNodes().FindByName( KPluginsElement );
        if ( !oldPluginsNode )
            {    
#ifdef HSPS_LOG_ACTIVE  
            if( iLogBus )
                {
                iLogBus->LogText( _L( "ChspsMaintenanceHandler::UpdatePluginListL(): - plugin node was not found" ) );
                }
#endif            
            err = KErrNotFound;
            }
        else
            {
#ifdef HSPS_LOG_ACTIVE  
            if( iLogBus )
                {
                iLogBus->LogText( _L( "ChspsMaintenanceHandler::UpdatePluginListL(): - old plugins node has %d childs" ),
                        oldPluginsNode->ChildNodes().Length() );
                }
#endif            
            }
        }
    
    const TInt nodeCount = aPluginIdList.Count();
    if ( !err )
        {
        // Plugin node count and provided id count should match        
        if ( nodeCount < 1 || nodeCount != oldPluginsNode->ChildNodes().Length() )
            {
            err = KErrArgument;
            }
        }
    
    // Find all plugin nodes under the plugins node in the requested sequence
    CArrayFixFlat<ChspsDomNode*>* nodeArray = NULL;
    if ( !err )
        {
        nodeArray = new (ELeave)CArrayFixFlat<ChspsDomNode*>( nodeCount );
        CleanupStack::PushL( nodeArray );
        ChspsDomNode* node = NULL;
        for( TInt nodeIndex=0; nodeIndex < nodeCount; nodeIndex++ )        
            {                        
            const TInt pluginId = aPluginIdList.At(nodeIndex); 
            node = FindChildPluginNode( 
                *oldPluginsNode, 
                pluginId );
            if ( !node )
                {
#ifdef HSPS_LOG_ACTIVE  
                if( iLogBus )
                    {
                    iLogBus->LogText( _L( "ChspsMaintenanceHandler::UpdatePluginListL(): - FindChildPluginNode failure" ) );
                    }
#endif
                
                err = KErrNotFound;
                break;
                }
            nodeArray->AppendL( node );

#ifdef HSPS_LOG_ACTIVE  
            if( iLogBus )
                {
                iLogBus->LogText( _L( "ChspsMaintenanceHandler::UpdatePluginListL(): - plugin id=%d" ),
                        pluginId );
                }
#endif            
            }
        }
    
    ChspsDomNode* newPluginsNode = NULL;
    if ( !err )
        {            
        // Clone the plugins node
        newPluginsNode = oldPluginsNode->CloneWithoutKidsL( oldPluginsNode->StringPool() );
        CleanupStack::PushL( newPluginsNode );
    
        // Add the cloned plugins node into the control node (removal of the old plugins node is done later)        
        const TInt KNewPosition = 0;
        controlNode->ChildNodes().AddItemL( newPluginsNode, KNewPosition );        
        newPluginsNode->SetParent( controlNode );
            
        // Transfer ownership of the plugin nodes
        const TInt arrayCount = nodeArray->Count();
        for( TInt arrayIndex=0; arrayIndex < arrayCount; arrayIndex++)
            {        
            ChspsDomNode* pluginNode = nodeArray->At(arrayIndex);
            if ( !pluginNode )
                {
                err = KErrGeneral;
                break;
                }
            newPluginsNode->AddChildL( pluginNode );        
            pluginNode->SetParent( newPluginsNode );                    
            }    
        }
    
    if ( !err )
        {
        // Remove plugin nodes from the old plugins node
        const TInt remainingCount = oldPluginsNode->ChildNodes().Length();
        for( TInt nodeIndex=0; nodeIndex < remainingCount; nodeIndex++)
            {
            ChspsDomNode* node = (ChspsDomNode*)oldPluginsNode->ChildNodes().Item( 0 );    
            if ( node )
                {
                oldPluginsNode->ChildNodes().RemoveItem( node );
                }
            }                
        if ( oldPluginsNode->ChildNodes().Length() != 0 )
            {
            err = KErrGeneral;
            }        
        }

    if ( !err )
        {
        // Remove the old plugins node from the control node
        controlNode->ChildNodes().RemoveItem( oldPluginsNode );
        delete oldPluginsNode;
        oldPluginsNode = NULL;        
        }
    
    if ( newPluginsNode )
        {
        CleanupStack::Pop( newPluginsNode );
        }
    if ( nodeArray )
        {
        CleanupStack::PopAndDestroy( nodeArray );
        }
    
    return err;
    }

//----------------------------------------------------------------------------
// ChspsMaintenanceHandler::SetConfStateL()
// ----------------------------------------------------------------------------
//
void ChspsMaintenanceHandler::SetConfStateL(
    ChspsODT& aAppODT,      
    TInt aConfId,
    ThspsConfigurationState aState,
    ThspsConfStateChangeFilter aFilter )     
    {

    // Get state attribute value
    TPtrC8 state;
    switch ( aState )
        {
        case EhspsConfStateNotConfirmed:
            state.Set( KConfStateNotConfirmed );
            break;
        case EhspsConfStateWaitForConfirmation:
            state.Set( KConfStateWaitForConfirmation );
            break;
        case EhspsConfStateConfirmed:
            state.Set( KConfStateConfirmed );
            break;
        default:
            state.Set( KConfStateError );
            break;
        }
    
    // Find a configuration node with an id attribute that matches the 
    // provided id and update found node state attribute
    // If aConfId is -1 all configuration nodes are updated
    ChspsDomDocument& dom = aAppODT.DomDocument();
    ChspsDomDepthIterator* iter = ChspsDomDepthIterator::NewL( *dom.RootNode() );
    CleanupStack::PushL( iter );
    ChspsDomNode* node = iter->First();
    ChspsDomNode* prevNode = NULL;
    TBool jobDone = EFalse;
    while( node && !jobDone && prevNode != node )    
        {                
        const TDesC8& name = node->Name();
        
        // Configuration node is found 
        if ( name == KConfigurationElement )
            {
            if ( aConfId != -1 )
                {
                ChspsDomList& attrList = node->AttributeList();                    
                ChspsDomAttribute* idAttr = static_cast<ChspsDomAttribute*>( 
                    attrList.FindByName( KConfigurationAttrId ) );            
                if ( !idAttr )
                    {
                    User::Leave( KErrNotFound );
                    }
                TInt id(0);            
                const TDesC8& idValue = idAttr->Value();                        
                TLex8 lex( idValue );                        
                lex.Val( id );
                TBuf8<10> confId;
                confId.Num( aConfId );
                if ( aConfId == id && aFilter == EhspsConfStateChangeNoFilter )
                    {
                    hspsServerUtil::AddAttributeDescL( 
                        *node, 
                        KConfigurationAttrState, 
                        state );
                    jobDone = ETrue;
                    }
                else if ( aFilter == EhspsConfStateChangePlugins && 
                        hspsServerUtil::GetParentNode( 
                            *node,
                            KConfigurationElement,
                            KConfigurationAttrId,
                            confId ) )
                    {
                    hspsServerUtil::AddAttributeDescL( 
                        *node, 
                        KConfigurationAttrState, 
                        state );
                    }
                }
            else
                {
                hspsServerUtil::AddAttributeDescL( 
                    *node,
                    KConfigurationAttrState,
                    state );
                }
            }
        
        prevNode = node;        
        node = iter->NextL();
        }
    CleanupStack::PopAndDestroy( iter );

    }

// -----------------------------------------------------------------------------
// ChspsMaintenanceService::hspsGetListHeadersL
// Gets the header list to aHeaderDataList
// (other items were commented in a header).
// -----------------------------------------------------------------------------
//
ThspsServiceCompletedMessage ChspsMaintenanceHandler::hspsGetListHeaders(const TDesC8& 
                                        /*aSearchMaskData*/, CArrayPtrSeg<HBufC8>& aHeaderDataList) 
    {
    // set the default response
    ThspsServiceCompletedMessage ret = EhspsGetListHeadersEmpty;
    TInt errorCode;
    TRAP( errorCode, GetHeaderListL( aHeaderDataList, *iSearchMask ) );
     if (errorCode)
        {
        ret = EhspsGetListHeadersFailed;
        }
    else
        {
        ret = EhspsGetListHeadersSuccess;
        }
     
    return ret; 
    }
    
// -----------------------------------------------------------------------------
// ChspsMaintenanceHandler::hspsGetNextHeader()
// Gets the header list to aHeaderDataList
// (other items were commented in a header).
// -----------------------------------------------------------------------------
//
ThspsServiceCompletedMessage ChspsMaintenanceHandler::hspsGetNextHeader()
    {
    return EhspsServiceNotSupported; 
     }
    
// -----------------------------------------------------------------------------
// ChspsMaintenanceHandler::hspsSetActiveTheme
// Sets the active theme to central repository.
// (other items were commented in a header).
// -----------------------------------------------------------------------------
//
ThspsServiceCompletedMessage ChspsMaintenanceHandler::hspsSetActiveTheme(const ChspsODT& aSetMask, 
                                                                                  ChspsODT& aOdt)
    {
    // set the default response
    ThspsServiceCompletedMessage ret = EhspsSetActiveThemeFailed;
    TInt errorCode = KErrNone;

#ifdef HSPS_LOG_ACTIVE  
    if( iLogBus )
        {
        iLogBus->LogText( _L( "ChspsMaintenanceHandler::hspsSetActiveTheme(): - requested for AppUid = %d, ThemeUid= %d." ),
                aSetMask.RootUid(),
                aSetMask.ThemeUid() );
        }
#endif
       
    TRAP( errorCode, errorCode = iThemeServer.ActivateThemeL( aSetMask, aOdt ));
    if ( errorCode )
           {
#ifdef HSPS_LOG_ACTIVE  
         if( iLogBus )
             {
             iLogBus->LogText( _L( "ChspsMaintenanceHandler::hspsSetActiveTheme(): - theme activation failed - bad ODT!" ) );
             }
#endif
        
         ret = EhspsSetActiveThemeFailed;    
            }
    else
          {
#ifdef HSPS_LOG_ACTIVE  
        if( iLogBus )
            {
            iLogBus->LogText( _L( "ChspsMaintenanceHandler::hspsSetActiveTheme(): - activated for AppUid = %d, ThemeUid= %d." ),
                    aOdt.RootUid(),
                    aOdt.ThemeUid() );
            }
#endif
        
          ret = EhspsSetActiveThemeSuccess;
        }
       return ret;
    }    

// -----------------------------------------------------------------------------
// ChspsMaintenanceHandler::hspsRestoreDefault
// Restores the default theme and returns either EhspsRestoreDefaultSuccess or 
// EhspsRestoreDefaultFailed.
// (other items were commented in a header).
// -----------------------------------------------------------------------------
//
ThspsServiceCompletedMessage ChspsMaintenanceHandler::hspsRestoreDefault( const ChspsODT& aSetMask,
                                                                                ChspsODT& aHeader )
    {
    // set the default response
    ThspsServiceCompletedMessage ret = EhspsRestoreDefaultFailed;
    TInt errorCode = 0;
    TRAP( errorCode, RestoredDefaultL( aSetMask, aHeader ) );
    if ( errorCode )
        {
        ret = EhspsRestoreDefaultFailed;    
         }
    else
        {
        ret = EhspsRestoreDefaultSuccess;
        }
    return ret;
    }    


// -----------------------------------------------------------------------------
// ChspsMaintenanceHandler::hspsRemoveThemeL
// Removes the theme by calling the appropriate method in definition repository.
// (other items were commented in a header).
// -----------------------------------------------------------------------------
//
ThspsServiceCompletedMessage ChspsMaintenanceHandler::hspsRemoveThemeL( const ChspsODT& aSetMask )
    {   
    ThspsServiceCompletedMessage ret( EhspsRemoveThemeFailed );

    if( !( aSetMask.Flags() & EhspsThemeStatusLicenceeDefault ) )                      
        {       
        RArray<ThspsRepositoryInfo> notifParams;
        
        if( !iDefinitionRepository.Locked() )
            {
            iDefinitionRepository.Lock();
                                                                       
            // In case of error. repository is unlocked    
            CleanupStack::PushL( TCleanupItem( UnlockRepository, &iDefinitionRepository ) );
                                                                                                       
            // Check what is being being uninstalled
            TInt error( KErrNone );
            if ( aSetMask.ConfigurationType() != EhspsAppConfiguration )
                {
                // Fix plugin instances and get notifications from valid cases
                TRAP( error, RemovePluginFromAppConfsL( aSetMask, notifParams ) );                    
                }                                
            
            if( !error )
                {
                // Remove the actual plugin from file system
                TRAP( error, RemoveThemeL( aSetMask ) );                
                }
                                               
            if( !error )
                {
                // Remove header from the cache
                iThemeServer.UpdateHeaderListCache(
                        EhspsCacheRemoveHeader,
                        aSetMask.RootUid(),
                        aSetMask.ProviderUid(),
                        aSetMask.ThemeUid() );
                }
            
            // Must be done before the notifications are sent
            iDefinitionRepository.Unlock();
            CleanupStack::Pop( &iDefinitionRepository );
            
            if ( !error )
                {
                // Send the notifications which will update the client UIs
                for( TInt i=0; i < notifParams.Count(); i++ )
                    {                                        
                    iDefinitionRepository.RegisterNotification( notifParams[i] );
                    }
                
                ret = EhspsRemoveThemeSuccess;                
                }                                                             
            }
        
        notifParams.Close();
        }
         
     return ret;
    }    

// -----------------------------------------------------------------------------
// RemovePluginFromAppConfsL
// -----------------------------------------------------------------------------
//
void ChspsMaintenanceHandler::RemovePluginFromAppConfsL( 
        const ChspsODT& aOdt,
        RArray<ThspsRepositoryInfo>& aNotificationParams )        
    {        
    __ASSERT_DEBUG( aOdt.ThemeUid(), User::Leave( KErrArgument ) );
           
    // Loop application configurations
    const TInt count = iHeaderListCache.Count();                  
    for ( TInt i = 0; i < count; i++ )
        {
        ChspsODT* header = iHeaderListCache.At(i);
        if ( header && header->ConfigurationType() == EhspsAppConfiguration )
            {                              
            // Get an ODT from the looped application configuration header                
            ChspsODT* appOdt = ChspsODT::NewL();
            CleanupStack::PushL( appOdt );
            
            // Fill only those values which are required by the GetOdtL call
            appOdt->SetRootUid( header->RootUid() );
            appOdt->SetProviderUid( header->ProviderUid() );
            appOdt->SetThemeUid( header->ThemeUid() );
            appOdt->SetProviderNameL( header->ProviderName() );
            appOdt->SetThemeShortNameL( header->ThemeShortName() );
            appOdt->SetThemeVersionL( header->ThemeVersion() );        
            User::LeaveIfError( iDefinitionRepository.GetOdtL( *appOdt ) );
             
            // Get active application configuration for the client in question
            TInt activeAppConfUid = 0;
            iCentralRepository.Get( appOdt->RootUid(), activeAppConfUid );
            
            // Get plugin id's from the instances in the application configuration
            RArray<TInt> pluginIds;   
            CleanupClosePushL( pluginIds );
            
            hspsServerUtil::GetPluginIdsByUidL( *appOdt,
                                                TUid::Uid( aOdt.ThemeUid() ),
                                                pluginIds  );
                                        
            // If there were plugin instances in an application configuration
            if ( pluginIds.Count() > 0 )
                {           
                                
                // If the application configuration is inactive
                if ( activeAppConfUid != appOdt->ThemeUid() )
                    {
                    // Prevent notifications and set state of the plugin instances to "uninstalled",
                    // AI3 will remove instances (or replaces them with an empty widget) 
                    // when it loads the configuration after it has first been activated
                    TBool updatesDone = InvalidateUninstalledPluginInstancesL( 
                            *appOdt,    
                            aOdt.ThemeUid(),
                            pluginIds );                    
#ifdef HSPS_LOG_ACTIVE  
                    if( iLogBus )
                        {
                        if ( updatesDone )
                            {
                            iLogBus->LogText( 
                                _L( "ChspsMaintenanceHandler::RemovePluginFromAppConfsL(): old plugin instances were updated in inactive root configuration" ) 
                                );
                            }                        
                        else
                            {
                            iLogBus->LogText( 
                                _L( "ChspsMaintenanceHandler::RemovePluginFromAppConfsL(): nothing was done" ) 
                                );
                            }
                        }                            
#endif                        
                    }
                else
                    {                    
                    // Notify active application configuration that old plugin instances need to be replaced                    
                    TBool lastNotification = EFalse;
                    for( TInt i = 0; i < pluginIds.Count(); i++ )
                       {
                       if( i == pluginIds.Count() - 1 )
                          {
                          lastNotification = ETrue;
                          }
                       ThspsRepositoryInfo info( 
                            ThspsRepositoryEvent( EhspsClean ),
                            appOdt->RootUid(),
                            appOdt->ThemeUid(),
                            0, //=Any file
                            appOdt->ProviderUid(),
                            aOdt.RootUid(),
                            aOdt.ProviderUid(),
                            aOdt.ThemeUid(),
                            pluginIds[i], 
                            lastNotification,
                            aOdt.ThemeFullName(),
                            (TLanguage)( aOdt.OdtLanguage() ) );
                       aNotificationParams.Append(info);
                       }
#ifdef HSPS_LOG_ACTIVE  
                    if( iLogBus )
                        {
                        iLogBus->LogText( 
                            _L( "ChspsMaintenanceHandler::RemovePluginFromAppConfsL(): plugin uninstalled notifications sent to SAPI for all instances" ) 
                            );
                        }
#endif                                               
                    }
                } // instance count > 0    
            else
                {                
                if ( activeAppConfUid == appOdt->ThemeUid() )
                    {
                    // Notify active application configuration which had no plugin instances
                    ThspsRepositoryInfo info( 
                        ThspsRepositoryEvent( EhspsClean ),
                        appOdt->RootUid(),
                        appOdt->ThemeUid(),
                        0, //=Any file
                        appOdt->ProviderUid(),
                        aOdt.RootUid(),
                        aOdt.ProviderUid(),
                        aOdt.ThemeUid(),
                        0, 
                        ETrue,
                        aOdt.ThemeFullName(),
                        (TLanguage)( aOdt.OdtLanguage() ) );
                    aNotificationParams.Append(info);
                    }
                }
            
            pluginIds.Close();
            CleanupStack::PopAndDestroy( 2, appOdt ); // appOdt, pluginIds                         
            appOdt = NULL;             
            
            } // app configuration
        
        } // header loop
       
    }

// -----------------------------------------------------------------------------
// ChspsMaintenanceHandler::InvalidateUninstalledPluginInstancesL
// -----------------------------------------------------------------------------
TBool ChspsMaintenanceHandler::InvalidateUninstalledPluginInstancesL(
        ChspsODT& aAppODT,    
        const TInt aPluginUid,
        const RArray<TInt>& aPluginIds )
    {            
    // Should be already locked by hspsRemoveThemeL()
    __ASSERT_DEBUG( iDefinitionRepository.Locked(), User::Leave( KErrGeneral ) );
    
#ifdef HSPS_LOG_ACTIVE  
    if( iLogBus )
        {        
        iLogBus->LogText( _L( "ChspsMaintenanceHandler::InvalidateUninstalledPluginInstancesL(): - Before Error state updates:") );
        ChspsOdtDump::Dump( aAppODT, *iLogBus );
        }
#endif
    
    TInt processedCount = 0;
    for( TInt idIndex = 0; idIndex < aPluginIds.Count(); idIndex++ )
        {        
        const TInt pluginId( aPluginIds[idIndex] );
        
        // If full DOM/application configuration hasn't been generated yet (plugin IDs are unset)
        if ( pluginId > 0 )
            {
            ChspsDomNode *pluginNode = hspsServerUtil::FindPluginNodeL( aAppODT, pluginId );
            __ASSERT_DEBUG( pluginNode, User::Leave( KErrArgument) );
            if ( pluginNode )
                {
                ChspsDomNode* confNode = (ChspsDomNode *)pluginNode->ChildNodes().Item( 0 );
                __ASSERT_DEBUG( confNode, User::Leave( KErrArgument) );
                if ( confNode )
                    {
                    // Indicate that the configuration is in error state
                    // Should be changed to "uninstalled" when Homescreen supports it silently 
                    hspsServerUtil::AddAttributeDescL( *confNode, KConfigurationAttrState, KConfStateError );                                       
                    processedCount++;
                    }
                }
            }
        }
    
    if ( processedCount )
        {
        // Remove uninstalled resources from the server (copies will remain in client's private directory)
        RemovePluginResourcesL( aAppODT, aPluginUid );
        
        // Store changes
        User::LeaveIfError( iDefinitionRepository.SetOdtL( aAppODT ) );
        }       
    
#ifdef HSPS_LOG_ACTIVE
    if( iLogBus )
        {
        if ( processedCount > 0 )
            {                
            iLogBus->LogText( _L( "ChspsMaintenanceHandler::InvalidateUninstalledPluginInstancesL(): - Error states updated") );
            ChspsOdtDump::Dump( aAppODT, *iLogBus );
            }
        else
            {
            iLogBus->LogText( _L( "ChspsMaintenanceHandler::InvalidateUninstalledPluginInstancesL(): - Error states were not added") );
            }
        }
#endif
    
    return ( processedCount > 0 );        
    }

// -----------------------------------------------------------------------------
// ChspsMaintenanceHandler::hspsPluginUpdateL
// (other items were commented in a header).
// -----------------------------------------------------------------------------

ThspsServiceCompletedMessage ChspsMaintenanceHandler::hspsPluginUpdateL( const ChspsODT& aOdt )
    {   
    ThspsServiceCompletedMessage ret( EhspsUpdatePluginFailed );
     
    if( !iDefinitionRepository.Locked() )
        {
        iDefinitionRepository.Lock();
        
        // In case of error. repository is unlocked 
        CleanupStack::PushL( TCleanupItem( UnlockRepository, &iDefinitionRepository ) );
                
        // set the default response
        ret = EhspsUpdatePluginSuccess;
        
        TInt errorCode( KErrNone );
        
        //create whole pluginOdt aOdt is only header for pluginOdt
        ChspsODT* odt = ChspsODT::NewL();
        CleanupStack::PushL( odt );
        odt->SetRootUid( aOdt.RootUid() );
        odt->SetThemeUid( aOdt.ThemeUid() );        
        odt->SetConfigurationType( aOdt.ConfigurationType() );
        odt->SetRootUid( aOdt.RootUid() );
        odt->SetProviderUid( aOdt.ProviderUid() );
        odt->SetThemeUid( aOdt.ThemeUid() );
        odt->SetProviderNameL( aOdt.ProviderName() );
        odt->SetThemeFullNameL( aOdt.ThemeFullName() );
        odt->SetThemeShortNameL( aOdt.ThemeShortName() );
        odt->SetThemeVersionL( aOdt.ThemeVersion() );
		odt->SetDescriptionL( aOdt.Description() );          
        odt->SetFlags( aOdt.Flags() ); 
        odt->SetMultiInstance( aOdt.MultiInstance() );
        User::LeaveIfError( iDefinitionRepository.GetOdtL( *odt ) );
        
        RArray<ThspsRepositoryInfo> notifParams;
        
        TRAP( errorCode, UpdatePluginFromAppConfsL( *odt, notifParams ));
        
        if( errorCode )
            {
            ret = EhspsUpdatePluginFailed;           
            }
                
        iDefinitionRepository.Unlock();
        CleanupStack::Pop( &iDefinitionRepository );

        if( ret == EhspsUpdatePluginSuccess )
            {
            if(notifParams.Count() > 0 )
                {
                //There is active app&appconfs to notify
                
                
                for( TInt i=0; i < notifParams.Count(); i++ )
                    {
                    iDefinitionRepository.RegisterNotification( notifParams[i] );
                    }
                }
            
            } 
        notifParams.Close();
        
        CleanupStack::PopAndDestroy( odt );
        }
         
    return ret;
    }
// -----------------------------------------------------------------------------
// ChspsMaintenanceHandler::UpdatePluginFromAppConfsL
// (other items were commented in a header).
//--------------------------------------------------------------------- 
void ChspsMaintenanceHandler::UpdatePluginFromAppConfsL( ChspsODT& aOdt,
        RArray<ThspsRepositoryInfo>& aNotificationParams )
    {
    
    if ( iHeaderListCache.Length() > 0 )
        {
        TInt count = iHeaderListCache.Count();
        for ( TInt i = 0; i < count; i++ )
            {
            ChspsODT* header = iHeaderListCache.At(i);
            if ( header->ConfigurationType() == EhspsAppConfiguration )
                {
                ChspsODT* odt = ChspsODT::NewL();
                CleanupStack::PushL( odt );
                odt->SetRootUid( header->RootUid() );
                odt->SetThemeUid( header->ThemeUid() );        
                odt->SetConfigurationType( header->ConfigurationType() );
                odt->SetRootUid( header->RootUid() );
                odt->SetProviderUid( header->ProviderUid() );
                odt->SetThemeUid( header->ThemeUid() );
                odt->SetProviderNameL( header->ProviderName() );
                odt->SetThemeFullNameL( header->ThemeFullName() );
                odt->SetThemeShortNameL( header->ThemeShortName() );
                odt->SetThemeVersionL( header->ThemeVersion() );            
                odt->SetDescriptionL( header->Description() );
                odt->SetFlags( header->Flags() ); 
                odt->SetMultiInstance( header->MultiInstance() );
                User::LeaveIfError( iDefinitionRepository.GetOdtL( *odt ) );
                     
                
                RArray<TInt> pluginIds;
                
                hspsServerUtil::GetPluginIdsByUidL( *odt,
                                                    TUid::Uid( aOdt.ThemeUid() ),
                                                    pluginIds );
               
                
                if ( pluginIds.Count() > 0 )
                    {
                    
                    
                    TInt err = UpdatePluginConfigurationL( 
                            *odt,
                            aOdt,
                            pluginIds );
                 
                    User::LeaveIfError( iDefinitionRepository.SetOdtL( *odt ) );
                    
                   
                        
                    TBool status = EFalse;
                    for(TInt i = 0; i < pluginIds.Count(); i++ )
                        {
                        if( i == pluginIds.Count() - 1 )
                            {  
                            status = ETrue;
                            }
                          ThspsRepositoryInfo info( 
                                    ThspsRepositoryEvent( EhspsODTUpdated ),
                                    odt->RootUid(),
                                    odt->ThemeUid(),
                                    0, //=Any file
                                    0,
                                    aOdt.RootUid(),
                                    aOdt.ProviderUid(),
                                    aOdt.ThemeUid(),
                                    pluginIds[i], 
                                    status,
                                    aOdt.ThemeFullName(),
                                    (TLanguage)( aOdt.OdtLanguage() ) );
                        aNotificationParams.Append(info);
                        }
                    }
                        
                    
               
                pluginIds.Close();
                
                CleanupStack::PopAndDestroy( odt );                        
                                   
                }
            }
        
        }
    }
// -----------------------------------------------------------------------------
// ChspsMaintenanceHandler::UpdatePluginConfigurationL
// Not supported
// (other items were commented in a header).
// -----------------------------------------------------------------------------
//
TInt ChspsMaintenanceHandler::UpdatePluginConfigurationL(
        ChspsODT& aOdt, 
        ChspsODT& aPluginOdt,
        RArray<TInt>& aPluginIds )
    {
    TInt err(KErrNone);
    
    // remove old resources
    err = RemovePluginResourcesL( aOdt, aPluginOdt.ThemeUid() );
    
    if( err )
        {
        return err;
        }
    
    for( TInt i = 0; i < aPluginIds.Count() && err == KErrNone; i++ )
        {
        ChspsDomNode* configNode  = NULL;        
        ChspsDomNode* pluginNode =
                hspsServerUtil::FindPluginNodeL( aOdt, aPluginIds[i] );
        TInt index = 0;
        
        if ( pluginNode )
            {
            configNode = 
            hspsServerUtil::FindChildNodeByTagL( KConfigurationElement, *pluginNode, index );
            }
       
        if( configNode )
            {
            TInt id  = hspsServerUtil::DecString2Int(
                        configNode->AttributeValue(KConfigurationAttrId));
            hspsServerUtil::AddAttributeNumericL( *aPluginOdt.DomDocument().RootNode(), KConfigurationAttrId, id );
            
            pluginNode->ReplaceChildL(configNode,aPluginOdt.DomDocument().RootNode()); 
            }
        else
            {
            err = KErrNotFound;
            }
       
        }
    if( err )
        {
        return err;
        }
    
    _LIT(KSourcesFolder, "\\sources\\");
    _LIT(KLocalesFolder, "\\locales\\");
   // Add plugin resources
    TInt resourceCount = aPluginOdt.ResourceCount();
    for ( TInt index=0; index < resourceCount; index++ )
        {                       
        ChspsResource& pluginResource = aPluginOdt.ResourceL(index);    
            // Add only those that are located under the sources folder
        if ( pluginResource.FileName().FindF( KSourcesFolder ) > 0
                  || pluginResource.FileName().FindF( KLocalesFolder ) > 0 )
            {                                                   
            ChspsResource* r = pluginResource.CloneL();
            CleanupStack::PushL( r );
            aOdt.AddResourceL( r ); 
            CleanupStack::Pop( r );
            }
        }
    
    return err;
    }
// -----------------------------------------------------------------------------
// ChspsMaintenanceHandler::hspsGetListHeaders()
// Not supported
// (other items were commented in a header).
// -----------------------------------------------------------------------------
//
ThspsServiceCompletedMessage ChspsMaintenanceHandler::hspsGetListHeaders(
        const ChspsODT& /*aSearchMask*/,
        const TBool /*aCopyLogos*/,
        CArrayPtrFlat<ChspsODT>& /*aHeaderList*/)        
    {
    return EhspsServiceNotSupported;
    }

// -----------------------------------------------------------------------------
// ChspsMaintenanceHandler::hspsSetActiveTheme()
// Not supported
// (other items were commented in a header).
// -----------------------------------------------------------------------------
//
ThspsServiceCompletedMessage ChspsMaintenanceHandler::hspsSetActiveTheme(const TDesC8& /*aSetMaskData*/,
                                                         TDes8& /*aHeaderData*/)
    {
    return EhspsServiceNotSupported;
    }

// -----------------------------------------------------------------------------
// ChspsMaintenanceHandler::hspsAddPlugin()
// Not supported - inherited from an interface and not used.
// -----------------------------------------------------------------------------
//
ThspsServiceCompletedMessage ChspsMaintenanceHandler::hspsAddPlugin(
            const TInt /*aAppUid*/,
            const TInt /*aParentPluginId*/,
            const TInt /*aPluginUid*/,
            const TInt /*aPosition*/,
            TInt& /*aAddedPluginId*/ )
    {
    return EhspsServiceNotSupported;
    }

// -----------------------------------------------------------------------------
// ChspsMaintenanceHandler::hspsRemovePlugin()
// Not supported - inherited from an interface and not used.
// -----------------------------------------------------------------------------
//
ThspsServiceCompletedMessage ChspsMaintenanceHandler::hspsRemovePlugin(
               const TInt /*aAppUid*/,                
               const TInt /*aPluginId*/ )
    {
    return EhspsServiceNotSupported;
    }

// -----------------------------------------------------------------------------
// ChspsMaintenanceHandler::hspsSetActivePlugin()
// Not supported - inherited from an interface and not used.
// -----------------------------------------------------------------------------
//
ThspsServiceCompletedMessage ChspsMaintenanceHandler::hspsSetActivePlugin(
            const TInt /*aAppUid*/,             
            const TInt /*aPluginId*/ )
    {
    return EhspsServiceNotSupported;
    }

// -----------------------------------------------------------------------------
// ChspsMaintenanceHandler::hspsReplacePlugin()
// Not supported - inherited from an interface and not used.
// -----------------------------------------------------------------------------
//
ThspsServiceCompletedMessage ChspsMaintenanceHandler::hspsReplacePlugin(
                const TInt /*aAppUid*/,
                const TInt /*aPluginId*/,             
                const TInt /*aConfUid*/ )
    {
    return EhspsServiceNotSupported;
    }

// -----------------------------------------------------------------------------
// ChspsMaintenanceHandler::hspsSetPluginSettings()
// Not supported - inherited from an interface and not used.
// -----------------------------------------------------------------------------
//
ThspsServiceCompletedMessage ChspsMaintenanceHandler::hspsSetPluginSettings(
                const ChspsODT& /*aHeader*/,
                const TInt /*aPluginId*/,
                ChspsDomDocument& /*aDom*/,
                const TBool /*aPluginStoringStatus*/)
    {
    return EhspsServiceNotSupported;
    }

// -----------------------------------------------------------------------------
// ChspsMaintenanceHandler::hspsMovePluginsL()
// Not supported - inherited from an interface and not used.
// -----------------------------------------------------------------------------
//
ThspsServiceCompletedMessage ChspsMaintenanceHandler::hspsMovePluginsL(
        const TInt /*aAppUid*/,
           const TInt /*aConfId*/,               
           const CArrayFixFlat<TInt>& /*aPluginIdList*/ )
    {
    return EhspsServiceNotSupported;
    }

// -----------------------------------------------------------------------------
// ChspsMaintenanceHandler::hspsSetConfState()
// Not supported - inherited from an interface and not used.
// -----------------------------------------------------------------------------
//
ThspsServiceCompletedMessage ChspsMaintenanceHandler::hspsSetConfState(
        const TInt /*aAppUid*/,
        const TInt /*aConfId*/,             
        const ThspsConfigurationState /*aState*/,
        const ThspsConfStateChangeFilter /*aFilter*/ )
    {
    return EhspsServiceNotSupported;
    }

// -----------------------------------------------------------------------------
// ChspsMaintenanceHandler::hspsRestoreActiveAppConf()
// Not supported - inherited from an interface and not used.
// -----------------------------------------------------------------------------
//
ThspsServiceCompletedMessage ChspsMaintenanceHandler::hspsRestoreActiveAppConf(
    const TInt /*aAppUid*/,
    const TInt /*aConfUid*/ )
    {
    return EhspsServiceNotSupported;
    }

// -----------------------------------------------------------------------------
// ChspsMaintenanceHandler::hspsCancelGetListHeaders()
// Cancels the GetListHeaders request
// (other items were commented in a header).
// -----------------------------------------------------------------------------
//
ThspsServiceCompletedMessage ChspsMaintenanceHandler::hspsCancelGetListHeaders()
    {
    if ( IsActive() )
        {
        Cancel();
        }
    iHeaderDataList->ResetAndDestroy(); // no headers
    iDeliveryCount = 0; // no delivered headers
    iSubscription = EFalse; // no subscription
    CompleteRequest( EhspsServiceRequestCanceled, iMessagePtr );
    // return with cancellation confirm    
    return EhspsServiceRequestCanceled;
    }
// -----------------------------------------------------------------------------
// ChspsClientRequestHandler::HandleDefinitionRespositoryEvent()
// Handles events coming from hspsDefinitionRepository.
// (other items were commented in a header).
// -----------------------------------------------------------------------------
//
TBool ChspsMaintenanceHandler::HandleDefinitionRespositoryEvent( ThspsRepositoryInfo aRepositoryInfo )
    {
    TInt errorCode = KErrNone;
    TBool status(EFalse);
    TRAP( errorCode, status = HandleDefinitionRespositoryEventL( aRepositoryInfo ) );
    if( errorCode != KErrNone )
        {
#ifdef HSPS_LOG_ACTIVE  
        if( iLogBus )
            {
            iLogBus->LogText( _L( "ChspsClientRequestHandler::HandleDefinitionRespositoryEvent(): - Error occured in HandleDefinitionRespositoryEventL" ) );
            }
#endif        
        }    
    return status;    
    }
// -----------------------------------------------------------------------------
// ChspsMaintenanceHandler::HandleDefinitionRespositoryEvent()
// Handles events coming from hspsDefinitionRepository.
// (other items were commented in a header).
// -----------------------------------------------------------------------------
//
TBool ChspsMaintenanceHandler::HandleDefinitionRespositoryEventL( ThspsRepositoryInfo aRepositoryInfo )
    {
    // is there any changes in cache
    if ( ( aRepositoryInfo.iEventType & EhspsCacheUpdate ) && !iDefinitionRepository.Locked() && iSubscription && !iMessagePtr.IsNull() )     
        {
        // cache changed, check if there is any changes when comparing to the local list    
        // and what kind of change there is
        iCompletedMessage = GetHeaderListUpdateL();
        // is there headers to deliver
        if ( iCompletedMessage == EhspsGetListHeadersRestart )
               {
               if (iHeaderDataList->Count())
                  {
                // at least one header on the list
                iMessagePtr.WriteL(2,iHeaderDataList->At(iDeliveryCount)->Des(),0);
                // add list count
                iDeliveryCount++; 
                // delivery of the first header
                 }
            CompleteRequest( EhspsGetListHeadersRestart, iMessagePtr );
               }
        else if ( iCompletedMessage == EhspsGetListHeadersUpdate )
               {
            // return list update, count continues from where it was
            iMessagePtr.WriteL(2,iHeaderDataList->At(iDeliveryCount)->Des(),0);
            // add list count
            iDeliveryCount++; 
            // deliver a list item
            CompleteRequest( EhspsGetListHeadersUpdate, iMessagePtr );
              }
        else if (iCompletedMessage == EhspsGetListHeadersEmpty)
               {
               CompleteRequest( EhspsGetListHeadersEmpty, iMessagePtr );
            // no list update available at the moment, continue the polling for list updates
               }
        }
    else if ( ( aRepositoryInfo.iEventType & EhspsCacheUpdate ) && iDefinitionRepository.Locked() 
        && !IsActive() && iSubscription )
        {
        After(KHeaderListUpdatePollingTimeSpan);    
        }      
    
    else if( aRepositoryInfo.iEventType & EhspsODTAdded
            || aRepositoryInfo.iEventType & EhspsODTUpdated )
        {
        // If a widget has been installed or updated
        if( iServerSession )
            {
            // Make sure all logos are copied when user retrieves the list
            iServerSession->SetIconFileCopyRequired( ETrue );
            }
        }
 
    return EFalse;
    }

// -----------------------------------------------------------------------------
// ChspsMaintenanceHandler::DoCancel()
// Not implemented yet
// (other items were commented in a header).
// -----------------------------------------------------------------------------
//   
void ChspsMaintenanceHandler::DoCancel()
    {
    // no need to implement
    } 

// -----------------------------------------------------------------------------
// ChspsMaintenanceHandler::CompleteRequest()
// Completes client request
// (other items were commented in a header).
// -----------------------------------------------------------------------------
//    
void ChspsMaintenanceHandler::CompleteRequest(const ThspsServiceCompletedMessage aReturnMessage, 
    RMessagePtr2& aMessagePtr, const TDesC8& /*aHeaderData*/ )
    {
    TInt errorCode = KErrNone;
    RDesWriteStream writeBuf( iResultData );

    TRAP( errorCode, iResult->ExternalizeL( writeBuf ));

    writeBuf.Close();
    
    if ( !aMessagePtr.IsNull() )
        {
        if ( errorCode )
            {
            TRAP_IGNORE( aMessagePtr.WriteL( 0, KNullDesC8, 0 ));
            }
        else
            {
            TRAP_IGNORE( aMessagePtr.WriteL( 0, iResultData, 0 ));
            }
        aMessagePtr.Complete( aReturnMessage );    
        } 
    }
     
// -----------------------------------------------------------------------------
// ChspsMaintenanceHandler::RunError
// From CActive. Called when error occurred in asynchronous request
// (other items were commented in a header).
// -----------------------------------------------------------------------------
//
TInt ChspsMaintenanceHandler::RunError( TInt aError )
    {
    iResult->iSystemError = aError;
    iResult->iXuikonError = aError; 

#ifdef HSPS_LOG_ACTIVE  
    if( iLogBus )
        {
        iLogBus->LogText( _L( "ChspsMaintenanceHandler::RunError(): - error %d" ),
                aError );
        }
#endif
        
    CompleteRequest( EhspsGetListHeadersFailed, iMessagePtr );
    
    return KErrNone;
    }  

// -----------------------------------------------------------------------------
// ChspsMaintenanceHandler::RunL()
// Handles header list polling
// (other items were commented in a header).
// -----------------------------------------------------------------------------
//    
void ChspsMaintenanceHandler::RunL()
    {
    if ( !iDefinitionRepository.Locked()  && !iMessagePtr.IsNull() )     
        {
        // cache changed, check if there is any changes when comparring to the local list    
        // and what kind of change there is
        iCompletedMessage = GetHeaderListUpdateL();
        // is there headers to deliver
        if ( iCompletedMessage == EhspsGetListHeadersRestart)
               {
               if (iHeaderDataList->Count())
                  {
                // at least one header on the list
                iMessagePtr.WriteL(2,iHeaderDataList->At(iDeliveryCount)->Des(),0);
                // add list count
                iDeliveryCount++; 
                // delivery of the first header
                 }
            CompleteRequest( EhspsGetListHeadersRestart, iMessagePtr );
               }
        else if ( iCompletedMessage == EhspsGetListHeadersUpdate )
               {
            // return list update, count continues from where it was
            iMessagePtr.WriteL(2,iHeaderDataList->At(iDeliveryCount)->Des(),0);
            // add list count
            iDeliveryCount++; 
            // deliver a list item
            CompleteRequest( EhspsGetListHeadersUpdate, iMessagePtr );
              }
        else if (iCompletedMessage == EhspsGetListHeadersEmpty)
               {
               CompleteRequest( EhspsGetListHeadersEmpty, iMessagePtr );
            // no list update available at the moment, continue the polling for list updates
               }
        }
    else if ( !IsActive() )
        {
        After(KHeaderListUpdatePollingTimeSpan);    
        }      
    }

// -----------------------------------------------------------------------------
// ChspsMaintenanceHandler::GetHeaderListUpdateL
// Checks if the header list has changed and returns the appropriate 
// ThspsServiceCompletedMessage answer.
// (other items were commented in a header).
// -----------------------------------------------------------------------------
//
ThspsServiceCompletedMessage ChspsMaintenanceHandler::GetHeaderListUpdateL()
    {
    ThspsServiceCompletedMessage ret = EhspsGetListHeadersNoChange;
     
     // chech if repository have a cache update available 
       TInt oldcount = iHeaderDataList->Count();
       CArrayPtrSeg<HBufC8>* newheaderDataList = new( ELeave ) CArrayPtrSeg<HBufC8>
                            (KHeaderListGranularity);
       CleanupStack::PushL( TCleanupItem( ResetAndDestroyArray, newheaderDataList ) );
 
    GetHeaderListL( *newheaderDataList, *iSearchMask    );
      if ( newheaderDataList->Count() )
           {
           TBool reset = EFalse;
           TBool found = EFalse;
           TInt newcount = newheaderDataList->Count();      
           // cases:
           // 0. both lists are empty => no change
           if (!oldcount && !newcount)
               {
               ret = EhspsGetListHeadersNoChange;
               }
           else
           // 1. new list has members but old list is empty => just add new headers on old list 
           // => restart anyway
           if (!oldcount && newcount)
               {
                for (TInt k=0;k<newheaderDataList->Count();k++)
                {
                 HBufC8* l = newheaderDataList->At(k)->AllocL();
                 if (l != NULL)
                     {
                     CleanupStack::PushL(l);
                        iHeaderDataList->AppendL(l);
                        CleanupStack::Pop(l);
                     }
                     }
                  ret = EhspsGetListHeadersRestart; // start from begin                  
               }
           // 2. new list is empty and old has members => empty old list too => empty the list        
           else if (!newcount && oldcount)
               {
               // must fetch whole list again
               iHeaderDataList->ResetAndDestroy();
               iDeliveryCount = 0;  
               ret = EhspsGetListHeadersEmpty; // empty the list
               }
           // 3. old list and new list both have members, newcount < oldcount => reset
           else if (newcount < oldcount)
               {
               // must fetch whole list again
               iHeaderDataList->ResetAndDestroy();
               iDeliveryCount = 0;  
               GetHeaderListL( *iHeaderDataList, *iSearchMask );
               ret = EhspsGetListHeadersRestart; 
               }
           // 4. old list and new list both have members => examine next cases          
           else
               {
               TInt j=0;
               for ( TInt i=0; i<iHeaderDataList->Count();i++ )
                     {
                   HBufC8* old = iHeaderDataList->At(i);
                   if (old != NULL)
                       {
                       while ( j < newheaderDataList->Count() )
                           {
                           HBufC8* cand = newheaderDataList->At(j);
                           
                           if (cand != NULL)
                              {
                            if (CompareHeadersL(*old, *cand)) // is it there
                                     {
                                   // delete existing from the new list
                                   newheaderDataList->Delete(j);
                                   delete cand; //free allocated memory
                                   found = ETrue;
                                   break; // take next i in for for-loop
                                   }
                               else
                                   {
                                   // not found at this round, let see will the next one be a hit
                                   j++; // next j
                                   }
                              }
                             else
                              {
                              // not found at this round, let see will the next one be a hit
                               j++; // next j
                              }
                           } // while
                       }
                   // did it found a match for entry i on iHeaderDataList
                    if (!found)
                       {
                          // lists do not match
                       reset = ETrue;
                       break;
                       }
                   } // for
               if ( reset || newheaderDataList->Count() )
                   {
                   // must fetch whole list again
                   iHeaderDataList->ResetAndDestroy();
                   iDeliveryCount = 0;  
                   GetHeaderListL( *iHeaderDataList, *iSearchMask );
                   ret = EhspsGetListHeadersRestart; 
                   }
            else 
                   {
                iDeliveryCount = 0;  
                   ret = EhspsGetListHeadersNoChange;
                   }    
            }
        }
    else // no headers found => list must be emptied
        {
        // reset the list
        iHeaderDataList->ResetAndDestroy();
        iDeliveryCount = 0;  
        ret = EhspsGetListHeadersEmpty;    
        }
    CleanupStack::Pop( newheaderDataList );
    if ( newheaderDataList )
        {
        newheaderDataList->ResetAndDestroy();
        delete newheaderDataList;
        newheaderDataList = NULL;
        }
     return ret;
    }

// -----------------------------------------------------------------------------
// ChspsMaintenanceHandler::GetHeaderListL
// Fills aHeaderDataList with headers and sets the appropriate flag for active theme
// (other items were commented in a header).
// -----------------------------------------------------------------------------
//
void ChspsMaintenanceHandler::GetHeaderListL( 
        CArrayPtrSeg<HBufC8>& aHeaderDataList, 
        const ChspsODT& aSearchMask )
    {            
    // Reset search results
    aHeaderDataList.ResetAndDestroy();
                    
    if( !iFileMan )
       {                
       iFileMan = CFileMan::NewL( iServerSession->FileSystem() );
       }    
        
    for ( TInt i = 0; i < iHeaderListCache.Count(); i++ )
        {
        ChspsODT* header = iHeaderListCache.At( i );
        
        // Check whether the header matches the search criteria (family etc)
        if ( FilterHeader( aSearchMask, *header ) )
            {
        
            // Update file paths into the existing logo declarations
            if( header->LogoFile().Length() &&
                iMaintainLogoResources &&
                ( header->ConfigurationType() == EhspsWidgetConfiguration ||
                  header->ConfigurationType() == EhspsTemplateConfiguration ) )
                {    
            
                RBuf targetFile;
                CleanupClosePushL( targetFile );       
                targetFile.CreateL( KMaxFileName );
                
                RBuf sourceFile;
                CleanupClosePushL( sourceFile );
                sourceFile.CreateL( KMaxFileName );
                
                RBuf newDeclaration;
                CleanupClosePushL( newDeclaration );
                newDeclaration.CreateL( header->LogoFile().Length() + KMaxFileName );
                
                // Find location of the logo file and location where it shold be copied                
                hspsServerUtil::PopulateLogoPathsL(
                    header->LogoFile(),
                    iSecureId,
                    targetFile,
                    sourceFile,
                    newDeclaration );
                
                if( targetFile.Length()
                        && sourceFile.Length() 
                        && newDeclaration.Length() )
                    {
                    // Update private path information to the logo declaration                
                    header->SetLogoFileL( newDeclaration );
                                        
                    hspsServerUtil::CopyResourceFileL(
                        iServerSession->FileSystem(),
                        *iFileMan,                         
                        targetFile,
                        sourceFile );
                    }
                
                CleanupStack::PopAndDestroy( 3, &targetFile ); // targetFile, sourceFile, newDeclaration                
                }      
        
            // Convert the header to a descriptor
            HBufC8* data = header->MarshalHeaderL();            
            if ( data )
                {
                // Append to the search results
                CleanupStack::PushL( data );
                aHeaderDataList.AppendL( data );
                CleanupStack::Pop( data );
                }
            }
        }          
    }

// -----------------------------------------------------------------------------
// ChspsMaintenanceHandler::RestoredDefaultL
// Goes through the themes for the application in order to find the Licensee 
// Default theme to restore.
// (other items were commented in a header).
// -----------------------------------------------------------------------------
//
void ChspsMaintenanceHandler::RestoredDefaultL( const ChspsODT& aSetMask, ChspsODT& aHeader )
    {
    TBool found = EFalse;
    TUint mask = 0;
    TUint rootUid = aSetMask.RootUid();
    ChspsODT* odt;
    
    if ( aSetMask.Flags() & EhspsThemeStatusOperatorDefault )
        {
        mask = EhspsThemeStatusOperatorDefault;
        }
    else if ( aSetMask.Flags() & EhspsThemeStatusUserDefault )
        {
        mask = EhspsThemeStatusUserDefault;
        }
        
    // If all but ROM based configurations should be removed
    if ( aSetMask.Flags() & EhspsThemeStatusClean )
        {
        for( TInt i = 0; i < iHeaderListCache.Count(); i++) // delete themes from c:
               {
               odt = iHeaderListCache.At(i);
               
               // Remove specific application configurations which are not matching the mask and
               // the licencee default flag
               if ( rootUid == odt->RootUid() 
                    && !( (odt->Flags() & mask) && (aSetMask.Flags() & mask) )
                    && !( odt->Flags() & EhspsThemeStatusLicenceeDefault ) )                  
                   {
                   // do not care about possible error
                   TRAP_IGNORE( RemoveThemeL( *odt ) );
                   }
            }
        // update cache after deletion
           iThemeServer.UpdateHeaderListCacheL();
        }
    
    // Try activating the first licencee restorable configuration in the cache
    for( TInt i = 0; i < iHeaderListCache.Count() && !found; i++ )
           {
           odt = iHeaderListCache.At(i);
           if( rootUid == odt->RootUid() && odt->Flags() & EhspsThemeStatusLicenceeRestorable )
               {
               if ( iThemeServer.ActivateThemeL( *odt, aHeader ) == KErrNone )
                   {
                   found = ETrue;
                   }
               }
        }
    // any default will do, depends on restoration level
    // this is safe because the default theme could be updated only with other default theme 
    mask = EhspsThemeStatusLicenceeDefault + EhspsThemeStatusOperatorDefault + EhspsThemeStatusUserDefault;

    // If no luck so far, try activating a "default" configuration with the new mask
    for( TInt i = 0; i < iHeaderListCache.Count() && !found; i++ )
           {
           odt = iHeaderListCache.At(i);
                      
           if( rootUid == odt->RootUid() && odt->Flags() & mask )
               {
               if ( iThemeServer.ActivateThemeL( *odt, aHeader ) == KErrNone )
                   {
                   found = ETrue;
                   }
               }
        }

    // If still no success, just select the first one in the cache
    if( !found )
        { // should not get here
        for( TInt i = 0; i < iHeaderListCache.Count() && !found; i++ ) // licensee default not found, activate some other theme
               {
               odt = iHeaderListCache.At(i);
               if( rootUid == odt->RootUid() )
                   {
                   if ( iThemeServer.ActivateThemeL( *odt, aHeader ) == KErrNone )
                       {
                       found = ETrue;
                       }
                   }
               }
        }
         
    // If there were no application specific configurations, give up
    if( !found )
        {
        // should not get here
        User::Leave( KErrNotFound );
        }      
    }


// -----------------------------------------------------------------------------
// ChspsMaintenanceHandler::RemoveThemeL
// Removes given theme from repository. If theme is in use (KErrInUse), then the theme
// is added on cleanup list.
// (other items were commented in a header).
// -----------------------------------------------------------------------------
//
void ChspsMaintenanceHandler::RemoveThemeL( const ChspsODT& aSetMask )
    {
    // do not even try to delete a theme licencee default theme as it is located in rom
    if( !( aSetMask.Flags() & EhspsThemeStatusLicenceeDefault ) )                                 
        {
        iDefinitionRepository.RemoveThemeL( aSetMask );
        }                                       
    }

// -----------------------------------------------------------------------------
// ChspsMaintenanceHandler::CompareHeadersL
// Compares the two theme headers and returns ETrue if they are the same
// (other items were commented in a header).
// -----------------------------------------------------------------------------
//
TBool ChspsMaintenanceHandler::CompareHeadersL(const TDesC8& aOldHeaderData, const TDesC8& 
    aNewHeaderData)
    {
    TBool ret;
    ChspsODT* old = ChspsODT::UnMarshalHeaderLC(aOldHeaderData);
    ChspsODT* cand= ChspsODT::UnMarshalHeaderLC(aNewHeaderData);
    if     ( old->RootUid() == cand->RootUid()            
        && old->ProviderUid() == cand->ProviderUid()            
        && old->ThemeUid() == cand->ThemeUid()
        && !old->ThemeVersion().Compare(cand->ThemeVersion())            
        && old->Flags() == cand->Flags() 
        )
        {
        ret = ETrue;
        }
    else
        {
        ret = EFalse;
        }
    CleanupStack::PopAndDestroy( cand );
    CleanupStack::PopAndDestroy( old );
    return ret;    
    }
    
// -----------------------------------------------------------------------------
// ChspsMaintenanceHandler::ComparePaths
// (other items were commented in a header).
// -----------------------------------------------------------------------------
//
TBool ChspsMaintenanceHandler::ComparePaths(const ChspsODT& aOldHeader, const ChspsODT& aNewHeader)
  {
  TBool ret;
  if  ( aOldHeader.RootUid() == aNewHeader.RootUid()        
        && aOldHeader.ProviderUid() == aNewHeader.ProviderUid()        
        && aOldHeader.ThemeUid() == aNewHeader.ThemeUid()            
        && !aOldHeader.ThemeVersion().Compare(aNewHeader.ThemeVersion()) )    
      {
      ret = ETrue;
      }
  else
      {
      ret = EFalse;
      }
  return ret; 
  }

// -----------------------------------------------------------------------------
// ChspsMaintenanceHandler::FilterHeader
// Compares the header and mask and returns true if the mask doesn't have any different
// values than the header (missing values are OK).
// (other items were commented in a header).
// -----------------------------------------------------------------------------
//
TBool ChspsMaintenanceHandler::FilterHeader(
        const ChspsODT& aMask, 
        const ChspsODT& aHeader )
    {
    TBool ret( EFalse );
    if (
            (   // 0 is not valid when comparing
                (aMask.RootUid() && aMask.RootUid() == aHeader.RootUid())
                ||
                 // 0 is OK in mask when aHeader is valid 
                (!aMask.RootUid() && aHeader.RootUid())
            )
        &&
            (
                (aMask.ProviderUid() && aMask.ProviderUid() == aHeader.ProviderUid())
                ||
                (!aMask.ProviderUid() && aHeader.ProviderUid())
            )            
        &&
            (
                (aMask.ThemeUid() && aMask.ThemeUid() == aHeader.ThemeUid())
                ||
                (!aMask.ThemeUid() && aHeader.ThemeUid())
            )
        &&                   
            (
                (aMask.ThemeVersion().Length() && !aMask.ThemeVersion().Compare( 
                                                                           aHeader.ThemeVersion()))
                ||
                (!aMask.ThemeVersion().Length() && aHeader.ThemeVersion().Length())
            )
        &&
            (
            ( aMask.ConfigurationType() && ( aHeader.ConfigurationType() == aMask.ConfigurationType() ) )
            ||
            ( !aMask.ConfigurationType() )
            )            
        && 
            // Show widgets designed for the active resolution or scalable
            ( ( aHeader.Family() & aMask.Family() ) || aHeader.Family() == 0 )
       )
        {
        ret = ETrue;
        }
    
    return ret;    
    }

// -----------------------------------------------------------------------------
// ChspsMaintenanceHandler::RestoreDefaultAppConfL
// (other items were commented in a header).
// -----------------------------------------------------------------------------
//
void ChspsMaintenanceHandler::RestoreDefaultAppConfL(
    ChspsODT*& aHeader,
    ChspsODT& aOdt)
    {
    
    // If active application configuration is LicenceeRestorable 
    if ( aHeader->Flags() & EhspsThemeStatusLicenceeRestorable )
        {
        // Reinstall the configuration from ROM
        iThemeServer.ReinstallConfL( aHeader->RootUid(), aHeader->ThemeUid() );
        }
    else
        {
        // Try to activate a configuation with the LicenceeRestorable status
        ChspsODT* searchMask = ChspsODT::NewL();
        CleanupStack::PushL( searchMask );
        searchMask->SetRootUid( aHeader->RootUid() );
        searchMask->SetFlags( EhspsThemeStatusLicenceeRestorable );
        TInt pos( 0 );
        iThemeServer.GetConfigurationHeader( *searchMask, aHeader, pos );
        if ( aHeader )
            {
            // Activate licensee restorable configuration
            iThemeServer.ActivateThemeL( *aHeader, aOdt );
            ThspsRepositoryInfo info( EhspsODTActivated );
            iDefinitionRepository.RegisterNotification( info );
            }
        else
            {
            // Licensee restorable configuration not found
            // There must be at least one licensee restorable configuration
            User::Leave( KErrNotFound );
            }
        CleanupStack::PopAndDestroy( searchMask );
        }    
    }

// -----------------------------------------------------------------------------
// ChspsMaintenanceHandler::AddErrorConfigurationL()
// -----------------------------------------------------------------------------
//
void ChspsMaintenanceHandler::AddErrorConfigurationL(
        ChspsDomDocument& aAppDom,
        ChspsDomNode& aMissingPluginNode,
        const TInt aPluginUid
        )        
    {    
    // Create a new dummy configuration element
    ChspsDomNode* confNode = aAppDom.CreateElementNSL( 
        KConfigurationElement,         
        aMissingPluginNode.Namespace()            
        );
    CleanupStack::PushL( confNode );        
        
    hspsServerUtil::AddAttributeDescL( *confNode, KConfigurationAttrType, KConfTypeWidget );
    _LIT8( KUnknown, "unknown" );
    hspsServerUtil::AddAttributeDescL( *confNode, KConfigurationAttrInterface, KUnknown );
    hspsServerUtil::AddAttributeNumericL( *confNode, KConfigurationAttrUid, aPluginUid, EHex );
    hspsServerUtil::AddAttributeDescL( *confNode, KConfigurationAttrName, KUnknown );
    hspsServerUtil::AddAttributeDescL( *confNode, KConfigurationAttrNameEntity, KUnknown );
    hspsServerUtil::AddAttributeDescL( *confNode, KConfigurationAttrVersion, KUnknown );        
    hspsServerUtil::AddAttributeNumericL( *confNode, KConfigurationAttrMaxChild, 0, EDecimal );        
    
    // Indicate that the configuration is in error state
    hspsServerUtil::AddAttributeDescL( *confNode, KConfigurationAttrState, KConfStateError );
            
    // Set parent node
    aMissingPluginNode.AddChildL( confNode );
    CleanupStack::Pop( confNode );

    confNode->SetParent( &aMissingPluginNode );
        
    // Mandatory configuration-control node
    ChspsDomNode* controlNode = aAppDom.CreateElementNSL( 
        KControlElement,         
        confNode->Namespace()            
        );
    CleanupStack::PushL( controlNode );    
    confNode->AddChildL( controlNode );
    CleanupStack::Pop( controlNode );

    controlNode->SetParent( confNode );
    
    // Mandatory configuration-control-settings node
    ChspsDomNode* settingsNode = aAppDom.CreateElementNSL( 
        KSettingsElement,         
        controlNode->Namespace()            
        );
    CleanupStack::PushL( settingsNode );    
    controlNode->AddChildL( settingsNode );
    CleanupStack::Pop( settingsNode );
    settingsNode->SetParent( controlNode );           
    
    
    // Mandatory configuration-resources node
    ChspsDomNode* resourcesNode = aAppDom.CreateElementNSL( 
        KResourcesElement,         
        confNode->Namespace()            
        );
    CleanupStack::PushL( resourcesNode );    
    confNode->AddChildL( resourcesNode );
    CleanupStack::Pop( resourcesNode );        
    resourcesNode->SetParent( confNode );           
    
    }

// -----------------------------------------------------------------------------
// ChspsMaintenanceHandler::ServiceRestoreConfigurationsL
// -----------------------------------------------------------------------------
//    
void ChspsMaintenanceHandler::ServiceRestoreConfigurationsL( const RMessage2& aMessage )
    {    
    ThspsServiceCompletedMessage ret = EhspsRestoreConfigurationsFailed;    
    
    // using message pointer as a local variable because of synch call
    RMessagePtr2 messagePtr = aMessage;
    
    // IPC slots: 
    // #0) output: externalized ChspsResult for error handling
    // #1) input: ThspsParamRestoreConfigurations struct                         
    ThspsParamRestoreConfigurations params;        
    TPckg<ThspsParamRestoreConfigurations> packagedStruct(params);    
    aMessage.ReadL(1, packagedStruct);                                
    if ( params.appUid < 1 )
        {
        User::Leave( KErrArgument );
        }
    // Enable modification of owned configurations only
    if( messagePtr.SecureId().iId != params.appUid )
        {
        User::Leave( KErrAccessDenied );
        }
    
    TInt err = KErrNone;
    if( iDefinitionRepository.Locked() )
        {
        // Repository locked
        err = KErrAccessDenied;
        }
            
    if( !err )
        {
        // Lock the Plugin Repository (a.k.a. Def.rep)
        iDefinitionRepository.Lock();                                
        CleanupStack::PushL( TCleanupItem( UnlockRepository, &iDefinitionRepository ) );
        
        // Get active root configuration for the client application
        ChspsODT* appODT = ChspsODT::NewL();
        CleanupStack::PushL( appODT );    

#ifdef HSPS_LOG_ACTIVE                
        if( iLogBus )
            {
            iLogBus->LogText( 
                _L( "ChspsMaintenanceHandler::ServiceRestoreConfigurationsL(): - Dump before the changes:" ) 
                );                
            ChspsOdtDump::Dump( *appODT, *iLogBus );
            }
#endif
        
        TInt err = KErrNone;
        if ( !params.restoreAll )
            {
            // reinstall all widgets
            TRAP( err, iThemeServer.InstallWidgetsL();
                       iThemeServer.InstallUDAWidgetsL() );
            
            // Force updating of the header cache
            iThemeServer.UpdateHeaderListCacheL();          
            }  
        
        iThemeServer.GetActivateAppConfigurationL( 
                params.appUid,
                *appODT );
        
        // As a backup, if restoration of the active view fails,  
        // or if all views but the locked view should be removedc
        if ( err || params.restoreAll )
            {                        
            // Remove all views but the locked one and reset active view            
            RemoveUnlockedViewsL( *appODT );
            
            // Remove all widgets from the active view
            err = RestoreActiveViewL( *appODT );
            }       

#ifdef HSPS_LOG_ACTIVE                
        if( iLogBus )
            {
            iLogBus->LogText( 
                _L( "ChspsMaintenanceHandler::ServiceRestoreConfigurationsL(): - Dump after the changes:" ) 
                );        
            ChspsOdtDump::Dump( *appODT, *iLogBus );
            }
#endif
        if( !err )
            {
            // Stores the new application configuration into the repository
            err = iDefinitionRepository.SetOdtL( *appODT );
            ret = EhspsRestoreConfigurationsSuccess;
            }
        
        CleanupStack::PopAndDestroy( appODT );        

        // Unlock after the changes have been done
        iDefinitionRepository.Unlock();
        CleanupStack::Pop(&iDefinitionRepository);                               
        }
                          
    // Error handling
    iResult->iXuikonError = err;    
    
    // complete the message
    CompleteRequest( ret, messagePtr );
    }

// -----------------------------------------------------------------------------
// ChspsMaintenanceHandler::RestoreActiveViewL
// -----------------------------------------------------------------------------
//
TInt ChspsMaintenanceHandler::RestoreActiveViewL(
        ChspsODT& aAppODT )
    {          
    TInt err = KErrCorrupt;
    
    // Find active view node
    ChspsDomNode* pluginNode = FindActiveView( aAppODT );
    if ( pluginNode )
        {    
        // Remove all plugins from the view configuration
        err = RemovePluginConfigurationsL( 
                aAppODT,
                *pluginNode ); 
        }   
    return err;
    }

// -----------------------------------------------------------------------------
// ChspsMaintenanceHandler::FindActiveView
// -----------------------------------------------------------------------------
//
ChspsDomNode* ChspsMaintenanceHandler::FindActiveView(
        ChspsODT& aAppODT )
    {       
    ChspsDomNode* pluginNode = NULL;
        
    // Get 1st configuration element
    ChspsDomNode* confNode = aAppODT.DomDocument().RootNode();
    if( confNode && confNode->Name().CompareF( KConfigurationElement ) == 0 )
        {                    
        // Get control element
        ChspsDomNode* controlNode = 
                (ChspsDomNode*)confNode->ChildNodes().FindByName( KControlElement );
        if( controlNode )
            {    
            // Get plugins element
            ChspsDomNode* pluginsNode = 
                    (ChspsDomNode*)controlNode->ChildNodes().FindByName( KPluginsElement );  
            if( pluginsNode )
                {                        
                // Find active plugin node under the plugins node 
                pluginNode = hspsServerUtil::GetActivePluginNode( pluginsNode );
                }
            }
        }
    return pluginNode;
    }

// -----------------------------------------------------------------------------
// ChspsMaintenanceHandler::RemovePluginConfigurationsL
// -----------------------------------------------------------------------------
//
TInt ChspsMaintenanceHandler::RemovePluginConfigurationsL(
        ChspsODT& aAppODT, 
        ChspsDomNode& aActivePluginNode )
    {
    TInt err = KErrCorrupt;
    
    // Find a configuration node    
    ChspsDomNode* confNode = 
            (ChspsDomNode*)aActivePluginNode.ChildNodes().FindByName( KConfigurationElement );
    if( confNode )
        {
        // Get control node
        ChspsDomNode* controlNode = 
                (ChspsDomNode*)confNode->ChildNodes().FindByName( KControlElement );
        if( controlNode )
            {            
            // Find a plugins node        
            ChspsDomNode* pluginsNode = 
                    (ChspsDomNode*)controlNode->ChildNodes().FindByName( KPluginsElement );
            if( pluginsNode )
                {
                // Loop plugin nodes            
                err = KErrNone;
                ChspsDomList& childNodes = pluginsNode->ChildNodes();
                for( TInt pluginIndex=childNodes.Length()-1; pluginIndex >= 0; pluginIndex-- )
                    {
                    ChspsDomNode* pluginNode = (ChspsDomNode*)childNodes.Item( pluginIndex );
                    if( pluginNode )
                        {
                        // Remove the plugin configuration instance                       
                        err = RemoveConfigurationL( 
                            aAppODT,
                            *pluginNode );
                        if( err )
                            {
                            break;
                            }
                        }                    
                    }
                }
            }
        }
    
    return err;    
    }

// -----------------------------------------------------------------------------
// ChspsMaintenanceHandler::IsConfigurationLocked
// -----------------------------------------------------------------------------
//
TBool ChspsMaintenanceHandler::IsConfigurationLocked(
        ChspsDomNode& aConfNode )
    {   
    TBool isLocked = EFalse;
    
    ChspsDomList& attrList = aConfNode.AttributeList();
    ChspsDomAttribute* attr = 
        static_cast<ChspsDomAttribute*>( attrList.FindByName( KConfigurationAttrLocking ) );                
    if( attr )
        {        
        isLocked = ( attr->Value().CompareF( KConfLockingLocked ) == 0 );
       }
    
    return isLocked;
    }

// -----------------------------------------------------------------------------
// ChspsMaintenanceHandler::RemoveUnlockedViewsL
// -----------------------------------------------------------------------------
//
void ChspsMaintenanceHandler::RemoveUnlockedViewsL(
        ChspsODT& aAppODT )
    {
    // Get 1st configuration element
    ChspsDomNode* confNode = aAppODT.DomDocument().RootNode();
    if( !confNode || confNode->Name().CompareF( KConfigurationElement) != 0 )
        {            
        User::Leave( KErrCorrupt );            
        }           
    
    ChspsDomNode* controlNode = 
            (ChspsDomNode*)confNode->ChildNodes().FindByName( KControlElement );
    if( !controlNode )
        {
        User::Leave( KErrCorrupt );
        }
    
    // Get plugins element
    ChspsDomNode* pluginsNode = 
            (ChspsDomNode*)controlNode->ChildNodes().FindByName( KPluginsElement );  
    if( !pluginsNode )
        {            
        User::Leave( KErrCorrupt );
        }
        
    // Find plugin nodes which should be removed        
    const TInt pluginCount = pluginsNode->ChildNodes().Length();
    if( pluginCount > 1 )
        {        
        // Array for nodes which should removed from the configuration
        // (don't touch the appended objects) 
        RPointerArray<ChspsDomNode> nodeArray;
        CleanupClosePushL( nodeArray );
        
        // Remove all but one view
        TBool foundLocked = EFalse;                
        for( TInt nodeIndex=0; nodeIndex < pluginCount; nodeIndex++ ) 
            {
            ChspsDomNode* pluginNode = 
                    (ChspsDomNode*)pluginsNode->ChildNodes().Item( nodeIndex );
            if( pluginNode )
                {
            
                ChspsDomNode* confNode = 
                        (ChspsDomNode*)pluginNode->ChildNodes().FindByName( KConfigurationElement );
                if( confNode )
                    {                                
                    TBool isLocked = IsConfigurationLocked( *confNode );
                    
                    // If the plugin configuration hasn't been locked or 
                    // if there are several locked plugin nodes then remove all the rest
                    if( !isLocked || foundLocked )
                        {
                        // Mark for removal
                        nodeArray.Append( pluginNode );
                        }
                    else
                        {
                        // If this is the 1st locked node
                        if( !foundLocked )
                            {
                            foundLocked = ETrue;
                            }
                        }
                    }
                }                
            }
                
        // If all the nodes were marked for removal
        if( nodeArray.Count() > 0 && nodeArray.Count() == pluginCount )
            {
            // Unmark the 1st node - remove from the array only
            nodeArray.Remove( 0 );
            }
        
        // Remove rest
        TInt err = KErrNone;
        for( TInt nodeIndex=0; nodeIndex < nodeArray.Count(); nodeIndex++ ) 
            {
            // Remove the plugin node, related resources and maintain activity information
            err = RemoveConfigurationL( 
                    aAppODT, 
                    *nodeArray[nodeIndex] );            
            if( err )
                {
#ifdef HSPS_LOG_ACTIVE                                            
                if( iLogBus )
                    {
                    iLogBus->LogText( _L( "ChspsMaintenanceHandler::RemoveUnlockedViewsL(): - Restoring failed with %d code" ), err );                    
                    }
#endif
                }

            }
        
        nodeArray.Reset();
        CleanupStack::PopAndDestroy( 1, &nodeArray );        
        }           
    }

// end of file