codhandler/codeng/src/CodEngBase.cpp
changeset 0 dd21522fd290
child 10 a359256acfc6
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/codhandler/codeng/src/CodEngBase.cpp	Mon Mar 30 12:54:55 2009 +0300
@@ -0,0 +1,2856 @@
+/*
+* Copyright (c) 2002 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of the License "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 class CCodEngBase.   
+*      
+*
+*/
+
+
+// INCLUDE FILES
+
+#include "CodEngBase.h"
+#include "Connection.h"
+#include "HttpLoader.h"
+#include "CodSaver.h"
+#include "FileSaver.h"
+#include "RoapSaver.h"
+#include "CodData.h"
+#include "CodLoadObserver.h"
+#include "CodError.h"
+#include "CodStatus.h"
+#include "CodPanic.h"
+#include "CodUtil.h"
+#include "CodLogger.h"
+#include "RoapData.h"
+#include "CodProgress.h"
+#include "MediaObject.h"
+#include "DownloadDataClient.h"
+
+#include <AiwGenericParam.h>
+#include <DocumentHandler.h>
+#include <ApmStd.h>
+#include <Oma2Agent.h>
+#include <RoapDef.h>
+#include <f32file.h>
+#include <BodyPart.h>
+#include <SysUtil.h>
+#include <pathinfo.h>
+#include "CodDefs.h"
+#include <CodUi.rsg>
+#include <AknQueryDialog.h>
+#include <stringloader.h>
+#include  <bautils.h>
+#include    "FileExt.h"
+
+#ifdef __SYNCML_DM_FOTA
+#include <fotaengine.h>
+#include "FotaSaver.h"
+/// FOTA Update Package type.
+_LIT8( KFotaPackageDataType, "application/vnd.nokia.swupd.dp2" );
+/// Default FOTA package id.
+LOCAL_D const TInt KCodDefaultFotaPkgId = -1;
+#endif /*def __SYNCML_DM_FOTA */
+
+#ifdef RD_MULTIPLE_DRIVE
+#include <centralrepository.h>
+#include <driveinfo.h>
+#include <BrowserUiSDKCRKeys.h>
+#endif //RD_MULTIPLE_DRIVE
+
+#include <bldvariant.hrh>
+
+// ================= CONSTANTS =======================
+const TInt KDownloadInfoIncrSize = 2*4096;     // used for DownloadInfo
+
+/// Name of UTF-8 character set.
+_LIT8( KCodUtf8, "utf-8" );
+
+#ifdef RD_MULTIPLE_DRIVE
+_LIT( KDefaultDriveListSep, ";" );
+_LIT( KDefaultDriveList, "C;E" );
+#endif
+// ================= MEMBER FUNCTIONS =======================
+
+// ---------------------------------------------------------
+// CCodEngBase::~CCodEngBase()
+// ---------------------------------------------------------
+//
+EXPORT_C CCodEngBase::~CCodEngBase()
+    {
+    Cancel();
+    delete iRoapData;
+
+    if(iSaver)
+        {
+        iSaver->Cleanup( !Pausable() );
+        }
+
+    delete iSaver;
+    delete iDocHandler;
+    delete iLoader;
+    delete iConn;
+    delete iCodBuf;
+    delete iData;
+    iFs.Close();
+    CLOG(( ECodEng, 2, _L("CCodEngBase::~CCodEngBase") ));
+    CLOG(( ECodEng, 2, _L("*****************") ));
+    }
+
+// ---------------------------------------------------------
+// CCodEngBase::SetL()
+// ---------------------------------------------------------
+//
+EXPORT_C void CCodEngBase::SetL
+        (
+        const TDesC8& aBuf,
+        TRequestStatus* aStatus,
+        const CAiwGenericParamList* aParams,
+        const RPointerArray<CBodyPart>* aParts
+        )
+    {
+    CLOG(( ECodEng, 0, _L("-> CCodEngBase::SetL aParams=0x%x, aParts=0x%x"), \
+        &aParams, aParts ));
+
+    // Misuse asserts.
+    __ASSERT_ALWAYS( aStatus, CodPanic( ECodInvalidArguments ) );
+    __ASSERT_ALWAYS( iState == EInit || iState == EReady, \
+                                            CodPanic( ECodOffState ) );
+    // Internal asserts.
+    __ASSERT_DEBUG( !iConn, CodPanic( ECodInternal ) );
+    __ASSERT_DEBUG( !iLoader, CodPanic( ECodInternal ) );
+    __ASSERT_DEBUG( !iParentStatus, CodPanic( ECodInternal ) );
+    __ASSERT_DEBUG( !iSaver, CodPanic( ECodInternal ) );
+    __ASSERT_DEBUG( !iCodBuf, CodPanic( ECodInternal ) );
+
+    ResetPaths();
+    delete iSaver;
+    iSaver = NULL;
+    iData->Reset();
+    iParts = aParts;
+    iParams = aParams;
+    iType = TDataType();
+    iHandler = TUid::Null();
+    delete iRoapData;
+    iRoapData = NULL;
+
+    // Default parameters.
+    TPtrC8 sourceUri;
+    TPtrC8 charset( KCodUtf8 );
+    iPreferredIap = 0;
+    
+    // Get params from GenericParams.
+    if ( iParams )
+        {
+        CodUtil::GetDesParamLC( sourceUri, EGenericParamURL, *iParams );
+        CodUtil::GetDesParamLC( charset, EGenericParamCharSet, *iParams );
+        CodUtil::GetUint32Param( iPreferredIap, EGenericParamAccessPoint, *iParams );
+        
+        CodUtil::GetUint32Param( iDownloadId, EGenericParamDownloadId, *iParams );
+        
+        TUint32 AppUId(0);
+        CodUtil::GetUint32Param( AppUId, EGenericParamApplication, *iParams );
+        iAppUId.iUid = AppUId;
+
+		// Generate COD DL Info folder name - C:\system\dmgr\<appuid>\codinfo\
+		
+		TBuf<KMaxPath> folderName;
+		CODDownloadInfoFolder(folderName);
+		
+		// TO DO - Create the folder if it does not exist
+		
+        iCodDlInfoPath.Format( _L("%S%d"), &folderName,iDownloadId  );
+
+        }
+
+    iData->SetSourceUriL( sourceUri );
+    iCodBuf = CodUtil::ConvertToUcs2L( aBuf, charset, iFs );
+
+    if ( iParams )
+        {
+        CleanupStack::PopAndDestroy( 2 );   // Two pushed temp buffer.
+        }
+        
+    iParentStatus = aStatus;
+    *iParentStatus = KRequestPending;
+
+    Continue( ESet );
+
+    CLOG(( ECodEng, 0, _L("<- CCodEngBase::SetL (user 8-bit)") ));
+    }
+
+
+
+
+// ---------------------------------------------------------
+// CCodEngBase::SetL()
+// ---------------------------------------------------------
+//
+EXPORT_C void CCodEngBase::SetL
+        (
+        const TInt aDownloadId,
+        const TUid aDlUid,
+        //TRequestStatus* aStatus,        
+        const RPointerArray<CBodyPart>* aParts
+        )
+
+	{
+    ResetPaths();
+    delete iSaver;
+    iSaver = NULL;
+    iData->Reset();
+    iParts = aParts;
+    //iParams = aParams;
+    iType = TDataType();
+    iHandler = TUid::Null();
+    delete iRoapData;
+    iRoapData = NULL;
+    
+
+    // Default parameters.
+    TPtrC8 sourceUri;
+    TPtrC8 charset( KCodUtf8 );
+    iPreferredIap = 0;
+  	//iLoader->LoadDownloadInfoL()
+    //Read from info file
+	iAppUId = aDlUid;
+	iDownloadId = aDownloadId;
+	TBuf<KMaxPath> folderName;
+	CODDownloadInfoFolder(folderName); 
+	iCodDlInfoPath.Format( _L("%S%d"), &folderName,iDownloadId  );
+	
+	// Download resumed after Pause 
+	iResumedDownload = ETrue;   
+   	
+   	LoadInfoFilesL();
+    	
+	}
+// ---------------------------------------------------------
+// CCodEngBase::CODDownloadInfoFolder()
+// ---------------------------------------------------------
+//
+void CCodEngBase::CODDownloadInfoFolder( TDes& aFolder ) const
+    {
+    aFolder.Format( KDownloadFolderFormat, 
+                        &KDmDefaultDir, 
+                        iAppUId,
+                        &KInfoFilesCodDirName );
+    }
+
+// ---------------------------------------------------------
+// CCodEngBase::Data()
+// ---------------------------------------------------------
+//
+EXPORT_C const CCodData& CCodEngBase::Data() const
+    {
+    return *iData;
+    }
+
+// ---------------------------------------------------------
+// CCodEngBase::SetObserver()
+// ---------------------------------------------------------
+//
+EXPORT_C void CCodEngBase::SetObserver( MCodLoadObserver* aObserver )
+    {
+    CLOG(( ECodEng, 2, _L("CCodEngBase::SetObserver(0x%x)"), aObserver ));
+    __ASSERT_ALWAYS( !(aObserver && iObserver), \
+        CodPanic( ECodObserverAlreadySet ) );
+    iObserver = aObserver;
+    if ( iSaver )
+        {
+        iSaver->SetObserver( iObserver );
+        }
+    if ( iProgress )
+        {
+        iProgress->SetObserver( iObserver );
+        }
+    }
+
+// ---------------------------------------------------------
+// CCodEngBase::Accept()
+// ---------------------------------------------------------
+//
+EXPORT_C void CCodEngBase::Accept( TRequestStatus* aStatus )
+    {
+    CLOG(( ECodEng, 0, _L("-> CCodEngBase::Accept") ));
+    // Misuse asserts.
+    __ASSERT_ALWAYS( iData->IsValid(), CodPanic( ECodInvalidData ) );
+    __ASSERT_ALWAYS( aStatus, CodPanic( ECodInvalidArguments ) );
+    __ASSERT_ALWAYS( iState == EReady, CodPanic( ECodOffState ) );
+    // Internal asserts.
+    __ASSERT_DEBUG( !iConn, CodPanic( ECodInternal ) );
+    __ASSERT_DEBUG( !iLoader, CodPanic( ECodInternal ) );
+    __ASSERT_DEBUG( !iParentStatus, CodPanic( ECodInternal ) );
+
+    iParentStatus = aStatus;
+    *iParentStatus = KRequestPending;	
+    /*
+	OMA 2: If the license element includes the order attribute and the order attribute
+	is equal to the post. The contents of the license element MUST NOT be passed 
+	to the License Agent unless the Media Object or Product is successfully downloaded		
+    */
+    if (iIsLicense && !iData->IsPostOrder())
+	{
+	  // dd2 case with license tag and order tag equals to "any", 
+	  // so we should install the ROAP trigger as soon as it became available
+	  Continue( EStartInstallRoap );
+	}
+    else
+	{
+	  // we should install MO first		
+	  // 1) dd1 case
+	  // 2) dd2 without license tag
+	  // 3) dd2 with license tag and order tag = "POST"
+	  __ASSERT_DEBUG( !iSaver, CodPanic( ECodInternal ) );
+	  Continue( EStartConnect );
+	}
+    CLOG(( ECodEng, 0, _L("<- CCodEngBase::Accept") ));
+    }
+
+// ---------------------------------------------------------
+// CCodEngBase::Reject()
+// ---------------------------------------------------------
+//
+EXPORT_C void CCodEngBase::Reject( TRequestStatus* aStatus )
+    {
+    CLOG(( ECodEng, 0, _L("-> CCodEngBase::Reject") ));
+    // Misuse asserts.
+    __ASSERT_ALWAYS( iData->IsValid(), CodPanic( ECodInvalidData ) );
+    __ASSERT_ALWAYS( aStatus, CodPanic( ECodInvalidArguments ) );
+    __ASSERT_ALWAYS( iState == EReady, CodPanic( ECodOffState ) );
+    // Internal asserts.
+    __ASSERT_DEBUG( !iConn, CodPanic( ECodInternal ) );
+    __ASSERT_DEBUG( !iLoader, CodPanic( ECodInternal ) );
+    __ASSERT_DEBUG( !iParentStatus, CodPanic( ECodInternal ) );
+//TODO
+	if (!iIsLicense ) 
+	{
+    __ASSERT_DEBUG( !iSaver, CodPanic( ECodInternal ) );
+	}
+
+    iParentStatus = aStatus;
+    *iParentStatus = KRequestPending;
+
+    iResult = KErrAbort;
+    iStatusCode = StatusCode( iResult, iState );
+    Continue( EStartNotify );
+    CLOG(( ECodEng, 0, _L("<- CCodEngBase::Reject") ));
+    }
+
+// ---------------------------------------------------------
+// CCodEngBase::Stop()
+// ---------------------------------------------------------
+//
+EXPORT_C void CCodEngBase::Stop()
+    {
+    CLOG(( ECodEng, 0, _L("-> CCodEngBase::Stop iState(%d)"), iState ));
+
+    // This method is almost the same as DoCancel, yet works differently:
+    //
+    // When Cancel()->DoCancel() is called, this Active Object is not longer
+    // active (set inactive by the framework). That is, RunL will not be called
+    // after Cancel(). Anything that is going on stopped abruptly, without
+    // any further processing, we are Done() (parent is completed).
+    //
+    // When Stop is called, we still stay active, so after cancelling the
+    // outstanding request (if any), we will complete (RunL will be called)
+    // with KErrCancel. That triggers further processing, so we are not Done()
+    // yet (parent is not completed).
+    //
+    // Having this method comes from the logic of how a downloading is
+    // cancelled: after cancel, we may still have to continue with notify. In
+    // effect, a download must be cancelled twice to stop it; this method
+    // supports the double-cancel.
+
+    if ( iStopInProgress )
+        {
+        // Prevent reentrant calls.
+        // Reentrancy normally should not be possible: we call some Cancel()
+        // here, and that should not return and should not allow other object
+        // to run until done. But it does: disconnecting the WAP stack
+        // unfortunately includes waiting on the disconnect_cnf event.
+        // This means that there IS a Cancel which allows other objects run.
+        CLOG(( ECodEng, 0, _L("<- CCodEngBase::Stop already stopping") ));
+        return;
+        }
+    iStopInProgress = ETrue;
+
+    switch ( iState )
+        {
+        case ESet:
+            {
+            // Cancelled before we could start.
+            delete iCodBuf;
+            iCodBuf = NULL;
+            // Own status already completed (by self-completion).
+            __ASSERT_DEBUG( iStatus != KRequestPending, \
+                CodPanic( ECodInternal ) );
+            SelfComplete( KErrCancel );
+            // Complete parent.
+            iResult = KErrCancel;
+            Done();
+            break;
+            }
+
+        case EStartConnect:
+        case EStartFetch:
+        case EStartNotify:
+            {
+            // Already completed (by self-completion).
+            __ASSERT_DEBUG( iStatus != KRequestPending, \
+                CodPanic( ECodInternal ) );
+            SelfComplete( KErrCancel );
+            break;
+            }
+
+        case EConnect:
+            {
+            __ASSERT_DEBUG( iConn, CodPanic( ECodInternal ) );
+            iConn->Cancel();
+            // We are not Done() - parent request is still outstanding, we
+            // are still active. RunL will be called with KErrCancel.
+            break;
+            }
+
+        case EFetch:
+            {
+            if ( iObserver && iNotificationStatus == ELoad )
+                {
+                CLOG(( ECodEng, 3, \
+                    _L("-> CCodEngBase::Stop notify StartCancelL") ));
+                TRAP_IGNORE( iObserver->StartCancelL() );
+                iNotificationStatus = ECancel;
+                }
+            __ASSERT_DEBUG( iLoader, CodPanic( ECodInternal ) );
+            iLoader->Cancel();
+            // We are not Done() - parent request is still outstanding, we
+            // are still active. RunL will be called with KErrCancel.
+            break;
+            }
+
+        case EInstall:
+        case EInstallRoap:
+            {
+            __ASSERT_DEBUG( iSaver, CodPanic( ECodInternal ) );
+            iSaver->CancelInstall();
+            // We are not Done() - parent request is still outstanding, we
+            // are still active. RunL will be called with KErrCancel.
+            break;
+            }
+
+        case ENotify:
+            {
+            __ASSERT_DEBUG( iLoader, CodPanic( ECodInternal ) );
+            iLoader->Cancel();
+            // We are not Done() - parent request is still outstanding, we
+            // are still active. RunL will be called with KErrCancel.
+            break;
+            }
+
+        case EInit:
+        case EReady:
+        case EStartInstall:
+        default:
+            {
+            if ( iObserver && iNotificationStatus == EPaused )
+                {
+                TRAP_IGNORE( iObserver->StartCancelL() );
+                iNotificationStatus = ECancel;
+                }
+            // No request is outstanding, but as this is an user-callable
+            // method, tolerate misuse (and do nothing).
+            break;
+            }
+        }
+    iStopInProgress = EFalse;
+    CLOG(( ECodEng, 0, _L("<- CCodEngBase::Stop") ));
+    }
+
+// ---------------------------------------------------------
+// CCodEngBase::RemovableMedia()
+// ---------------------------------------------------------
+//
+EXPORT_C TBool CCodEngBase::RemovableMedia() const
+    {
+    return iRemovableMedia;
+    }
+
+// ---------------------------------------------------------
+// CCodEngBase::GetPath()
+// ---------------------------------------------------------
+//
+EXPORT_C TPtrC CCodEngBase::GetPath() const
+    {
+    if(!iData || !iData->Count() || !(*iData)[iData->ActiveDownload()]->iFullName )
+        return KNullDesC();
+    return *((*iData)[iData->ActiveDownload()]->iFullName);
+    }
+
+// ---------------------------------------------------------
+// CCodEngBase::GetDestFilePath()
+// ---------------------------------------------------------
+//
+EXPORT_C TPtrC CCodEngBase::GetDestFilePath (TInt aMOIndex ) const
+    {
+    if(iData && aMOIndex >=1 && aMOIndex <= iData->Count())
+        {
+        if((*iData)[aMOIndex]->iFullName)
+        	return *((*iData)[aMOIndex]->iFullName);
+        }
+    return TPtrC( KNullDesC );
+    }   
+
+// ---------------------------------------------------------
+// CCodEngBase::GetType()
+// ---------------------------------------------------------
+//
+EXPORT_C const TDataType& CCodEngBase::GetType() const
+    {
+    return iType;
+    }
+
+// ---------------------------------------------------------
+// CCodEngBase::GetHandler()
+// ---------------------------------------------------------
+//
+EXPORT_C TUid CCodEngBase::GetHandler() const
+    {
+    return iHandler;
+    }
+
+// ---------------------------------------------------------
+// CCodEngBase::GetStatusCode()
+// ---------------------------------------------------------
+//
+EXPORT_C TInt CCodEngBase::GetStatusCode() const
+    {
+    return iStatusCode;
+    }
+
+// ---------------------------------------------------------
+// CCodEngBase::GetRoapData()
+// ---------------------------------------------------------
+//
+EXPORT_C const CRoapData* CCodEngBase::GetRoapData() const
+    {
+    return iRoapData;
+    }
+
+// ---------------------------------------------------------
+// CCodEngBase::SetCodDlAttached()
+// ---------------------------------------------------------
+//
+EXPORT_C void CCodEngBase::SetCodDlAttached(const TBool aValue)
+    {
+       iAttached = aValue;
+       if(iSaver)
+       {
+        iSaver->SetProgressiveMode(aValue);	
+       }
+       
+    }
+    
+// ---------------------------------------------------------
+// CCodEngBase::CCodEngBase()
+// ---------------------------------------------------------
+//
+CCodEngBase::CCodEngBase( MCodLoadObserver* aObserver )
+: CActive( CActive::EPriorityStandard ),
+  iState( EInit ),
+  iObserver( aObserver ),
+  iStopInProgress( EFalse ),
+  iPreferredIap( 0 ),
+  iNotificationStatus( ENull ),
+  iFsUsed( EFalse ),
+  iDownloadId( 0 ),
+#ifdef RD_MULTIPLE_DRIVE 
+  iSpaceAvailOk( EFalse ),
+  iAvailDriveSpace( -1 ),
+#else
+  iPhoneMemoryOk( EFalse ),
+  iMmcOk( EFalse ),
+#endif
+  iRemovableMedia( EFalse ),
+  iStatusCode( KHttp902UserCancelled ),
+  iResult( KErrGeneral ),
+  iContentTypeCheck ( EFalse ),
+  iResumedDownload ( EFalse )  
+    {
+    CLOG(( ECodEng, 2, _L("") ));
+    CLOG(( ECodEng, 2, _L("*****************") ));
+    CLOG(( ECodEng, 2, _L("CCodEngBase::CCodEngBase") ));
+    CLOG(( ECodEng, 2, _L8("Build time " __DATE__ " " __TIME__) ));
+    CActiveScheduler::Add( this );
+    }
+
+// ---------------------------------------------------------
+// CCodEngBase::ConstructL()
+// ---------------------------------------------------------
+//
+void CCodEngBase::ConstructL( CEikProcess* aProcess )
+    {
+    iData = CCodData::NewL();
+    iDocHandler = CDocumentHandler::NewL( aProcess );
+    User::LeaveIfError( iFs.Connect() );
+#ifdef RD_MULTIPLE_DRIVE
+    QueryDriveListL();
+#endif
+    }
+
+// ---------------------------------------------------------
+// CCodEngBase::DoCancel()
+// ---------------------------------------------------------
+//
+void CCodEngBase::DoCancel()
+    {
+    CLOG(( ECodEng, 2, _L("-> CCodEngBase::DoCancel iState(%d)"), iState ));
+
+    switch ( iState )
+        {
+        case ESet:
+        case EStartConnect:
+        case EStartFetch:
+        case EStartNotify:
+            {
+            // Already completed (by self-completion).
+            __ASSERT_DEBUG( iStatus != KRequestPending, \
+                CodPanic( ECodInternal ) );
+            SelfComplete( KErrCancel );
+            break;
+            }
+
+        case EConnect:
+            {
+            // Instant abort, without any further processing
+            // (no install, no notify).
+            __ASSERT_DEBUG( iConn, CodPanic( ECodInternal ) );
+            iConn->Cancel();
+            break;
+            }
+            
+        case EFetch:
+        case ENotify:
+            {
+            // Instant abort, without any further processing
+            // (no install, no notify).
+            __ASSERT_DEBUG( iLoader, CodPanic( ECodInternal ) );
+            iLoader->Cancel();
+            break;
+            }
+
+        case EInstall:
+            {
+            // Instant abort, without any further processing (no notify).
+            __ASSERT_DEBUG( iSaver, CodPanic( ECodInternal ) );
+            iSaver->CancelInstall();
+            break;
+            }
+            
+        case EInit:
+        case EReady:
+        case EStartInstall:
+        default:
+            {
+            // No requests should be outstanding in these states.
+            CodPanic( ECodInternal );
+            break;
+            }
+        }
+
+    iStatusCode = KHttp902UserCancelled;    // "Clarity only" code.
+    iResult = KErrCancel;                   // "Clarity only" code.
+    Done();                                 // Complete parent.
+    CLOG(( ECodEng, 2, _L("<- CCodEngBase::DoCancel") ));
+    }
+
+
+EXPORT_C void CCodEngBase::Pause()
+    {
+    CLOG(( ECodEng, 2, _L("-> CCodEngBase::Pause iState(%d)"), iState ));
+
+    switch ( iState )
+        {
+        case EFetch:
+            {
+            // Instant abort, without any further processing
+            // (no install, no notify).
+            __ASSERT_DEBUG( iLoader, CodPanic( ECodInternal ) );
+            iLoader->Pause();
+            //iLoader->CompleteTransaction();
+            break;
+            }
+        }
+
+    //Done();                                 // Complete parent.
+    CLOG(( ECodEng, 2, _L("<- CCodEngBase::Pause") ));
+    }
+
+// ---------------------------------------------------------
+// CCodEngBase::RunL()
+// ---------------------------------------------------------
+//
+void CCodEngBase::RunL()
+    {
+    CLOG(( ECodEng, 2, _L("-> CCodEngBase::RunL iStatus(%d) iState(%d)"), \
+        iStatus.Int(), iState ));
+
+    switch( iState )
+        {
+        case ESet:
+            {
+            SetL();
+            break;
+            }
+
+        case EStartInstallRoap:
+            {
+            StartInstallRoapL();
+            break;
+            }
+
+        case EInstallRoap:
+            {
+            EndInstallRoapL();
+            break;
+            }
+
+        case EStartConnect:
+            {
+            StartConnectL();
+            break;
+            }
+
+        case EConnect:
+            {
+            EndConnectL();
+            break;
+            }
+
+        case EStartFetch:
+            {
+            StartFetchL();
+            break;
+            }
+
+        case EFetch:
+            {
+            EndFetchL();
+            break;
+            }
+
+        case EStartInstall:
+            {
+            StartInstallL();
+            break;
+            }
+
+        case EInstall:
+            {
+            EndInstallL();
+            break;
+            }
+            
+        case EStartNotify:
+            {
+            StartNotifyL();
+            break;
+            }
+
+        case ENotify:
+            {
+            EndNotifyL();
+            break;
+            }
+        case EMediaChange:
+        	{
+        	ChangeMediaObjectL();
+        	break;
+        	}
+        case EStartProductNotify:
+            {
+            StartProductNotifyL();
+            break;
+            }
+        case EProductNotify:
+            {
+            EndProductNotifyL();
+            break;            
+            }
+        case EInit:
+        case EReady:
+        default:
+            {
+            // No requests should be outstanding in these states.
+            CLOG(( ECodEng, 0, _L("CCodEngBase::RunL: unexpected state") ));
+            CodPanic( ECodInternal );
+            break;
+            }
+        }
+    CLOG(( ECodEng, 2, _L("<- CCodEngBase::RunL") ));
+    }
+
+// ---------------------------------------------------------
+// CCodEngBase::RunError()
+// ---------------------------------------------------------
+//
+TInt CCodEngBase::RunError( TInt aError )
+    {
+    CLOG(( ECodEng, 2, \
+        _L("-> CCodEngBase::RunError iStatus(%d) iState(%d) aError(%d)"), \
+        iStatus.Int(), iState, aError ));
+    switch( iState )
+        {
+        case ESet:
+            {
+            delete iCodBuf;
+            iCodBuf = NULL;
+            // Failed - classify reason and notify about failure.
+            iStatusCode = StatusCode( aError, iState );
+            iResult = aError;
+            Continue( EStartNotify );
+            break;
+            }
+
+        case EStartInstallRoap:
+        case EInstallRoap:
+			{
+            iStatusCode = StatusCode( aError, iState );
+            iResult = aError;
+            Continue( EStartNotify );
+            break;
+			}
+        case EStartConnect:
+        case EConnect:
+        case EStartFetch:
+        case EFetch:
+        case EStartInstall:
+        case EInstall:
+            {
+            
+            if(aError != KErrCodHttpServerError)
+                {
+                //if PreconditionFailed check if the updated DD URI is present
+                //cancel the download if not set
+                if( aError == KErrCodHttpPreconditionFailed )
+                    {
+                if( iData && iData->UpdatedDDUriL().Length() )
+                        {
+                        iState = EInit;//in case of 412 we should restart from first state
+                        iStatusCode =  StatusCode( aError, iState );
+                    	TBuf<KMaxPath>   folderName;
+                    	CODDownloadInfoFolder(folderName);
+
+                    	HBufC* fileNameBuf = HBufC::NewLC( KMaxPath );
+                    	TPtr fileName = fileNameBuf->Des();
+
+                    	fileName.Format( _L("%S%d"), &folderName,iDownloadId  );
+                        RFs fs;
+                        User::LeaveIfError( fs.Connect() );
+                        fs.Delete( fileName );//delete the info path as download has to begin from fresh state
+                        CleanupStack::PopAndDestroy( fileNameBuf );	
+                        fs.Close();                    
+                        }
+                    else
+                        {
+                        // Failed - classify reason and notify about failure.
+                        iStatusCode = StatusCode( aError, iState );
+                        iResult = aError;
+                                            
+                        //If ther is no Updated DD Uri. Cancel the download.
+                        DoCancel();
+                        break;
+                        }
+                    }
+                else
+                    {
+                    //If user cancel the download, delete the media object also.
+                    //If paused due to other errors, delete the file if non-pausable.
+                    if(iSaver)
+                        {
+                        TBool delContent = (aError == KErrCancel) ? ETrue : !( iData && (*iData)[iData->ActiveDownload()]->iPausable );
+                        iSaver->Cleanup( delContent );
+                        }
+                    }
+                if( iObserver && KErrCodHttpPreconditionFailed != aError)
+                    {
+                    //TODO : Pass the error code if required
+                    iObserver->DownloadPaused();
+                    iNotificationStatus = EPaused;
+                    } 
+                    
+                }
+            delete iSaver;  // Cleans up.
+            iSaver = NULL;
+
+            // Failed - classify reason and notify about failure.
+            iStatusCode = StatusCode( aError, iState );
+            iResult = aError;
+            Continue( EStartNotify );
+            break;
+            }
+
+        case EStartNotify:
+        case ENotify:
+            {
+            //If Notify Fails do not delete download.
+            //Ignore the error code.
+            //End State Machine.Download is Successful.
+            Done();
+            break;
+            }
+        case EStartProductNotify:
+        case EProductNotify:
+            {
+            Done();
+            break;
+            }
+
+        case EInit:
+        case EReady:
+        default:
+            {
+            // No requests should be outstanding in these states.
+            CLOG(( ECodEng, 0, _L("CCodEngBase::RunError: unexpected state") ));
+            CodPanic( ECodInternal );
+            break;
+            }
+        }
+    
+    if (iData && iData->Count())
+    	{
+	    (*iData)[iData->ActiveDownload()]->iStatusCode = iStatusCode;
+    	(*iData)[iData->ActiveDownload()]->iResult = iResult;
+    	}
+    
+    CLOG(( ECodEng, 2, _L("<- CCodEngBase::RunError") ));
+    return KErrNone;
+    }
+
+// ---------------------------------------------------------
+// CCodEngBase::SetL()
+// ---------------------------------------------------------
+//
+void CCodEngBase::SetL()
+    {
+    CLOG(( ECodEng, 2, _L("-> CCodEngBase::SetL (internal)") ));
+    __ASSERT_DEBUG( iState == ESet, CodPanic( ECodInternal ) );
+    __ASSERT_DEBUG( iCodBuf, CodPanic( ECodInternal ) );
+    
+    ParseDataL();
+
+    iData->SetActiveDownload ( 1 );
+    if( !(*(*iData)[iData->ActiveDownload()]).Name().Length() )
+    {
+    //No name To display
+    //add "unnamed"
+     (*(*iData)[iData->ActiveDownload()]).SetNameL( _L("Unnamed") ); 
+    }
+    CLOG(( ECodEng, 4, _L("CCodEngBase::SetL: parsed OK") ));
+    delete iCodBuf;
+    iCodBuf = NULL;
+    CheckDataL();   // TODO move that out from derived classes.
+    
+    TInt err = KErrNone;
+    for( TInt i = 1; i <= iData->Count() ; ++i )
+        {
+        iData->SetActiveDownload ( i );
+        //So that this download is considered when resume happens
+        //only in progress download can resume
+        (*iData)[ iData->ActiveDownload()]->iState = EInProgress; 
+        TRAP( err , CapabilityCheckL());
+        if( !err )
+            {
+            break;
+            }
+        else if( err != KErrCodInsufficientSpace )
+            {
+            User::Leave( err );            
+            }        
+        }
+        
+    if( err )
+    	{
+	    User::Leave( err );
+    	}
+    iState = EReady;
+    iResult = KErrNone;
+    iStatusCode = StatusCode( iResult, iState );
+
+    //Create info files
+    //This would create info file for album and each media track
+    
+    StoreInfoFilesL();
+    
+    // Update album and track info in server
+    UpdateMediaInfoL();
+    
+    if (iIsLicense && !iData->IsPostOrder())
+	{
+      // install Roap trigger first
+      DoneDD2();  
+	}
+    else
+	{
+      Done();
+	}
+
+    CLOG(( ECodEng, 2, _L("<- CCodEngBase::SetL (internal)") ));
+    }
+
+// ---------------------------------------------------------
+// CCodEngBase::SetFileNameL()
+// ---------------------------------------------------------
+//
+void CCodEngBase::SetFileNameL()
+    {
+
+    // Full name that we need to construct
+    HBufC* fullName = HBufC::NewLC(KMaxFileName);
+    TPtr fullNamePtr( fullName->Des() );
+    fullNamePtr.Append( (*iData)[iData->ActiveDownload()]->iTempPath );            // "c:\\system\\temp\\"
+    fullNamePtr.Append( (*iData)[iData->ActiveDownload()]->Name() );        // "c:\\system\\temp\\myfile"
+    
+   
+    
+    const TDataType& type( (*iData)[iData->ActiveDownload()]->Types().MdcaPoint( 0) );
+    
+    //Following code is added to fix the bug DRAI-7KA8TT( File is not available in Gallery even when download list shows "Saved to Gallery".)
+    //Fix applied: Changing the content type that is passed to document handler to "application/vnd.oma.drm.content" when the received content type is
+    //"application/vnd.oma.drm.message"
+    //This is because document handler is not changing the extension when content type is passed as "application/vnd.oma.drm.message"  
+    if(0==type.Des8().Compare(KOma1DrmMessageContentType))
+        {
+        // Add extention to full name of file
+        iDocHandler->CheckFileNameExtension(fullNamePtr, TDataType(KOma1DcfContentType)); // "c:\\system\\temp\\myfile.mp3"    
+        }
+    else
+        {
+        // Add extention to full name of file
+        iDocHandler->CheckFileNameExtension(fullNamePtr, type ); // "c:\\system\\temp\\myfile.mp3"    
+        }
+
+    CleanupStack::Pop(fullName);
+    
+    // This is the Full name that we want
+    delete (*iData)[iData->ActiveDownload()]->iFullName;
+    (*iData)[iData->ActiveDownload()]->iFullName = fullName;
+    
+    }
+
+// ---------------------------------------------------------
+// CCodEngBase::SetUniqueFileNameL()
+// ---------------------------------------------------------
+//
+void CCodEngBase::SetUniqueFileNameL()
+    {
+    HBufC* fullName = HBufC::NewLC(KMaxFileName);
+    TPtr fullNamePtr( fullName->Des() );
+    fullNamePtr.Append( (*iData)[iData->ActiveDownload()]->iFullName->Des() );
+    
+    // Get the file path
+    HBufC* filePath = HBufC::NewLC(KMaxFileName);
+    filePath->Des().Append( (*iData)[iData->ActiveDownload()]->iTempPath );        // "c:\\system\\temp\\"
+
+    // Retrieve extention as a string
+    HBufC* extention = HBufC::NewLC(KMaxFileName);
+    TInt dotInd = fullNamePtr.LocateReverse( '.' );
+    if( dotInd != KErrNotFound )
+        // filename extension found.
+        {
+        extention->Des().Copy( fullNamePtr.Right( fullNamePtr.Length() - dotInd ) );
+        }
+
+    // File name without extention
+    HBufC* fileName = HBufC::NewLC(KMaxFileName);
+    fileName->Des().Append( (*iData)[iData->ActiveDownload()]->Name() );    // "myfile"
+    TInt dot = fileName->LocateReverse( '.' );//check if Dot is part of name in DD file
+    // Find a unique file name. If fileName already exists, then this function will
+    // change fileName to some other unique name (like "myfile(1)")
+    if( dot != KErrNotFound )
+        {
+        //Remove Extension 
+        //File Name is with an extension.   
+        fileName->Des().Copy( fileName->Des().Left(dot));         
+        }        
+    iSaver->ConvertDownloadNameUniqueL( filePath, fileName, extention );
+    HBufC* dispName = HBufC::NewLC(KMaxFileName);
+    TPtr displayName(dispName->Des());
+    displayName.Append(*fileName);
+    if( dot != KErrNotFound )
+        {
+        //Since Name is with extension Append to Display Name
+        displayName.Append(*extention);
+        }
+    (*iData)[iData->ActiveDownload()]->SetNameL( displayName );
+    CleanupStack::PopAndDestroy(dispName);
+
+
+    // Now when we have a unique file name, create the full name (with path and extention)
+    fullNamePtr.Copy( *filePath );
+    fullNamePtr.Append( *fileName );
+	fullNamePtr.Append( *extention );           // Example - "c:\\system\\temp\\myfile(1).mp3"
+    CleanupStack::PopAndDestroy(fileName);
+    CleanupStack::PopAndDestroy(extention);
+    CleanupStack::PopAndDestroy(filePath);
+    CleanupStack::Pop(fullName);
+    
+    // This is the Full name that we want
+    delete (*iData)[iData->ActiveDownload()]->iFullName;
+    (*iData)[iData->ActiveDownload()]->iFullName = fullName;
+
+    }
+
+// ---------------------------------------------------------
+// CCodEngBase::StartConnectL()
+// ---------------------------------------------------------
+//
+void CCodEngBase::StartConnectL()
+    {
+    CLOG(( ECodEng, 2, _L("-> CCodEngBase::StartConnectL") ));
+    __ASSERT_DEBUG( iState == EStartConnect, CodPanic( ECodInternal ) );		
+    if (!iIsLicense ) 
+	{
+       __ASSERT_DEBUG( !iSaver, CodPanic( ECodInternal ) );
+	}
+    __ASSERT_DEBUG( !iConn, CodPanic( ECodInternal ) );
+    
+
+        //For the first track it is done already
+        CapabilityCheckL(); 
+
+        //Inform server about the Active download
+        iObserver->SetActiveDownload( );
+        iObserver->ContentTypeChanged();
+        iObserver->MediaObjectNameChanged();
+                
+        //Content type check should be done for subsequent tracks
+        iContentTypeCheck = EFalse;
+        
+        //Download is resumed for the current track in the album. For the subsequent tracks(downloads),iResumedDownload should be false
+        iResumedDownload = EFalse;
+        
+        
+        //Let all download that begin be in this state and then go to subsequent Succeeded state
+        (*iData)[iData->ActiveDownload()]->iState = EInProgress;     
+
+    if ( iFsUsed && (*iData)[iData->ActiveDownload()]->iTempPath == KNullDesC )
+        {
+        // Select drive before IAP selection.
+        SetPathsL();
+        SetFileNameL();       
+        //Store in Info File
+        StoreSubInfoFileL( NULL, iData->ActiveDownload() );
+        }
+    else
+        {
+        //Paused Download change display name if not already done
+        iObserver->MediaObjectNameChanged();
+        }
+
+    if ( CodUtil::IsCidSchemeL( (*iData)[iData->ActiveDownload()]->Url() ) &&
+         ( !(*iData)[iData->ActiveDownload()]->InstallNotify().Length() ||
+           CodUtil::IsCidSchemeL( (*iData)[iData->ActiveDownload()]->InstallNotify() )
+         )
+       )
+        {
+        CLOG(( ECodEng, 3, _L("  all URI-s are cid -> no connect") ));
+        // All URI-s are cid, no need to connect.
+        // Synchronous state change - we are already under RunL().
+        iState = EConnect;
+        EndConnectL();
+        }
+    else
+        {
+        // We have at least one non-cid scheme URI, need to connect.
+        CLOG(( ECodEng, 3, _L("  connecting") ));
+        iConn = CConnection::NewL();
+        iConn->ConnectL( iPreferredIap, &iStatus );
+        iState = EConnect;
+        SetActive();
+        if ( iObserver )
+            {
+            CLOG(( ECodEng, 3, \
+                _L("-> CCodEngBase::StartConnectL notify StartLoadL(%d)"), \
+                KHttp900Success ));
+            iObserver->StartLoadL( KHttp900Success );
+            iNotificationStatus = ELoad;
+            }
+        }
+
+    CLOG(( ECodEng, 2, _L("<- CCodEngBase::StartConnectL") ));
+    }
+
+// ---------------------------------------------------------
+// CCodEngBase::EndConnectL
+// ---------------------------------------------------------
+//
+void CCodEngBase::EndConnectL()
+    {
+    CLOG(( ECodEng, 2, _L("-> CCodEngBase::EndConnectL iStatus(%d)"), \
+        iStatus.Int() ));
+    __ASSERT_DEBUG( iState == EConnect, CodPanic( ECodInternal ) );
+
+    User::LeaveIfError( iStatus.Int() );        // Handle errors in RunError().
+
+    // Synchronous state change - we are already under RunL().
+    iState = EStartFetch;
+    StartFetchL();
+    CLOG(( ECodEng, 2, _L("<- CCodEngBase::EndConnectL") ));
+    }
+
+// ---------------------------------------------------------
+// CCodEngBase::StartFetchL()
+// ---------------------------------------------------------
+//
+void CCodEngBase::StartFetchL()
+    {
+    CLOG(( ECodEng, 2, _L("-> CCodEngBase::StartFetchL") ));
+    __ASSERT_DEBUG( iState == EStartFetch, CodPanic( ECodInternal ) );
+    __ASSERT_DEBUG( !iLoader, CodPanic( ECodInternal ) );
+    if (!iIsLicense )
+	{
+      __ASSERT_DEBUG( !iSaver, CodPanic( ECodInternal ) );
+	}
+
+    // Setup progress.
+    // Fetch size is known. ROAP & notify traffic is estimated.
+    if(!iProgress)
+        {
+        iProgress = new (ELeave) TCodProgress( iObserver );
+
+        TInt roapBytes = (*iData)[iData->ActiveDownload()]->Type().Compare( KOma2TriggerContentType ) ?
+            0 :
+            KRoapProgressMax;
+/*
+            iProgress->Setup
+            (
+            iData->Size() + roapBytes ,
+            iData->InstallNotify().Length() ? KCodNotifyTraffic : 0 
+            );    
+*/
+            iProgress->Setup
+            (
+            (*iData)[iData->ActiveDownload()]->Size() + roapBytes ,
+            iData->InstallNotify().Length() ? KCodNotifyTraffic : 0 
+            ); 
+        }
+
+    if ( CodUtil::IsCidSchemeL( (*iData)[iData->ActiveDownload()]->Url() ) )
+        {
+        if ( !iParts )
+            {
+            // Cannot resolve cid: scheme URI-s without the multipart parts!
+            CLOG(( ECodEng, 4, _L("  no multipart, fail") ));
+            User::Leave( KErrNotFound );
+            }
+        CBodyPart* part = CodUtil::PartByCidL( *iParts, (*iData)[iData->ActiveDownload()]->Url() );
+        if ( !part )
+            {
+            CLOG(( ECodEng, 4, _L("  part not found, fail") ));
+            User::Leave( KErrNotFound );
+            }
+		CreateSaverL( part->ContentType() );
+        User::LeaveIfError( iSaver->AppendData( part->Body() ) );
+        iSaver->CloseStore();
+        iProgress->IncrementL( part->Body().Size() );
+        // Synchronous state change - we are already under RunL().
+        iState = EFetch;
+        EndFetchL();
+        }
+    else
+        {
+        __ASSERT_DEBUG( iConn, CodPanic( ECodInternal ) );
+        iLoader = CHttpLoader::NewL( *iConn, NULL, iProgress ,this);
+        HBufC8* url = CodUtil::AbsoluteUrlLC
+            ( iData->SourceUri(), (*iData)[iData->ActiveDownload()]->Url() );
+        iLoader->LoadL( *url, *this, &iStatus );
+        CleanupStack::PopAndDestroy( url );
+
+        iState = EFetch;
+        SetActive();
+	}
+    
+    CLOG(( ECodEng, 2, _L("<- CCodEngBase::StartFetchL") ));
+    }
+
+// ---------------------------------------------------------
+// CCodEngBase::EndFetchL
+// ---------------------------------------------------------
+//
+void CCodEngBase::EndFetchL()
+    {
+    CLOG(( ECodEng, 2, _L("-> CCodEngBase::EndFetchL iStatus(%d)"), \
+        iStatus.Int() ));
+    __ASSERT_DEBUG( iState == EFetch, CodPanic( ECodInternal ) );
+
+    User::LeaveIfError( iStatus.Int() );        // Handle errors in RunError().
+
+    __ASSERT_DEBUG( iSaver, CodPanic( ECodInternal ) );
+//TODO: ??  iState == EStoreOpen (for dd2) EStoreClose - for dd1
+    iSaver->CheckResponseAttributesL( *iData ); // Leaves if response not OK.
+
+	if (iIsLicense)
+	{
+    iStatusCode = KHttp956LicenseSuccess;
+	}
+	else
+	{
+    iStatusCode = KHttp900Success;
+	}
+    iResult = KErrNone;
+    // Synchronous state change - we are already under RunL().
+    iState = EStartInstall;
+    StartInstallL();
+    CLOG(( ECodEng, 2, _L("<- CCodEngBase::EndFetchL") ));
+    }
+
+// ---------------------------------------------------------
+// CCodEngBase::StartInstallL()
+// ---------------------------------------------------------
+//
+void CCodEngBase::StartInstallL()
+    {
+    CLOG(( ECodEng, 2, _L("-> CCodEngBase::StartInstallL iStatusCode(%d)"), \
+        iStatusCode ));
+    __ASSERT_DEBUG( iState == EStartInstall, CodPanic( ECodInternal ) );
+    __ASSERT_DEBUG( iSaver, CodPanic( ECodInternal ) );
+
+    //__ASSERT_DEBUG( iStatusCode == KHttp900Success, CodPanic( ECodInternal ) );
+
+    (*iData)[iData->ActiveDownload()]->iState = ETobeInstalled;
+    
+    if( iData->Count() > 1)
+        {
+        // Check to see if all tracks are downloaded. Install will be done only at the end
+        for( TInt i = 1; i <= iData->Count() ; ++i )
+            {
+            TInt state ((*iData)[i]->iState);
+            if( state != ETobeInstalled && state != ESucceeded )
+        	    {
+        	    Continue(EInstall);
+        	    return;
+        	    }
+            }
+        }
+
+    TInt installErr( KErrNone );
+
+	if (iObserver && (iObserver->ConnError() == KErrTimedOut))
+	{
+		User::LeaveIfError( KErrTimedOut );
+	}
+	else
+	    {
+	    if( iData->Count() > 1)
+	        {
+            TRAP( installErr, iSaver->BulkInstallL( &iStatus, *iData, iAttached ));
+	        }
+        else
+	        {
+            if (!iIsDd2)
+                {
+                TRAP( installErr, iSaver->InstallL( &iStatus, (*iData)[iData->ActiveDownload()]->Name(), iAttached ));
+                }
+            else
+                {
+                TRAP( installErr, iSaver->InstallL( &iStatus, (*iData)[iData->ActiveDownload()]->iFullName->Des(), iAttached )); 
+                }
+            //Move has happened update destination file name
+	        (*iData)[ iData->ActiveDownload()]->iFullName = iSaver->NameL();
+	        }
+	    }
+
+    // if download is DRM-protected content with Preview-only rights
+    // then we cannot move content, but will launch it from the temp file
+    // that it is currently in.  For all other errors we leave.
+    if( installErr == KDRMErrPreviewRights )
+        {
+        iDrmPreviewOnly = ETrue;
+        }
+    else
+        {
+        User::LeaveIfError( installErr );
+        }
+    SetActive();
+    iState = EInstall;
+    CLOG(( ECodEng, 4, _L("<- CCodEngBase::StartInstallL") ));
+    }
+
+// ---------------------------------------------------------
+// CCodEngBase::StartInstallRoapL()
+// ---------------------------------------------------------
+//
+void CCodEngBase::StartInstallRoapL()
+    {
+    CLOG(( ECodEng, 2, _L("-> CCodEngBase::StartInstallRoapL iStatusCode(%d)"), \
+        iStatusCode ));
+    __ASSERT_DEBUG( iState == EStartInstallRoap, CodPanic( ECodInternal ) );
+//TODO check if we have a retry the iSaver could be NULL ?
+    if (iSaver)
+	{
+	iSaver->InstallL( &iStatus, (*iData)[iData->ActiveDownload()]->Name(), ETrue );
+	}
+    // Synchronous state change - we are already under RunL().
+    iState = EInstallRoap;
+    SetActive();
+
+    CLOG(( ECodEng, 4, _L("<- CCodEngBase::StartInstallRoapL") ));
+    }
+
+// ---------------------------------------------------------
+// CCodEngBase::EndInstallRoapL()
+// ---------------------------------------------------------
+//
+void CCodEngBase::EndInstallRoapL()
+    {
+    CLOG(( ECodEng, 2, _L("-> CCodEngBase::InstallRoapL iStatusCode(%d)"), \
+        iStatusCode ));
+
+    User::LeaveIfError( iStatus.Int() );        // Handle errors in RunError().
+//TODO: make sure that 956 and 900 sent
+    iStatusCode = KHttp956LicenseSuccess;
+    iResult = KErrNone;
+//	iSaver->CloseStore();
+	iState = EStartConnect;
+	StartConnectL();
+    CLOG(( ECodEng, 4, _L("<- CCodEngBase::EndInstallRoapL") ));
+    }
+
+// ---------------------------------------------------------
+// CCodEngBase::EndInstallL()
+// ---------------------------------------------------------
+//
+void CCodEngBase::EndInstallL()
+    {
+    CLOG(( ECodEng, 2, _L("-> CCodEngBase::EndInstallL iStatus(%d)"), \
+        iStatus.Int() ));
+    __ASSERT_DEBUG( iState == EInstall, CodPanic( ECodInternal ) );
+
+    User::LeaveIfError( iStatus.Int() );    // Handle errors in RunError().
+    // Synchronous state change - we are already under RunL().
+    iState = EStartNotify;
+    StartNotifyL();
+    CLOG(( ECodEng, 4, _L("<- CCodEngBase::EndInstallL") ));
+    }
+    
+// ---------------------------------------------------------
+// CCodEngBase::StartNotifyL
+// ---------------------------------------------------------
+//
+void CCodEngBase::StartNotifyL()
+    {
+    __ASSERT_DEBUG( iState == EStartNotify, CodPanic( ECodInternal ) );
+
+    if ( iData && iData->Count() > 0 && iData->ActiveDownload() && (*iData)[iData->ActiveDownload()]->InstallNotify().Length() )
+        {
+	    CLOG(( ECodEng, 2, _L("-> CCodEngBase::StartNotifyL iStatusCode(%d)"), \
+	        iStatusCode ));
+
+        CLOG(( ECodEng, 4, _L("CCodEngBase::StartNotifyL: init request") ));
+        if ( !iProgress )
+            {
+            // Setup notify-only progress.
+            iProgress = new (ELeave) TCodProgress( iObserver );
+            iProgress->Setup( 0, KCodNotifyTraffic );    
+            }
+        iProgress->StartPhaseL( TCodProgress::ENotify );
+        TBool notifyObserver = EFalse;
+        // When notifying after fetch, we already have a loader (and the
+        // observer has already been notified about load).
+        // When notifying without fetch, we don't have a loader yet (and the
+        // observer has not been notified about load yet).
+        if ( !iConn )
+            {
+            iConn = CConnection::NewL();
+            }
+        // For notify, attach only (do no create new connection).
+        iConn->AttachL( iPreferredIap );
+        if( !iLoader )
+            {
+            iLoader = CHttpLoader::NewL( *iConn, NULL, iProgress ,this );
+            notifyObserver = ETrue;
+            }
+        HBufC8* url = CodUtil::AbsoluteUrlLC
+            ( (*iData)[iData->ActiveDownload()]->SourceUri(), (*iData)[iData->ActiveDownload()]->InstallNotify() );
+        iLoader->NotifyL( *url, StatusText( iStatusCode ), &iStatus );
+        CleanupStack::PopAndDestroy( url );
+        iState = ENotify;
+        SetActive();
+        if ( iObserver && notifyObserver )
+            {
+            if ( iStatusCode == KHttp902UserCancelled ||
+                 iStatusCode == KHttp921UserAborted )
+                {
+                CLOG(( ECodEng, 3, \
+                    _L("-> CCodEngBase::StartNotifyL notify StartCancelL") ));
+                iObserver->StartCancelL();
+                iNotificationStatus = ECancel;
+                }
+            else
+                {
+                CLOG(( ECodEng, 3, \
+                    _L("-> CCodEngBase::StartNotifyL notify StartLoadL(%d)"), \
+                    iStatusCode ));
+                iObserver->StartLoadL( iStatusCode );
+                iNotificationStatus = ELoad;
+                }
+            }
+        }
+    else
+        {
+        // No install notify attribute, regarded as successful notification.
+        CLOG(( ECodEng, 4, _L("CCodEngBase::StartNotifyL: nothing to do") ));
+        Continue( ENotify );
+        }
+    CLOG(( ECodEng, 2, _L("<- CCodEngBase::StartNotifyL") ));
+    }
+
+// ---------------------------------------------------------
+// CCodEngBase::EndNotifyL
+// ---------------------------------------------------------
+//
+void CCodEngBase::EndNotifyL()
+    {
+    CLOG(( ECodEng, 2, _L("-> CCodEngBase::EndNotifyL iStatus(%d)"), \
+        iStatus.Int() ));
+    __ASSERT_DEBUG( iState == ENotify, CodPanic( ECodInternal ) );
+
+    delete iLoader;
+    iLoader = NULL;
+    delete iConn;
+    iConn = NULL;
+
+    User::LeaveIfError( iStatus.Int() );    // Handle errors in RunError().
+
+    // Do not leave after this point! Notify was successful, we must keep
+    // downloaded content now.
+    
+    if ( iProgress )
+        {
+        TRAP_IGNORE( iProgress->DoneL() );
+        delete iProgress;
+        iProgress = NULL;
+        }
+
+    if( iSaver && iResult == KErrNone )
+        {
+//TODO: check if in case of PD we should release. It is already done.
+        iSaver->ReleaseContent( (*iData)[iData->ActiveDownload()]->iFileName, iHandler );
+
+        if ((!(*iData)[iData->ActiveDownload()]->iFullName) || (!((*iData)[iData->ActiveDownload()]->iFullName->Compare(KNullDesC))))
+            {
+            delete (*iData)[iData->ActiveDownload()]->iFullName;
+            (*iData)[iData->ActiveDownload()]->iFullName = (*iData)[iData->ActiveDownload()]->iFileName.AllocL();
+            }
+        
+        iType = iSaver->DataType();
+        }
+
+    //Done();
+    Continue ( EMediaChange );
+    CLOG(( ECodEng, 2, _L("<- CCodEngBase::EndNotifyL") ));
+    }
+
+// ---------------------------------------------------------
+// CCodEngBase::Done
+// ---------------------------------------------------------
+//
+void CCodEngBase::Done()
+    {
+    CLOG(( ECodEng, 2, _L("-> CCodEngBase::Done iResult(%d)"), iResult ));
+
+    if( iSaver )
+        {
+        iSaver->Cleanup( !(*iData)[iData->ActiveDownload()]->iPausable );
+        }
+
+    delete iSaver;  // Cleans up unless Release()-d.
+    iSaver = NULL;	
+    delete iLoader;
+    iLoader = NULL;
+    delete iConn;
+    iConn = NULL;
+    delete iCodBuf;
+    iCodBuf = NULL;
+    delete iProgress;
+    iProgress = NULL;
+
+    if( iObserver )
+        {
+        CLOG(( ECodEng, 3, \
+            _L("CCodEngBase::Done notify Done code(%d) err(%d)"), \
+            iStatusCode, iResult ));
+        iObserver->Done( iStatusCode, iResult );
+        iNotificationStatus = ENull;
+        }
+
+    // Reinit state.
+    iState = iData->IsValid() ? EReady : EInit;
+    // Notify parent.
+    __ASSERT_DEBUG( iParentStatus, CodPanic( ECodInternal ) );
+    User::RequestComplete( iParentStatus, iResult );
+    iParentStatus = NULL;
+    CLOG(( ECodEng, 2, _L("<- CCodEngBase::Done") ));
+    }
+
+// ---------------------------------------------------------
+// CCodEngBase::DoneDD2
+// ---------------------------------------------------------
+//
+void CCodEngBase::DoneDD2()
+    {
+    CLOG(( ECodEng, 2, _L("-> CCodEngBase::Done iResult(%d)"), iResult ));
+    delete iLoader;
+    iLoader = NULL;
+    delete iConn;
+    iConn = NULL;
+    delete iCodBuf;
+    iCodBuf = NULL;
+    delete iProgress;
+    iProgress = NULL;
+
+    if( iObserver )
+        {
+        CLOG(( ECodEng, 3, \
+            _L("CCodEngBase::Done notify Done code(%d) err(%d)"), \
+            iStatusCode, iResult ));
+        iObserver->Done( iStatusCode, iResult );
+        iNotificationStatus = ENull;
+        }
+
+    // Reinit state.
+    iState = iData->IsValid() ? EReady : EInit;
+    // Notify parent.
+    __ASSERT_DEBUG( iParentStatus, CodPanic( ECodInternal ) );
+    User::RequestComplete( iParentStatus, iResult );
+    iParentStatus = NULL;
+    CLOG(( ECodEng, 2, _L("<- CCodEngBase::Done") ));
+    }
+
+// ---------------------------------------------------------
+// CCodEngBase::Continue
+// ---------------------------------------------------------
+//
+void CCodEngBase::Continue( TState aNextState )
+    {
+    CLOG(( ECodEng, 2, _L("-> CCodEngBase::Continue nextState(%d)"), \
+        aNextState ));
+    __ASSERT_DEBUG( !IsActive(), CodPanic( ECodInternal ) );
+
+    iState = aNextState;
+    TRequestStatus* ownStatus = &iStatus;
+    *ownStatus = KRequestPending;
+    SetActive();
+    User::RequestComplete( ownStatus, KErrNone );
+    CLOG(( ECodEng, 2, _L("<- CCodEngBase::Continue") ));
+    }
+
+// ---------------------------------------------------------
+// CCodEngBase::SelfComplete
+// ---------------------------------------------------------
+//
+void CCodEngBase::SelfComplete( TInt aError )
+    {
+    // This method safely handles the case when a request may be completed
+    // multiple times.
+    // The main use is for content viewing (EContentView state), where
+    // there is no real external request made and the request can complete
+    // the following ways:
+    // - Embedded viewer exits and calls NotifyExit()
+    // - CodEng is Cancelled (e.g. deleted, if Exit is issued inside the
+    //   embedded viewer.
+    CLOG(( ECodEng, 2, _L("CCodEngBase::SelfComplete(%d)"), aError ));
+    if ( iStatus == KRequestPending )
+        {
+        // Request is pending, complete now.
+        CLOG(( ECodEng, 4, _L("  completing now") ));
+        TRequestStatus* ownStatus = &iStatus;
+        User::RequestComplete( ownStatus, aError );
+        }
+    else
+        {
+        // Request already completed.
+        // - If this second completion is error, override status.
+        // - If this second completion is success, don't override - existing
+        //   result may be error and we can't undo that.
+        CLOG(( ECodEng, 4, _L("  already completed") ));
+        if ( aError != KErrNone )
+            {
+            iStatus = aError;
+            }
+        }
+    }
+
+// ---------------------------------------------------------
+// CCodEngBase::CapabilityCheckL
+// ---------------------------------------------------------
+//
+void CCodEngBase::CapabilityCheckL()
+    {
+    CLOG(( ECodEng, 2, _L("-> CCodEngBase::CapabilityCheckL") ));
+    __ASSERT_DEBUG( iData->ActiveDownload(),CodPanic( ECodInternal ));
+    // 1. Data type checking.
+    TInt typeErr( KErrNone );    
+#ifdef __SYNCML_DM_FOTA
+    TBool fota( EFalse );
+#endif /*def __SYNCML_DM_FOTA */
+    for ( TInt i = 0; i < (*iData)[iData->ActiveDownload()]->Types().MdcaCount() && !iContentTypeCheck; i++ )
+        {
+        const TDataType& type( (*iData)[iData->ActiveDownload()]->Types().MdcaPoint( i ) );
+#ifdef __TEST_COD_LOG
+        TPtrC8 mime( type.Des8() );
+#endif /* def __TEST_COD_LOG */
+
+        if (
+            type == TDataType( KOma1XmlRoContentType ) ||
+            type == TDataType( KOma1WbxmlRoContentType )
+           )
+            {
+            // DRM related types which are not proper files (not saved to FS).
+            CLOG(( ECodEng, 4, _L8("  <%S> DRM1 rights OK"), &mime ));
+            iIsDd2 = EFalse;
+            }
+        else if ( type == TDataType( KOma1DrmMessageContentType ) )
+            {
+            // Accept DRM message. The system supports it but
+            // DocHandler does not report this.
+            CLOG(( ECodEng, 4, _L8("  <%S> DRM1 msg OK"), &mime ));
+            iFsUsed = ETrue;
+            }
+#ifdef __DRM_OMA2
+        else if (
+            type == TDataType( KOma2RoContentType ) ||
+            type == TDataType( KOma2ProtectedRoType ) ||
+            type == TDataType( KOma2TriggerContentType )
+           )
+            {
+            // DRM related types which are not proper files (not saved to FS).
+            CLOG(( ECodEng, 4, _L8("  <%S> DRM2 rights OK"), &mime ));
+            iIsDd2 = EFalse;            
+            }
+#endif /*def __DRM_OMA2*/
+#ifdef __SYNCML_DM_FOTA
+        else if ( type == TDataType( KFotaPackageDataType ) )
+            {
+            // Accept FOTA download. Special storage (not saved to FS).
+            CLOG(( ECodEng, 4, _L8("  <%S> FOTA OK"), &mime ));
+            fota = ETrue;
+            }
+#endif /*def __SYNCML_DM_FOTA */
+        else 
+            {
+            CLOG(( ECodEng, 4, _L8("  <%S> DocHandler check"), &mime ));
+            iFsUsed = ETrue;
+            
+            if ( !iResumedDownload )
+                {
+                TRAP( typeErr, iDocHandler->CanOpenL( type ));
+                if (typeErr == KMimeNotSupported)
+                    {
+                    CAknQueryDialog* dialog = CAknQueryDialog::NewL();
+                    dialog->PrepareLC(R_COD_UI_CONFIRM_NOTE);
+                    HBufC* prompt;
+                    prompt = StringLoader::LoadLC(R_QTN_BROWSER_DOWNLOADS_UNSUPPORTED_CONTENT_QUERY);
+                    dialog->SetPromptL(*prompt);  
+                    CleanupStack::PopAndDestroy( prompt );
+                    if(!dialog->RunLD())
+                        {
+                        User::Leave( KHttp902UserCancelled );
+                        }
+                    }
+                }
+            }
+        }
+
+    // 2. Storage space checking. (Depends on data types.)
+   
+    TInt size = (*iData)[iData->ActiveDownload()]->Size() - (*iData)[iData->ActiveDownload()]->DownloadedSize();
+    TInt bytesToWrite = size;
+    if (bytesToWrite < 0)
+        bytesToWrite = 0;
+
+    if ( iFsUsed )
+        {
+        CLOG(( ECodEng, 2, _L("  FS check (%d)"), size ));
+#ifdef RD_MULTIPLE_DRIVE 
+        TInt err( KErrNone );
+        iSpaceAvailOk = EFalse;
+        User::LeaveIfError(
+                DriveInfo::GetDefaultDrive( DriveInfo::EDefaultPhoneMemory, iAvailDriveSpace ) );
+
+        HBufC8* drivesDynList = QueryDynDriveListLC();
+        TPtrC8 drives( *drivesDynList );
+        
+        // drive letters are separated by semicolons
+        for( TInt i = 0; i < drives.Length() && (err || !iSpaceAvailOk); i = i + 2 )
+            {
+            if( (err = iFs.CharToDrive( drives[i], iAvailDriveSpace )) == KErrNone )
+                {
+                // Check if there's enough memory in the phone
+        	    TRAP( err, iSpaceAvailOk = !SysUtil::DiskSpaceBelowCriticalLevelL(
+                                                        &iFs,
+        			                                    bytesToWrite,
+                                                        iAvailDriveSpace ));
+                }
+            else
+                {
+                CLOG(( ECodEng, 4, _L("Bad drive letter [%c]"), drives[i] ));
+                }            
+            }
+        CleanupStack::PopAndDestroy( drivesDynList );
+
+        if( err || !iSpaceAvailOk )
+            {
+            User::Leave( KErrCodInsufficientSpace );
+            }
+#else
+        iPhoneMemoryOk = EFalse;
+        iMmcOk = EFalse;
+        // Check C:
+        iPhoneMemoryOk = !SysUtil::FFSSpaceBelowCriticalLevelL( &iFs, bytesToWrite );
+        CLOG(( ECodEng, 4, _L("  iPhoneMemoryOk(%d)"), iPhoneMemoryOk ));
+        RFeatMgr featMgr;
+        featMgr.OpenL();
+        CleanupClosePushL<RFeatMgr>( featMgr );
+        if ( featMgr.FeatureSupported( KFeatureIdMmc ) )
+            {
+            // If no MMC is inserted, this will leave (and not set iMmcOk).
+            TRAP_IGNORE( iMmcOk = !SysUtil::MMCSpaceBelowCriticalLevelL
+                ( &iFs, bytesToWrite ); )
+            }
+        CleanupStack::PopAndDestroy();  // featMgr
+        CLOG(( ECodEng, 4, _L("  iMmcOk(%d)"), iMmcOk ));
+        if( !(iPhoneMemoryOk || iMmcOk) )
+            {
+            User::Leave( KErrCodInsufficientSpace );
+            }
+#endif
+        }
+
+#ifdef __SYNCML_DM_FOTA
+    if ( fota )
+        {
+        // Transient FOTA session is used to check store space -> waste.
+        // Pre-allocate FOTA saver to avoid this (??) makes the saver's
+        // lifespan hard to follow, error-prone. TODO (??)
+        CLOG(( ECodEng, 2, _L("  FOTA check (%d)"), size ));
+        RFotaEngineSession fotaEng;
+        CleanupClosePushL<RFotaEngineSession>( fotaEng );
+        fotaEng.OpenL();
+        if ( !fotaEng.IsPackageStoreSizeAvailable( size ) )
+            {
+            User::Leave( KErrCodInsufficientSpace );
+            }
+        CleanupStack::PopAndDestroy( &fotaEng );
+        }
+#endif /*def __SYNCML_DM_FOTA */
+
+	//When reached here, it is assured that capability check is done successfully
+	//for the active download.
+	//Content type check is done for this track
+	iContentTypeCheck = ETrue;
+	
+    CLOG(( ECodEng, 2, _L("<- CCodEngBase::CapabilityCheckL") ));
+    }
+
+// ---------------------------------------------------------
+// CCodEngBase::CreateSaverL
+// ---------------------------------------------------------
+//
+CCodSaver* CCodEngBase::CreateSaverL( const TDesC8& aType )
+    {
+    CLOG(( ECodEng, 2, _L8("-> CCodEngBase::CreateSaverL <%S>"), &aType ));
+//TODO:    __ASSERT_DEBUG( !iSaver, CodPanic( ECodInternal ) );
+    // TODO check attribute match (early reject mismatched or unsupported types)!
+
+    if( aType == KNullDesC8 )
+    	{
+    	return NULL;
+    	}
+    
+// DD1 and DD2 cases
+    if (( aType.Find( KOma2TriggerContentType ) != KErrNotFound) || ( aType.Find( KDd2DataType ) != KErrNotFound )|| ( aType.Find( KOma1WbxmlRoContentType ) != KErrNotFound ))
+        {
+        iSaver = CRoapSaver::NewL( aType, iRoapData, iProgress, KRoapProgressMax, (*iData)[iData->ActiveDownload()]->iTempPath, (*iData)[iData->ActiveDownload()]->iRootPath, KNullDesC());
+        iSaver->SetObserver( iObserver );
+        iSaver->SetParams( iParams );
+        iSaver->SetMaxSize( iData->Size() );
+        iSaver->OpenStoreL();   // TODO unneeded method, put to construction.
+        }
+#ifdef __SYNCML_DM_FOTA
+    else if ( aType.Find( KFotaPackageDataType ) != KErrNotFound  )
+        {
+        TInt pkgId( KCodDefaultFotaPkgId );
+        if ( iParams )
+            {
+            CodUtil::GetIntParam( pkgId, EGenericParamFotaPkgId, *iParams );
+            }
+        iSaver = CFotaSaver::NewL( aType, pkgId );
+        iSaver->SetObserver( iObserver );
+        iSaver->SetParams( iParams );
+        iSaver->SetMaxSize( iData->Size() );
+        iSaver->OpenStoreL();   // TODO unneeded method, put to construction.
+        }
+#endif /*def __SYNCML_DM_FOTA */
+    else
+        {
+        // TODO the assert below crashes without early reject!
+        //__ASSERT_DEBUG( iFsUsed, CodPanic( ECodInternal ) );
+
+        TBool contentTypeMisMatch ( ETrue );
+        for ( TInt i = 0; i < (*iData)[iData->ActiveDownload()]->Types().MdcaCount(); i++ )
+            {
+            const TDataType& type( (*iData)[iData->ActiveDownload()]->Types().MdcaPoint( i ) );
+            if( ( aType.Find (type.Des8()) != KErrNotFound ) || 
+                            ( (type.Des8().Find(KOma1DrmMessageContentType)!= KErrNotFound) && (aType.Find(KOma1DcfContentType)!= KErrNotFound )  ))             
+                {
+                contentTypeMisMatch = EFalse;
+                break;
+                }                
+            }
+        if(contentTypeMisMatch)
+            {
+            User::Leave(KErrCodAttributeMismatch);
+            }
+        
+        // Do this only if Unique filename check has never been performed earlier for this file.
+        if (( !(*iData)[iData->ActiveDownload()]->IsUniqueFilenameSet() ))
+            {
+            // Append an index to filename in case file with same name already exists
+            SetUniqueFileNameL();
+            (*iData)[iData->ActiveDownload()]->UniqueFilenameSet( ETrue );
+            
+            CArrayPtrFlat<CHeaderField>* headers = NULL;
+            if (iLoader)
+            	headers = iLoader->ResponseHeaders();
+            
+            // Store in Sub-Info File
+            StoreSubInfoFileL( headers, iData->ActiveDownload() );
+            // Name changed. Inform server.
+            iObserver->MediaObjectNameChanged();
+            }
+        
+        if (iIsDd2)
+		    {
+            iSaver = CFileSaver::NewL( ((*iData)[iData->ActiveDownload()]->Types().MdcaPoint( 0)), iFs, *iDocHandler, (*iData)[iData->ActiveDownload()]->iTempPath, (*iData)[iData->ActiveDownload()]->iRootPath, (*iData)[iData->ActiveDownload()]->iFullName->Des());
+		    }
+        else
+		    {
+            iSaver = CFileSaver::NewL( aType, iFs, *iDocHandler, (*iData)[iData->ActiveDownload()]->iTempPath, (*iData)[iData->ActiveDownload()]->iRootPath, (*iData)[iData->ActiveDownload()]->iFullName->Des());
+		    }
+        iSaver->SetObserver( iObserver );
+        iSaver->SetParams( iParams );
+        iSaver->SetMaxSize( iData->Size() );
+        iSaver->OpenStoreL();   // TODO unneeded method, put to construction.
+		iSaver->ReleaseFileName( (*iData)[iData->ActiveDownload()]->iFileName);
+		//send message that PDL is available. The DlMgrUiLib will have a "Play" option available
+        /*
+        OMA 2:
+        If the Media Object of the Product containing the Media Object has a license element, 
+        the Download Agent MUST NOT make the Media Object(s) available for rendering before 
+        the License has been successfully installed..
+        Only the order tag equals to any allows to install the License element first.
+        */
+          if ((iIsDd2 && iObserver && iData && (*iData)[iData->ActiveDownload()]->ProgressiveDownload() && !iIsLicense) || 
+             (iIsDd2 && iObserver && iData && (*iData)[iData->ActiveDownload()]->ProgressiveDownload() &&  iIsLicense && !iData->IsPostOrder()))
+		  {
+          iSaver->ReleaseFileName( (*iData)[iData->ActiveDownload()]->iFileName);
+          iObserver->PdPlayAvailable();
+		  }
+        }
+
+    CLOG(( ECodEng, 2, _L("<- CCodEngBase::CreateSaverL") ));
+    return iSaver;
+    }
+
+// ---------------------------------------------------------
+// CCodEngBase::SetPathsL
+// ---------------------------------------------------------
+//
+void CCodEngBase::SetPathsL()
+    {
+    CLOG(( ECodEng, 2, _L("-> CCodEngBase::SetPathsL") ));
+#ifdef RD_MULTIPLE_DRIVE 
+    __ASSERT_DEBUG( iSpaceAvailOk, CodPanic( ECodInternal ) );
+#else
+    __ASSERT_DEBUG( iPhoneMemoryOk || iMmcOk, CodPanic( ECodInternal ) );
+    __ASSERT_DEBUG( iFsUsed, CodPanic( ECodInternal ) );
+#endif
+    (*iData)[iData->ActiveDownload()]->iTempPath = KNullDesC;
+    (*iData)[iData->ActiveDownload()]->iRootPath = KNullDesC;
+#ifdef RD_MULTIPLE_DRIVE 
+    if ( iSpaceAvailOk )
+        {
+        User::LeaveIfError( PathInfo::GetRootPath( (*iData)[iData->ActiveDownload()]->iRootPath, iAvailDriveSpace ) );
+        }
+#else    
+    if ( iPhoneMemoryOk && iMmcOk && iObserver ) 
+        {
+        iObserver->GetRootPathL( (*iData)[iData->ActiveDownload()]->iRootPath );
+        if(!(*iData)[iData->ActiveDownload()]->iRootPath.Compare(_L("C:\\")))
+            {
+                (*iData)[iData->ActiveDownload()]->iRootPath = PathInfo::PhoneMemoryRootPath();
+                
+            }
+        }
+    else if ( iPhoneMemoryOk )
+        {
+        (*iData)[iData->ActiveDownload()]->iRootPath = PathInfo::PhoneMemoryRootPath();
+        }
+    else
+        {
+        __ASSERT_DEBUG( iMmcOk, CodPanic( ECodInternal ) );
+        (*iData)[iData->ActiveDownload()]->iRootPath = PathInfo::MemoryCardRootPath();
+        }
+#endif
+
+ 	TParsePtrC rootPath( (*iData)[iData->ActiveDownload()]->iRootPath );
+ 	TBuf<KMaxPath> tempBuf;
+ 	// Set temp path to the same drive.
+    tempBuf.Format( KDownloadFolderFormat, 
+                    &KCodDefaultTempDir, 
+                    iAppUId,
+                    &KTempFilesCodDirName );      
+
+    (*iData)[iData->ActiveDownload()]->iTempPath.Append(rootPath.Drive());
+    (*iData)[iData->ActiveDownload()]->iTempPath.Append(tempBuf);
+
+    TDriveInfo info;
+    TDriveUnit unit( rootPath.Drive() );
+    User::LeaveIfError( iFs.Drive( info, unit ) );
+    // Create the temp directory earlier in case it's not created yet
+    iFs.MkDirAll( (*iData)[iData->ActiveDownload()]->iTempPath ); 
+    if ( info.iDriveAtt & KDriveAttRemovable )
+        {
+        iRemovableMedia = ETrue;
+        }
+        
+    CLOG(( ECodEng, 2, _L("<- CCodEngBase::SetPathsL root<%S> temp<%S>"), \
+        &(*iData)[iData->ActiveDownload()]->iRootPath, &(*iData)[iData->ActiveDownload()]->iTempPath ));
+    }
+
+// ---------------------------------------------------------
+// CCodEngBase::ResetPaths
+// ---------------------------------------------------------
+//
+void CCodEngBase::ResetPaths()
+    {
+    iFsUsed = EFalse;
+#ifdef RD_MULTIPLE_DRIVE 
+    iSpaceAvailOk = EFalse;
+    DriveInfo::GetDefaultDrive( DriveInfo::EDefaultPhoneMemory, iAvailDriveSpace );
+#else
+    iPhoneMemoryOk = EFalse;
+    iMmcOk = EFalse;
+#endif
+    //(*iData)[iData->ActiveDownload()]->iTempPath = KNullDesC;
+    //(*iData)[iData->ActiveDownload()]->iRootPath = KNullDesC;
+    iRemovableMedia = EFalse;
+    }
+
+#ifdef RD_MULTIPLE_DRIVE
+//------------------------------------------------------------------------
+//CCodEngBase::QueryDynDriveListLC
+//------------------------------------------------------------------------
+HBufC8* CCodEngBase::QueryDynDriveListLC()
+    {
+    TDriveList driveList;
+    TInt driveCount( 0 );
+    TChar driveLetter;
+    TBuf8<KMaxDriveListStrLen> driveLettersDyn;
+
+    // Checking validity of drives in Cenrep List
+    // drive letters are separated by semicolons
+    // Destination is FFS in default
+    TInt drive;
+    User::LeaveIfError(
+        DriveInfo::GetDefaultDrive( DriveInfo::EDefaultPhoneMemory, drive ) );
+
+    for( TInt i = 0; i < iDriveLettersCenRep.Length(); i = i + 2 )
+        {
+        if( iFs.CharToDrive( iDriveLettersCenRep[i], drive ) == KErrNone )
+            {
+            TUint status;
+            if ( DriveInfo::GetDriveStatus( iFs, drive, status ) == KErrNone )
+                {
+                if ( ( status & ( DriveInfo::EDriveUserVisible | DriveInfo::EDrivePresent ) ) )
+                    {
+                    CLOG(( ECodEng, 0, _L("-> CCodEngBase::QueryDynDriveListLC Drive is present and visible")));
+                    }
+                }
+            }
+        }
+
+    // get the list of drives available in real time
+    if ( DriveInfo::GetUserVisibleDrives( iFs, driveList, driveCount ) == KErrNone )
+        {
+        if ( iDriveLettersCenRep.Length() > 0 )
+            {
+                driveLettersDyn.Append( iDriveLettersCenRep );
+                if ( driveLettersDyn[driveLettersDyn.Length() - 1] != ';' )
+                    {
+                    driveLettersDyn.Append( KDefaultDriveListSep );
+                    }
+            }
+        TInt count( driveList.Length() );
+        for ( TInt i( 0 ); i < count; ++i )
+            {
+            if ( driveList[ i ] )
+                {
+                User::LeaveIfError( iFs.DriveToChar( i, driveLetter) );
+                TInt drivePos = driveLettersDyn.LocateF( driveLetter );
+                if ( drivePos == KErrNotFound )
+                    {
+                    driveLettersDyn.Append( driveLetter ); 
+                    driveLettersDyn.Append( KDefaultDriveListSep ); 
+                    }
+                }
+            }
+        CLOG(( ECodEng, 2, _L("<- CCodEngBase::QueryDynDriveListLC Pref. drive list dynamic: [%S]"), \
+                &driveLettersDyn));
+        }
+
+    HBufC8* driveLetters = HBufC8::NewLC( KMaxDriveListStrLen );
+    driveLetters->Des().Copy( driveLettersDyn );
+    return driveLetters;
+    }
+
+//------------------------------------------------------------------------
+//CCodEngBase::QueryDriveList
+//------------------------------------------------------------------------
+void CCodEngBase::QueryDriveListL()
+    {
+    CRepository* repository = CRepository::NewLC( KCRUidBrowser );
+    
+    if( repository->Get(KBrowserDrivePrefListForDownloadedContent, iDriveLettersCenRep) != KErrNone )
+        {
+        CLOG(( ECodEng, 0, _L("-> CCodEngBase::QueryDriveListL Drive list not found")));
+        iDriveLettersCenRep.Copy( KDefaultDriveList );
+        }
+    CLOG(( ECodEng, 2, _L("<- CCodEngBase::QueryDriveListL Pref. drive list: [%S]"), \
+        &iDriveLettersCenRep));    
+    
+    CleanupStack::PopAndDestroy( repository );
+    }
+
+#endif
+
+//------------------------------------------------------------------------
+//CCodEngBase::DownloadID
+//------------------------------------------------------------------------
+TUint32 CCodEngBase::DownloadID()
+	{
+	return iDownloadId;
+	}
+
+//------------------------------------------------------------------------
+//CCodEngBase::SetPausable
+//------------------------------------------------------------------------
+
+void CCodEngBase::SetPausable(TBool aPausable)
+    {
+    (*iData)[iData->ActiveDownload()]->iPausable = aPausable;
+    if( iData->Count() > 1 && aPausable )
+    	{
+    	iObserver->UpdatePausable(aPausable);	
+    	}
+    else if(iData->Count()  ==  1)
+        {
+        iObserver->UpdatePausable(aPausable);
+        }	    	
+    }
+
+//------------------------------------------------------------------------
+//CCodEngBase::SetResumePDAvailable
+//------------------------------------------------------------------------
+
+void CCodEngBase::SetResumePDAvailable()
+	{
+	if(iData && iData->ActiveDownload() 
+		     && iData->Count() 
+			 && (*iData)[iData->ActiveDownload()]->ProgressiveDownload())
+		{
+		iObserver->DownloadResumedPdAvailable();	
+		}
+	}
+        
+//------------------------------------------------------------------------
+//CCodEngBase::StoreFilePathsL
+//------------------------------------------------------------------------
+void CCodEngBase::StoreFilePathsL(TPtr8& aBuf)
+	{
+    HBufC* buf1 = (*iData)[iData->ActiveDownload()]->iTempPath.AllocLC();
+	AppendBufL(aBuf,buf1);
+	
+	HBufC* buf2 = (*iData)[iData->ActiveDownload()]->iRootPath.AllocLC();
+	AppendBufL(aBuf,buf2);
+	
+	CleanupStack::PopAndDestroy(2,buf1);
+	AppendBufL(aBuf,(*iData)[iData->ActiveDownload()]->iFullName);
+		
+	}
+
+//------------------------------------------------------------------------
+//CCodEngBase::LoadFilePathsL
+//------------------------------------------------------------------------
+void CCodEngBase::LoadFilePathsL(RFile& aInFile)
+	{
+	HBufC* buf1 = NULL;
+	HBufC* buf2 = NULL;	
+	ReadHBufCL(aInFile,buf1);
+	(*iData)[iData->ActiveDownload()]->iTempPath = *buf1;
+	
+	ReadHBufCL(aInFile,buf2);
+	
+	(*iData)[iData->ActiveDownload()]->iRootPath = *buf2;
+	
+	ReadHBufCL(aInFile,(*iData)[iData->ActiveDownload()]->iFullName);
+	delete buf1;
+	delete buf2;
+	}
+
+//------------------------------------------------------------------------
+//CCodEngBase::Start()
+//------------------------------------------------------------------------
+// 
+EXPORT_C void CCodEngBase::Start( const CAiwGenericParamList* aParams, TRequestStatus* aStatus ) 
+	{
+	iParentStatus = aStatus;
+	*iParentStatus = KRequestPending;
+	iParams = aParams;
+    // Get params from GenericParams.
+    if ( iParams )
+        {
+        CodUtil::GetUint32Param( iPreferredIap, EGenericParamAccessPoint, *iParams );
+        }
+    
+	Continue( EStartConnect );
+	}
+	
+//------------------------------------------------------------------------
+//CCodEngBase::ChangeMediaObjectL()
+//------------------------------------------------------------------------
+// 
+void CCodEngBase::ChangeMediaObjectL()
+	{
+	__ASSERT_DEBUG( iState == EMediaChange, CodPanic( ECodInternal ) );
+	
+	TInt mediaObjectCount = iData->Count();	
+    if( mediaObjectCount && iData->ActiveDownload() )
+    	{
+    	(*iData)[iData->ActiveDownload()]->iStatusCode = iStatusCode;
+    	(*iData)[iData->ActiveDownload()]->iResult = iResult;
+     	iObserver->Done( iStatusCode, iResult );
+    
+		if( iStatusCode == KHttp900Success )
+	    	{
+	    	(*iData)[iData->ActiveDownload()]->iState = ESucceeded;
+        	StoreSubInfoFileL(NULL, iData->ActiveDownload() );
+	    	}
+
+    	UpdateTrackInfoL();
+    
+	    if( iData->ActiveDownload() != mediaObjectCount &&( (*iData)[iData->ActiveDownload()]->iResult != KErrCancel 
+	                                                    &&  (*iData)[iData->ActiveDownload()]->iResult != KErrAbort
+	                                                    &&  (*iData)[iData->ActiveDownload()]->iResult != KErrCodWapConnectionDropped
+	                                                    &&  (*iData)[iData->ActiveDownload()]->iResult != KErrCodHttpDownloadPaused
+	                                                    &&  (*iData)[iData->ActiveDownload()]->iResult != KErrCodInvalidDescriptor))
+    		{
+      		if( iSaver )
+          		{
+          		iSaver->Cleanup( !(*iData)[iData->ActiveDownload()]->iPausable );
+          		}	    		
+			delete iSaver;  // Cleans up unless Release()-d.
+		    iSaver = NULL;	
+		    delete iLoader;
+		    iLoader = NULL;
+		    delete iConn;
+		    iConn = NULL;
+		    delete iCodBuf;
+		    iCodBuf = NULL;
+
+    		TInt count = iData->ActiveDownload();
+		  	do
+		      {
+		      count++;
+		      }
+    			while( count <= iData->Count() && !( (*iData)[count]->State() == EQueued 
+	            		|| (*iData)[count]->State() == EInProgress )
+	            		);
+	    
+		    if( count <= iData->Count())
+		        {
+		    	iData->SetActiveDownload(count);
+				Continue( EStartConnect );	    		
+				return;
+		        }
+   			}
+      	}     
+    Continue ( EStartProductNotify );     
+	}
+
+//------------------------------------------------------------------------
+//CCodEngBase::Pausable
+//------------------------------------------------------------------------
+EXPORT_C TBool CCodEngBase::Pausable()
+    {
+    return (*iData)[iData->ActiveDownload()]->iPausable;	
+    }
+
+// ---------------------------------------------------------
+// CCodEngBase::StoreMainInfoFileL()
+// ---------------------------------------------------------  
+//       
+void CCodEngBase::StoreMainInfoFileL()	
+    {
+    if ( iCodDlInfoPath == KNullDesC )
+        {
+        return;
+        }
+    TInt bufSz = KDownloadInfoIncrSize;
+    HBufC8* newInfo = HBufC8::NewLC( bufSz );
+    TPtr8 newInfoPtr = newInfo->Des();
+    
+    // Append the DD attributes 
+	iData->AppendStorageInfoL(newInfoPtr);
+
+    RFile outFile;
+    CleanupClosePushL<RFile>( outFile );
+    
+    User::LeaveIfError( outFile.Replace( iFs, 
+                                         iCodDlInfoPath, 
+                                         EFileShareExclusive | 
+                                         EFileStream | 
+                                         EFileWrite ) );
+
+    outFile.Write( newInfoPtr );
+    User::LeaveIfError( outFile.Flush() );
+    
+    CleanupStack::PopAndDestroy(2);
+
+    }
+
+// ---------------------------------------------------------
+// CCodEngBase::StoreSubInfoFileL()
+// ---------------------------------------------------------        
+// 
+void CCodEngBase::StoreSubInfoFileL( const CArrayPtrFlat<CHeaderField>* aHeaders, TInt aMediaIndex )	
+    {
+    if ( iCodDlInfoPath == KNullDesC )
+        {
+        return;
+        }
+    RFile outFile;
+    CleanupClosePushL<RFile>( outFile );
+
+
+    TInt bufSz = KDownloadInfoIncrSize;
+    HBufC8* newInfo = HBufC8::NewLC( bufSz );
+    TPtr8 newInfoPtr = newInfo->Des();
+    
+    TFileName infoPath;
+    infoPath.Format( _L("%S_%d"), &iCodDlInfoPath, aMediaIndex );
+
+    newInfoPtr.Zero();
+    
+    // Load the DD attributes and other required information to the buffer
+	(*iData)[aMediaIndex]->StoreMediaInfoL( newInfoPtr, aHeaders );
+
+    User::LeaveIfError( outFile.Replace( iFs, 
+                                         infoPath, 
+                                         EFileShareExclusive | 
+                                         EFileStream | 
+                                         EFileWrite ) );
+
+    outFile.Write( newInfoPtr );
+    User::LeaveIfError( outFile.Flush() );
+
+    CleanupStack::PopAndDestroy(2);
+    }
+
+// ---------------------------------------------------------
+// CCodEngBase::StoreInfoFilesL()
+// ---------------------------------------------------------        
+// 
+void CCodEngBase::StoreInfoFilesL()	
+    {
+    StoreMainInfoFileL();
+    
+    for(TInt i = 1; i <= iData->Count(); ++i)
+        {
+        StoreSubInfoFileL( NULL, i );
+        }
+    }
+// ---------------------------------------------------------
+// CCodEngBase::LoadMainInfoFileL()
+// ---------------------------------------------------------        
+// 
+void CCodEngBase::LoadMainInfoFileL()	
+    {
+    	
+    RFile inFile;
+    CleanupClosePushL<RFile>( inFile );
+    TInt err = inFile.Open(iFs, 
+                           CodDlInfoFile(), 
+                           EFileShareReadersOnly | 
+                           EFileRead ) ;	
+
+    // Possible erros KErrNotFound , KErrPathNotFound , KErrBadName
+	if( err  )
+		{
+		CleanupStack::PopAndDestroy();
+		return;
+		}
+		
+	iData->LoadStorageInfoL( inFile );
+	CleanupStack::PopAndDestroy(); // inFile
+
+    }
+
+// ---------------------------------------------------------
+// CCodEngBase::LoadSubInfoFileL()
+// ---------------------------------------------------------            
+// 
+void CCodEngBase::LoadSubInfoFileL( TInt aMediaIndex, CArrayPtrFlat<CHeaderField>* aHeaders )	
+    {
+   	
+    RFile inFile;
+    CleanupClosePushL<RFile>( inFile );
+
+    TFileName infoPath;
+    infoPath.Format( _L("%S_%d"), &iCodDlInfoPath, aMediaIndex );
+
+    
+    TInt err = inFile.Open(iFs, 
+                           infoPath, 
+                           EFileShareReadersOnly | 
+                           EFileRead ) ;	
+
+    // Possible erros KErrNotFound , KErrPathNotFound , KErrBadName
+	if( err  )
+		{
+		CleanupStack::PopAndDestroy();
+		return;
+		}
+		
+	(*iData)[aMediaIndex]->LoadMediaInfoL( inFile, iFs, aHeaders );
+	CleanupStack::PopAndDestroy(); // inFile
+    }
+
+// ---------------------------------------------------------
+// CCodEngBase::LoadInfoFilesL()
+// ---------------------------------------------------------        
+// 
+void CCodEngBase::LoadInfoFilesL()	
+    {
+    LoadMainInfoFileL();
+    
+    TBool activeDownloadSet = EFalse;
+    
+    for(TInt i = 1; i <= iData->Count(); ++i)
+        {
+        LoadSubInfoFileL( i, NULL );
+        if( ((*iData)[i]->State() == EInProgress  || (*iData)[i]->State() == EQueued ) && !activeDownloadSet )
+            {
+            iData->SetActiveDownload ( i );
+            activeDownloadSet = ETrue;
+            }            
+        }
+    if( iData->ActiveDownload() == 0 )
+        {
+        iData->SetActiveDownload(iData->Count());
+        }
+    }    
+    
+// ---------------------------------------------------------
+// CCodEngBase::StartProductNotifyL
+// ---------------------------------------------------------
+//    
+void CCodEngBase::StartProductNotifyL()
+    {
+    
+    CLOG(( ECodEng, 2, _L("-> CCodEngBase::StartProductNotifyL iStatus(%d)"), \
+        iStatus.Int() ));
+    __ASSERT_DEBUG( iState == EStartProductNotify, CodPanic( ECodInternal ) );    
+    if ( iData->InstallNotify().Length() )
+        {
+        CLOG(( ECodEng, 4, _L("CCodEngBase::StartProductNotifyL: init request") ));
+        if ( !iProgress )
+            {
+            // Setup notify-only progress.
+            iProgress = new (ELeave) TCodProgress( iObserver );
+            iProgress->Setup( 0, KCodNotifyTraffic );    
+            }
+        iProgress->StartPhaseL( TCodProgress::ENotify );
+        TBool notifyObserver = EFalse;
+        // When notifying after fetch, we already have a loader (and the
+        // observer has already been notified about load).
+        // When notifying without fetch, we don't have a loader yet (and the
+        // observer has not been notified about load yet).
+        if ( !iConn )
+            {
+            iConn = CConnection::NewL();
+            }
+        // For notify, attach only (do no create new connection).
+        iConn->AttachL( iPreferredIap );
+        if( !iLoader )
+            {
+            iLoader = CHttpLoader::NewL( *iConn, NULL, iProgress ,this );
+            notifyObserver = ETrue;
+            }
+        TInt statusCode;
+        
+        if(!iData->Count())
+            {
+            statusCode = KHttp906InvalidDescriptor; 
+            }
+        else
+            {
+            statusCode = KHttp981DownloadCompletion; 
+            }
+            
+        for( TInt i = 1;i <= iData->Count(); ++i )
+            {
+            if( (*iData)[i]->iStatusCode != KHttp900Success )
+                {
+                statusCode = KHttp970MixedStatus;
+                break;
+                }
+            }
+        HBufC8* url = CodUtil::AbsoluteUrlLC
+            ( iData->SourceUri(), iData->InstallNotify() );
+        iLoader->NotifyL( *url, StatusText( statusCode ), &iStatus );
+        CleanupStack::PopAndDestroy( url );
+        iState = EProductNotify;
+        SetActive();
+        if ( iObserver && notifyObserver )
+            {
+            if ( iStatusCode == KHttp902UserCancelled ||
+                 iStatusCode == KHttp921UserAborted )
+                {
+                CLOG(( ECodEng, 3, \
+                    _L("-> CCodEngBase::StartNotifyL notify StartCancelL") ));
+                iObserver->StartCancelL();
+                iNotificationStatus = ECancel;
+                }
+            else
+                {
+                CLOG(( ECodEng, 3, \
+                    _L("-> CCodEngBase::StartNotifyL notify StartLoadL(%d)"), \
+                    iStatusCode ));
+                iObserver->StartLoadL( iStatusCode );
+                iNotificationStatus = ELoad;
+                }
+            }
+        }
+    else
+        {
+        // No install notify attribute, regarded as successful notification.
+        CLOG(( ECodEng, 4, _L("CCodEngBase::StartNotifyL: nothing to do") ));
+        Continue( EProductNotify );
+        }
+    CLOG(( ECodEng, 2, _L("<- CCodEngBase::StartNotifyL") ));    
+    }
+    
+// ---------------------------------------------------------
+// CCodEngBase::EndProductNotifyL
+// ---------------------------------------------------------    
+void CCodEngBase::EndProductNotifyL()
+    {
+        CLOG(( ECodEng, 2, _L("-> CCodEngBase::EndNotifyL iStatus(%d)"), \
+        iStatus.Int() ));
+    __ASSERT_DEBUG( iState == EProductNotify, CodPanic( ECodInternal ) );
+
+    delete iLoader;
+    iLoader = NULL;
+    delete iConn;
+    iConn = NULL;
+
+    User::LeaveIfError( iStatus.Int() );    // Handle errors in RunError().
+
+    // Do not leave after this point! Notify was successful, we must keep
+    // downloaded content now.
+    
+    if ( iProgress )
+        {
+        TRAP_IGNORE( iProgress->DoneL() );
+        delete iProgress;
+        iProgress = NULL;
+        }
+    /*
+    if( iSaver && (*iData)[iData->ActiveDownload()]->iResult == KErrNone )
+        {
+//TODO: check if in case of PD we should release. It is already done.
+        iSaver->ReleaseContent( (*iData)[iData->ActiveDownload()]->iFileName, iHandler );
+        iType = iSaver->DataType();
+        }
+    */
+    Done();
+    }
+
+//------------------------------------------------------------------------
+//CCodEngBase::UpdatedDownloadDataL
+//------------------------------------------------------------------------
+EXPORT_C HBufC8* CCodEngBase::UpdatedDownloadDataL()
+    {
+    if (!iData)
+        return NULL;
+    
+    CDownloadDataClient* dlData = CDownloadDataClient::NewLC();
+    ConvertCodDataToDownloadDataL( dlData );
+    HBufC8* des8 = dlData->MarshalDataL();
+    CleanupStack::PopAndDestroy(dlData);
+    
+    return des8;
+    }
+// ---------------------------------------------------------
+// CCodEngBase::UpdateDownloadedSize
+// ---------------------------------------------------------       
+void CCodEngBase::UpdateDownloadedSize( TInt aSize )
+    {
+    (*iData)[iData->ActiveDownload()]->SetDownloadedSize( (*iData)[iData->ActiveDownload()]->DownloadedSize() + aSize );    
+    }
+// ---------------------------------------------------------
+// CCodEngBase::ActiveDownload
+// ---------------------------------------------------------          
+EXPORT_C TInt CCodEngBase::ActiveDownload()
+    {
+    return iData->ActiveDownload();
+    }
+
+//------------------------------------------------------------------------
+//CCodEngBase::UpdatedTrackDataL
+//------------------------------------------------------------------------
+EXPORT_C HBufC8* CCodEngBase::UpdatedTrackDataL(TInt& aValue)
+    {
+    if (!iData)
+        return NULL;
+    
+    aValue = iData->ActiveDownload();
+    
+    CMediaDataClient* mediaData = CMediaDataClient::NewL();
+	CleanupStack::PushL(mediaData);
+	ConvertMOToMediaDataL(mediaData, aValue);
+    HBufC8* des8 = mediaData->MarshalDataL();
+    CleanupStack::PopAndDestroy(); //mediaData
+
+    return des8;
+    }
+//------------------------------------------------------------------------
+//CCodEngBase::ConvertCODDataToDownloadDataL
+//------------------------------------------------------------------------    
+void CCodEngBase::ConvertCodDataToDownloadDataL( CDownloadDataClient*& aDlData )
+    {
+    if (aDlData)
+        {
+        aDlData->SetNameL( iData->Name() );
+        aDlData->SetSize( iData->Size() );
+        aDlData->SetIconL( iData->Icon() );
+        aDlData->SetUpdatedDDURI( iData->UpdatedDDUriL() );
+        
+        for (TInt mObj = 1; mObj <= iData->Count(); ++mObj)
+            {
+            CMediaDataClient* mediaData = CMediaDataClient::NewL();
+            CleanupStack::PushL(mediaData);
+            
+            ConvertMOToMediaDataL(mediaData, mObj);
+            aDlData->AppendMediaData(mediaData);
+            
+            CleanupStack::Pop(); //mediaData
+            }
+        }
+    }
+
+//------------------------------------------------------------------------
+//CCodEngBase::ConvertMOToMediaDataL
+//------------------------------------------------------------------------    
+void CCodEngBase::ConvertMOToMediaDataL( CMediaDataClient*& aMOData, TInt aMOIndex )
+    {
+    CMediaObjectData* objMedia = (*iData)[aMOIndex];
+    
+    aMOData->SetNameL( objMedia->Name() );
+    aMOData->SetUrlL( objMedia->Url() );
+    aMOData->SetSize( objMedia->Size() );
+    aMOData->SetIconL( objMedia->Icon() );
+    aMOData->SetSourceUriL( objMedia->SourceUri() );
+    aMOData->SetProgressiveDownload( objMedia->ProgressiveDownload() );
+    aMOData->SetState( objMedia->State() );
+    aMOData->SetResult( objMedia->iResult );
+    aMOData->SetDownloadedSize( objMedia->DownloadedSize() );
+    aMOData->SetPausable( objMedia->Pausable() );
+    if(objMedia->iFullName)
+    	{
+    	aMOData->SetDestFilenameL( objMedia->FullName() );
+    	aMOData->SetTempFilenameL( objMedia->FullName() );
+    	}  
+    
+    for (TInt type = 0; type < objMedia->TypesCount(); ++type)
+        aMOData->AddTypeL( objMedia->Types().MdcaPoint(type) );
+    }
+
+//------------------------------------------------------------------------
+//CCodEngBase::UpdateMediaInfoL
+//------------------------------------------------------------------------    
+void CCodEngBase::UpdateMediaInfoL()
+    {
+    if (iObserver)
+        {
+        iObserver->UpdateMediaInfoL();
+        }
+    }
+// ---------------------------------------------------------
+// CCodEngBase::GetProductStatusCode
+// ---------------------------------------------------------       
+EXPORT_C TCodDownloadProgress::TState CCodEngBase::GetProductStatusCode() const
+    {
+    TCodDownloadProgress::TState statusCode = TCodDownloadProgress::EFailedPermanent;        
+    TInt allSucceeded = 0;
+    TInt currentActiveDownload = iData->ActiveDownload();
+    
+    for( TInt i = 1 ; i <= iData->Count() ; ++i )
+        {
+        TInt mediaObjectStatusCode = (*iData)[i]->iStatusCode;
+        
+        // If the current track failed for some reason, set this as the
+        // active download. Do this only for the first failed track.
+        if ((mediaObjectStatusCode != KHttp900Success) &&
+            (mediaObjectStatusCode != KHttp956LicenseSuccess))
+            {
+            if( currentActiveDownload > i )
+                {
+                //This is done so that next time when resume happens
+                //it happens from first failed download
+                iData->SetActiveDownload ( i );
+                currentActiveDownload = i;
+                
+                //Inform server about the Active download
+                iObserver->SetActiveDownload();
+                iObserver->MediaObjectNameChanged();
+                }
+            }
+
+        // Check for error and status code
+        switch( mediaObjectStatusCode )
+            {
+            case KHttp900Success:
+            case KHttp956LicenseSuccess:
+                {
+                allSucceeded++;
+                statusCode = TCodDownloadProgress::ESucceeded;
+                break;
+                }
+
+            case KHttp901InsufficientMemory:
+                {
+                statusCode = TCodDownloadProgress::EFailedTemporary;
+                break;
+                }
+            case KHttp902UserCancelled:
+            case KHttp921UserAborted:
+            case KHttp957LicenseFailed:
+                {
+                break;
+                }
+            
+            case KHttp905AttributeMismatch:
+            case KHttp906InvalidDescriptor:
+            case KHttp907InvalidType:
+            case KHttp922DeviceAborted:
+            case KHttp923NonAcceptableContent:
+            case KHttp924LoaderError:
+            case KHttp951InvalidDdVersion:
+            case KHttp952DeviceAborted:
+            case KHttp953NonAcceptableContent:
+            case KHttp909RequestedRangeNotSatisfiable:
+                {
+                // Permanent errors: retry is useless.
+                if( (*iData)[i]->iPausable ) 
+                    {
+                    //for pausable permanent errors
+                    //Are actually Temporary errors
+                    return TCodDownloadProgress::EFailedTemporary;
+                    }
+                break;
+                }
+            case KHttp954LoaderError:
+            case KHttp903LossOfService:
+            case KHttp910NoMemory:
+            	{
+            	if( (*iData)[i]->iPausable )
+            		{
+            		return TCodDownloadProgress::EPaused;
+            		}
+            	break;
+            	}
+            	
+
+            case KHttp955PreconditionFailed:
+                {
+                return TCodDownloadProgress::EInit;
+                }
+
+            default:
+                {
+                // Unexpected status.
+                //__ASSERT_DEBUG( EFalse, CodUiPanic( ECodUiInternal ) );
+                statusCode = TCodDownloadProgress::EFailedPermanent;
+                break;
+                }
+
+            }
+        }
+        
+    if( iData->Count() && allSucceeded == iData->Count())
+        {
+        return TCodDownloadProgress::ESucceeded;
+        }            
+    if( statusCode == TCodDownloadProgress::EFailedPermanent && !allSucceeded)    
+        {
+        return statusCode;
+        }
+
+    return TCodDownloadProgress::EFailedTemporary;    
+    }
+    
+//------------------------------------------------------------------------
+//CCodEngBase::UpdateTrackInfoL
+//------------------------------------------------------------------------    
+void CCodEngBase::UpdateTrackInfoL()
+    {
+    if (iObserver)
+        {
+        iObserver->UpdateTrackInfoL();
+        }
+    }
+
+//------------------------------------------------------------------------
+//CCodEngBase::SetUrlL
+//------------------------------------------------------------------------
+void CCodEngBase::SetUrlL(const TDesC& aUrl)
+	{
+	TInt currentActiveDownload = iData->ActiveDownload();
+	(*iData)[currentActiveDownload]->SetUrlL( aUrl );
+	}
+	
+	
+//------------------------------------------------------------------------
+//CCodEngBase::ContentTypeChanged
+//------------------------------------------------------------------------    
+void CCodEngBase::ContentTypeChanged()
+    {
+    if (iObserver)
+        {
+        iObserver->ContentTypeChanged();
+        }
+    }