browserutilities/downloadmgr/DownloadMgrServEng/Src/HttpDownload.cpp
author Kiiskinen Klaus (Nokia-D-MSW/Tampere) <klaus.kiiskinen@nokia.com>
Mon, 30 Mar 2009 12:54:55 +0300
changeset 0 dd21522fd290
child 1 7c90e6132015
permissions -rw-r--r--
Revision: 200911 Kit: 200912

/*
* Copyright (c) 2002-2004 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:  ?Description
*
*/



// INCLUDE FILES
#include    "HeaderField.h"
#include    "HttpDownloadManagerServerEngine.h"
#include    "HttpClientApp.h"
#include    "FileExt.h"
#include    "HttpDownload.h"
#include    "HttpStorage.h"
#include    "HttpDownloadMgrLogger.h"
#include    "bautils.h"

#include    <CommDbConnPref.h>
#include    <Uri16.h>
#include    <F32FILE.H>
#include    <EscapeUtils.h>
#include    <HttpFilterCommonStringsExt.h>
#include    <tinternetdate.h>
#include    <SysUtil.h>
#include    <MGXFileManagerFactory.h>
#include    <CMGXFileManager.h>
#include    <DcfEntry.h>
#include    <DcfRep.h>

#include    <pathinfo.h>

// EXTERNAL DATA STRUCTURES
//extern  ?external_data;

// EXTERNAL FUNCTION PROTOTYPES  
//extern ?external_function( ?arg_type,?arg_type );

// CONSTANTS
const TInt32 KDMgrInfoFileId = 0x2002;      // id to check if it's really an info file
const TInt32 KDmgrVersionNumber = 0x0301;   // version number of the info file
const TInt   KUrlFixChar = '_';
const TInt KMaxHeaderOfMultipart = 32000;
const TInt KRespSizeForRecognition = 1024;  //for THttpProgressState EHttpContTypeRecognitionAvail
const TInt KMinDataSizeToSend = (32*1024);  //for Browser Control to call NewDownloadL     

_LIT8( KHttpScheme, "http" );
_LIT8( KHttpsScheme, "https" );
_LIT8( KDefDestFilename, "content.bin" );
_LIT8( KSchemeAddon, "://" );
_LIT8( KBoundary, "boundary=" );
_LIT8( KDoubleEOL, "\r\n\r\n" );
_LIT8( KContentType, "Content-Type: " );

#ifdef __SYNCML_DM_FOTA
_LIT8( KFotaMimeType, "application/vnd.nokia.swupd.dp2");
#endif
_LIT8( KDefaultAcceptHeader, "multipart/mixed, application/java-archive, application/java, application/x-java-archive, text/vnd.sun.j2me.app-descriptor, application/vnd.oma.drm.message, application/vnd.oma.drm.content, application/vnd.wap.mms-message, text/x-co/desc, application/vnd.oma.dd+xml, text/javascript, text/javascript, application/x-javascript, text/ecmascript, */*" );
_LIT8( KDRMOldContentType, "x-drm-old-content-type");           // old content type header to be added

_LIT( KIndexString, "(%d)" );
const TInt KMaxIndexStringLength = 16;   // max size of index string "(4294967296)"

_LIT8( KCookieUsage, "CookiesEnabled" );

const TInt KStringAttribMaxLengths[][2] = {
    {EDlAttrReqUrl, KMaxUrlLength},
    {EDlAttrRedirUlr, KMaxUrlLength},
    {EDlAttrCurrentUrl, KMaxUrlLength},
    {EDlAttrName, KMaxPath},
    {EDlAttrRealm,KMaxRealmLength},
    {EDlAttrUsername, KMaxDefAttrLength},
    {EDlAttrPassword, KMaxDefAttrLength},
    {EDlAttrProxyRealm, KMaxRealmLength},
    {EDlAttrProxyUsername, KMaxDefAttrLength},
    {EDlAttrProxyPassword, KMaxDefAttrLength},
    {EDlAttrDestFilename, KMaxPath},
    {EDlAttrContentType, KMaxContentTypeLength},
    {EDlAttrMediaType, KMaxContentTypeLength},
    {0,0}
    };

const TInt KDownloadInfoIncrSize = 2*4096;     // used for DownloadInfo

_LIT( KDownloadPath, "download");

// MACROS
//#define ?macro ?macro_def

#define _OMADLOTA2_MULTI_DOWNLOAD	(iCodDlData && iCodDlData->Count()>1)

// LOCAL CONSTANTS AND MACROS
const TInt KDMHttpErrorBase = -25000;
#define GLOBAL_HTTP_ERROR( err ) ( KDMHttpErrorBase - err )
const TInt  KErrMultipeObjectDownloadFailed = -20046;  

// MODULE DATA STRUCTURES
//enum ?declaration
//typedef ?declaration

// LOCAL FUNCTION PROTOTYPES
//?type ?function_name( ?arg_type, ?arg_type );

// FORWARD DECLARATIONS
//class ?FORWARD_CLASSNAME;

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

// -----------------------------------------------------------------------------
// CHttpDownload::CHttpDownload
// C++ default constructor can NOT contain any code, that
// might leave.
// -----------------------------------------------------------------------------
//
CHttpDownload::CHttpDownload( CHttpClientApp *aClientApp,
                              TInt32 aId,
                              CHttpClientAppInstance* aClAppInstance )
    : CActive( EPriorityStandard )
    , iId( aId )
    , iClientApp( aClientApp )
    , iClAppInstance( aClAppInstance )
    , iPort( KDefaultPort )
    , iDisconnectOnPause( ETrue )
    , iDisconnectOnReset( ETrue )
    , iCodDownload( 0 )
    , iFotaPckgId( KDefaultFotaPckgId )
    , iDate( 0, EJanuary, 1, 0, 0, 0, 0 )
    , iExpires( 0, EJanuary, 1, 0, 0, 0, 0 )
    , iDlState( EHttpDlMultipleMOStarted )
    , iAction( ELaunch )
    , iRestartAction( ERestartIfExpired )
    , iPausable( ETrue )
    , iPausableDRM( ETrue )
    , iDrmContentLengthValid( ETrue )
    , iMultiPart( EFalse )
    , iDlNameChanged(EFalse)
    {
    __ASSERT_DEBUG( iClientApp, DMPanic( KErrArgument ) );
    CLOG_CREATE;
    }

// -----------------------------------------------------------------------------
// CHttpDownload::ConstructL
// Symbian 2nd phase constructor can leave.
// -----------------------------------------------------------------------------
//
void CHttpDownload::ConstructL( const TDesC8& aUrl )
    {
    CLOG_NAME_2( _L("cl%x_d%x"), iClientApp->AppUid(), iId );
    LOGGER_ENTERFN( "ConstructL" );
    CLOG_WRITE8_1( "URL: %S", &aUrl );

    CActiveScheduler::Add( this );

    iResponseHeaders = new (ELeave) CArrayPtrFlat<CHeaderField>(2);
    iRequestHeaders = new (ELeave) CArrayPtrFlat<CHeaderField>(2);
    iEntityHeaders = new (ELeave) CArrayPtrFlat<CHeaderField>(2);
    iGeneralHeaders = new (ELeave) CArrayPtrFlat<CHeaderField>(2);
    iStorage = CHttpStorage::NewL( this );
    iActiveDownload = 1 ;
    iMoLength = 0;
    iMoDownloadCompleted = EFalse;
    CLOG_ATTACH( iStorage, this );

    iUrl = aUrl.AllocL();
    if( iUrl->Length() )
        // this is a new download
        {
        ParseRequestedUrlL();   // iCurrentUrl is initialized there
        ParseDownloadNameL();
        StoreDownloadInfoL();
        SetDownloadStatus( EHttpProgNone, EHttpDlMultipleMOStarted );
        }
    else
        {
        LoadDownloadInfoL();

        if( iDlState == EHttpDlInprogress )
            // previous crash left this download here
            // reseting download can solve the problem
            {
            ++iDontFireEvent;

            TRAPD(err, PauseL() );

            --iDontFireEvent;
            
            User::LeaveIfError( err );
            }
        }

    if( !iStorage->CheckContentFileIntegrityL() )
        {
        if (iStorage->ProgressiveDownload() && 
             iStorage->Length() == iStorage->DownloadedSize() ) 
            // If it was a progressive download 
            // and downloaded size = content length,
            // it means that download was not properly closed
            // in the previous session
            {
            ReInitializeDownload();
            }
        else
            {
            OnError( KErrUnknown, EContentFileIntegrity );
            }
        }
        
        iMoveInProgress = EFalse;          
    }

// -----------------------------------------------------------------------------
// CHttpDownload::NewL
// Two-phased constructor.
// -----------------------------------------------------------------------------
//
CHttpDownload* CHttpDownload::NewL( const TDesC8& aUrl,
                                    CHttpClientApp *aClientApp,
                                    TInt32 aId,
                                    CHttpClientAppInstance* aClAppInstance )
    {
    __ASSERT_DEBUG( aId, DMPanic( KErrArgument ) );
    CHttpDownload* self = new( ELeave ) CHttpDownload( aClientApp,
                                                       aId,
                                                       aClAppInstance );
    
    CleanupStack::PushL( self );
    self->ConstructL( aUrl );
    CleanupStack::Pop();

    return self;
    }

    
// Destructor
CHttpDownload::~CHttpDownload()
    {
    ++iDontFireEvent;

    Cancel();

    delete iUrl;
    delete iRedirUrl;
    delete iCurrentUrl;
    delete iHttpRealm;
    delete iHttpNonce;
    delete iHttpUsername;
    delete iHttpPassword;
    delete iHttpProxyRealm;
    delete iHttpProxyUsername;
    delete iHttpProxyPassword;
    delete iContentType;
    delete iDDType;    
    delete iMediaType;
    delete iDlName;
	delete iDispositionType;
    delete iFileMan;
    
    
    delete iHashedMsgBody;
    delete iDownloadInfo;
    delete iAttachmentFileName;

    if( iTransValid )
        {
        iTrans.Close();
        }

    if( iResponseHeaders )
        {
        iResponseHeaders->ResetAndDestroy();
        delete iResponseHeaders;
        }

    if( iRequestHeaders )
        {
        iRequestHeaders->ResetAndDestroy();
        delete iRequestHeaders;
        }

    if( iEntityHeaders )
        {
        iEntityHeaders->ResetAndDestroy();
        delete iEntityHeaders;
        }

    if( iGeneralHeaders )
        {
        iGeneralHeaders->ResetAndDestroy();
        delete iGeneralHeaders;
        }

    delete iStorage;
    iStorage = NULL;
    delete iHeaderOfMultipart;
    
    iMoveInProgress = EFalse;
    
    CLOG_CLOSE;
    }

// -----------------------------------------------------------------------------
// CHttpDownload::Attach
// ?implementation_description
// (other items were commented in a header).
// -----------------------------------------------------------------------------
//
EXPORT_C void CHttpDownload::Attach( CHttpClientAppInstance* aClientAppInstance )
    {
    LOGGER_ENTERFN( "CHttpDownload::Attach" );
    
    __ASSERT_DEBUG( !iPDClAppInstance, DMPanic( KErrInUse) );
    iPDClAppInstance = aClientAppInstance;
    }

// -----------------------------------------------------------------------------
// CHttpDownload::StartL
// ?implementation_description
// (other items were commented in a header).
// -----------------------------------------------------------------------------
//
EXPORT_C void CHttpDownload::StartL()
    {
    LOGGER_ENTERFN( "StartL" );

    __ASSERT_DEBUG( !iNoMedia, DMPanic( KErrAbort ) );
    if( iNoMedia )
        // nomedia download cannot be started
        {
        SetDownloadStatus( EHttpProgNone, EHttpDlFailed, EInternal );

        return;
        }

    if( iContinueDownload )
        // Don't do anything until user accepts the given content
        // to be downloaded.
        {
        CLOG_WRITE( "Continue download" );


        if( !iConnHandler )
            // assign download to the connhandler
            // connection is surely up because it was created from client side
            // iClAppInstance also must be valid because it's a continue download
            {
            iConnHandler = iClAppInstance->ConnHandler();
            }

        if( iDlState == EHttpDlMultipleMOStarted )
            // do it only if EHttpDlCreated, anyway ignore Start request
            {
            iStorage->CreateDestinationFileL();

            SetDownloadStatus( EHttpProgResponseHeaderReceived );
            }
        else if( iDlState == EHttpDlInprogress )
            {
            TriggerEvent( EHttpDlAlreadyRunning );
            }
            
        // This is the place where client already set every continue
        // download attribute
        StoreDownloadInfoL();

        return;
        }
    if( iCodDownload )
        {
        if(iDlState == EHttpDlPaused)
            {
            if( !iConnHandler )
                {
                iConnHandler = iClAppInstance->ConnHandler();
                }
            SetDownloadStatus( EHttpStarted );
            //TriggerEvent( EHttpDlInprogress, EHttpProgCodDownloadShouldResume );
            }
        else
            {
            TriggerEvent( EHttpDlInprogress, EHttpProgCodDownloadStarted );
            }
        return;
        }
    switch( iDlState )
        {
        case EHttpDlMultipleMOStarted:
            // normal start from the beginning
            break;

        case EHttpDlInprogress:

            if( iUpdatedDDUriSet )
                {
                ReInitializeDownload();

                iStorage->UpdateDestinationFilenameL( KNullDesC, EFalse );

                ParseRequestedUrlL();   // iCurrentUrl is initialized there
                ParseDownloadNameL();
                StoreDownloadInfoL();
                SetDownloadStatus( EHttpStarted );
                
               if( !iConnHandler )
                    // assign download to the connhandler
                    // connection is surely up because it was created from client side
                    // iClAppInstance also must be valid because it's a continue download
                    {
                    iConnHandler = iClAppInstance->ConnHandler();
                    }

                }
            else
                {
                TriggerEvent( EHttpDlAlreadyRunning );
                }
            return;

        case EHttpDlPaused:
            {
            if( IsExpired() || !iPausable )
                // cannot be resume:
                // expired
                // non-pauseable
                {
                ForcedRestartL();
                }
            }
            break;

        case EHttpDlMultipleMOCompleted:
            {
            if( iRestartAction == ERestartNoIfCompleted )
                // nothing to do because content is downloaded
                // and update check is not interested
                {
                TriggerEvent( EHttpDlMultipleMOCompleted );
                return;
                }
            else if( iRestartAction == ERestartForced )
                // doesn't matter what we have. 
                // Download must be restarted from the very beginning
                {
                ForcedRestartL();
                }
            else if( iRestartAction == ERestartIfExpired )
                // First check that content is expired
                // If so, check for update on the server
                {
                if( !IsExpired() )
                    // content is still valid -> no need to download again
                    // Client has to use ERestartForced or Reset() to
                    // be able to download it again
                    {
                    TriggerEvent( EHttpDlMultipleMOCompleted );
                    return;
                    }
                }
            }
            break;

        case EHttpDlFailed:
            {
            if( NoMedia() )
                // we can't restart because original media is not present.
                // need a reset.
                {
                TriggerEvent( EHttpDlMediaRemoved );
                }
            else if( iRestartAction == ERestartNoIfCompleted )
                {
                if( iLastError == EContentExpired )
                    // Can't download content because it's expired.
                    // Use ERestartIfExpired, ERestartForced or Reset()
                    {
                    OnError( KErrUnknown, EContentExpired );
                    return;
                    }
                }
            }
            break;

        default:
            break;
        }

    if( iRedirect )
        // Requested url has to be restored, because of a previous redirection
        {
        ReallocateStringL( iCurrentUrl, *iRedirUrl, KMaxUrlLength );
        iRedirect = EFalse;
        }

    __ASSERT_DEBUG( iClAppInstance || iPDClAppInstance, DMPanic( KErrCorrupt ) );
    if (iPDClAppInstance && !iClAppInstance )
    //this is the case when browser is the main client and we  exit browser
    //in this case the PD client has to be made the main client.
        {
        iClAppInstance = iPDClAppInstance;
        iPDClAppInstance = NULL;
        }
    if( iClAppInstance )
        {        
        if( !iConnHandler )
            {
            iConnHandler = iClAppInstance->ConnHandler();
            }

        iUseCookies = iClAppInstance->Cookies();
        }

    iDlStartedByClient = ETrue;

    SetDownloadStatus( EHttpStarted );
    
    }

// -----------------------------------------------------------------------------
// CHttpDownload::PauseL
// ?implementation_description
// (other items were commented in a header).
// -----------------------------------------------------------------------------
//
EXPORT_C void CHttpDownload::PauseL( TBool aStore )
    {
    LOGGER_ENTERFN( "PauseL" );

    if( iDlState == EHttpDlPaused )
        // already paused
        {
        TriggerEvent( EHttpDlPaused );
        return;
        }

    //If the download is failed or completed, pause doesnt has any effect.
    if( iDlState == EHttpDlMultipleMOCompleted || iDlState == EHttpDlMultipleMOFailed )
        {
        return;
        }

    InternalPauseL( iDisconnectOnPause );

    //Pause the download only if it is pausable
    if( iDlState == EHttpDlInprogress )
        {
        if( Pausable() )
            // Do not change state when it's
            // created, pause, completed or failed.
            {
            SetDownloadStatus( EHttpProgNone, EHttpDlPaused );

            if( iCodDownload )
                {
                TriggerEvent( EHttpDlPaused, EHttpProgCodDownloadPause );
                }
            }
        else
            {
            //Else report error
            OnError( iGlobalErrorId, (THttpDownloadMgrError) iLastError );
            }
        }

    if( aStore && Pausable() )
        {
        StoreDownloadInfoL();
        }
    }

// -----------------------------------------------------------------------------
// CHttpDownload::Reset
// ?implementation_description
// (other items were commented in a header).
// -----------------------------------------------------------------------------
//
EXPORT_C void CHttpDownload::Reset()
    {
    LOGGER_ENTERFN( "Reset" );

    DoReset();
    }

// -----------------------------------------------------------------------------
// CHttpDownload::Delete
// ?implementation_description
// (other items were commented in a header).
// -----------------------------------------------------------------------------
//
EXPORT_C void CHttpDownload::Delete( CHttpClientAppInstance* aClAppInstance )
    {
    CLOG_WRITE( "Delete()" );
    if( !ClientApp()->Engine()->IsEngineClosing() )
        {
        if( aClAppInstance )
            {
            if( iPDClAppInstance == aClAppInstance )
                {
                iPDClAppInstance = NULL;
                if( !iStorage->ProgressiveMode() )
                    {
                    return;//This Attribute tells if Delete is called from MP when Exiting from Browser
                    }
                if( iClAppInstance )
                    {
                    SetDownloadStatus( EHttpProgNone, EHttpDlDeleting );
                    //Deref Attach Download instance
                    aClAppInstance->ClientApp()->UnregisterDownload( this ); 
                    return;
                    }
                }
            else if( iClAppInstance == aClAppInstance )
                {
                iClAppInstance = NULL;
                if( iPDClAppInstance )
                    {
                    SetDownloadStatus( EHttpProgNone, EHttpDlDeleting );
                    //Deref Master Client Instance
                    aClAppInstance->ClientApp()->UnregisterDownload( this );                    
                    return;
                    }
                }        
            }
        }

    // Do not inform user about that we are in deleteing state
    // This won't be reenabled at the end of this function so
    // don't call delete only from outside of this class.
    ++iDontFireEvent;
    
    TPath folder;
    TFileName file;

    // delete info file
    iClientApp->Engine()->DownloadInfoFolder( iClientApp, folder );
    file.Format( _L("%S%d"), &folder, iId );
    TInt err = iClientApp->Engine()->Fs().Delete( file );
    CLOG_WRITE_2( "Delete info file: %S, err : %d", &file, err );

    // delete cod info file
    iClientApp->Engine()->CODDownloadInfoFolder( iClientApp, folder );
    file.Format( _L("%S%d"), &folder, iId );
    //delete main info file
    err = iClientApp->Engine()->Fs().Delete( file );
    CLOG_WRITE_2( "Delete info file: %S, err : %d", &file, err );
    
    //delete subinfo file
    CFileMan* fileMan = CFileMan::NewL(iClientApp->Engine()->Fs() );
    file.Format( _L("%S%d_*"), &folder, iId );
    fileMan->Delete( file );
    delete fileMan;
        

    // to make sure the CHttpStorage releases the content file
    // and deletes it.
    CHttpStorage::TFileCloseOperation closeOp = CHttpStorage::EDeleteFile;
    
    if( iStorage->DestFNameSet() && iDlState == EHttpDlMultipleMOCompleted )
        // Do NOT delete the file: if the destination filename was
        // set by the client and download completed.
	        {
	        CLOG_WRITE("Keep file");
	        closeOp = CHttpStorage::EKeepFile;
	        }
    
	if( iStorage->RFileSetByClient())
	    {
	    TBool pausable;
        GetBoolAttributeL( EDlAttrPausable, pausable );
        if( iDlState == EHttpDlMultipleMOCompleted || ( iDlState == EHttpDlInprogress && pausable ) )
            {
            CLOG_WRITE("Keep file");
	        closeOp = CHttpStorage::EKeepFile;
            }
	    }
    if( iCodDlData )
	    {
	    // For User Delete when all the Downloads are moved to gallery
	    if( EHttpDlMultipleMOCompleted == iDlState && closeOp == CHttpStorage::EDeleteFile )
		    {
		    for(TInt i = 1; i <= iCodDlData->Count(); i++)
		    	{
		    	TPtrC fullName = ((*iCodDlData)[i])->DestFilename();
		    	ClientApp()->Engine()->Fs().Delete( fullName );
		    	}	
		    }
		// For User Cancel to Cancel Multiple download, Current and Queued DLs will be delete, completed ones will be kept    
		else if( EHttpDlInprogress == iDlState || EHttpDlPaused == iDlState || EHttpDlDeleting == iDlState)
			{
			for(TInt i = 1; i <= iCodDlData->Count(); i++)
		    	{
		    	if( EInProgress == ((*iCodDlData)[i])->State() || EFailed == ((*iCodDlData)[i])->State() )	// OnGoing and Queued will be deleted	  
			    	{
			    	TPtrC fullName = ((*iCodDlData)[i])->DestFilename();
			    	if(fullName.Length())
			    	    {
			    	    ClientApp()->Engine()->Fs().Delete( fullName );	    
			    	    }
			    	}  
		    	//else if( ESucceeded == ((*iCodDlData)[i])->State() ) 
		    	// Completed ones will be kept and moved to Gallery
		    	else if( ESucceeded == ((*iCodDlData)[i])->State() )
			    	{
			    	MoveInDelete(i);
			    	}
		    	}	
			} 	
	    }
    else
    	{
    	iStorage->CloseDestinationFile( closeOp );
    	}
    // when delete there's no store -> no leave
    aClAppInstance->ClientApp()->UnregisterDownload( this ); 
    }


// -----------------------------------------------------------------------------
// CHttpDownload::DeleteInfoFile
// ?implementation_description
// (other items were commented in a header).
// -----------------------------------------------------------------------------
//
EXPORT_C void CHttpDownload::DeleteInfoFile( CHttpClientAppInstance* aClAppInstance )
    {
    CLOG_WRITE( "DeleteInfoFile()" );
    
    // This should be called only after the completion of download
	if( ! (EHttpDlMultipleMOCompleted == iDlState && 
    		( 
    		EHttpProgContentFileMoved == iProgState ||
    		EHttpProgContentFileMovedAndDestFNChanged == iProgState 
    		)
    	))
		{
   		return;
		}

    // Do not inform user about that we are in deleteing state
    // This won't be reenabled at the end of this function so
    // don't call delete only from outside of this class.
    ++iDontFireEvent;
    
    TPath folder;
    TFileName file;

    // delete info file
    iClientApp->Engine()->DownloadInfoFolder( iClientApp, folder );
    file.Format( _L("%S%d"), &folder, iId );
    CLOG_WRITE_1( "Delete info file: %S", &file );
    iClientApp->Engine()->Fs().Delete( file );

    // delete cod info file
    iClientApp->Engine()->CODDownloadInfoFolder( iClientApp, folder );
    file.Format( _L("%S%d"), &folder, iId );
    CLOG_WRITE_1( "Delete info file: %S", &file );
    iClientApp->Engine()->Fs().Delete( file );    
    
    //delete subinfo file
    CFileMan* fileMan = CFileMan::NewL(iClientApp->Engine()->Fs() );
    file.Format( _L("%S%d_*"), &folder, iId );
    fileMan->Delete( file );
    delete fileMan;
    

    // to make sure the CHttpStorage releases the content file
    // and deletes it.
    CHttpStorage::TFileCloseOperation closeOp = CHttpStorage::EDeleteFile;
    
    if( iStorage->DestFNameSet() && iDlState == EHttpDlMultipleMOCompleted )
        // Do NOT delete the file: if the destination filename was
        // set by the client and download completed.
        {
        CLOG_WRITE("Keep file");
        closeOp = CHttpStorage::EKeepFile;
        }
        
    iStorage->CloseDestinationFile( closeOp );

    // when delete there's no store -> no leave	
    aClAppInstance->ClientApp()->UnregisterDownload( this ); 
    }


// -----------------------------------------------------------------------------
// CHttpDownload::MoveL
// ?implementation_description
// (other items were commented in a header).
// -----------------------------------------------------------------------------
//
EXPORT_C void CHttpDownload::MoveL()
    {
    LOGGER_ENTERFN( "MoveL" );
    
    
    if(iMoveInProgress) 
    {
    	CLOG_WRITE(" return MoveL  ");
    	return;
    }

    iMoveInProgress = ETrue;

    if( !iCodDownload && iDlState != EHttpDlMultipleMOCompleted )
        {
        User::Leave( KErrNotReady );
        }
    //Incase of COD downloads, Move should happen only after COD Load End
   if( iCodDownload && iProgState != EHttpProgCodLoadEnd )
		{
        User::Leave( KErrNotReady );
		}

    if( iProgState == EHttpProgMovingContentFile )
        {
        User::Leave( KErrInUse );
        }
        
        //File is already moved. Ignore the move
    if( iProgState == EHttpProgContentFileMovedAndDestFNChanged ||
    
      	iProgState ==  EHttpProgContentFileMoved )
        {
        return;
        }
        
    __ASSERT_DEBUG( !IsActive(), DMPanic( KErrInUse ) );
    //__ASSERT_DEBUG( !iFileMan, DMPanic( KErrInUse ) );
    
    if(_OMADLOTA2_MULTI_DOWNLOAD)
        {
		iMOMoved = 1;
		SetDownloadStatus( EHttpProgMovingContentFile, iDlState );
		MoveDownloadedMediaObjectL(iMOMoved);
		return;
        }


	RFs &rFs = iClientApp->Engine()->Fs();
	if(!iFileMan)
		{
		iFileMan = CFileMan::NewL(rFs);	
		}

    CLOG_WRITE_1( "Src: %S", iStorage->LocalFilename() );
    CLOG_WRITE_1( "Dest: %S", iStorage->DestFilename() );
    UpdateDestFileNameL();

    HBufC* fileName = HBufC::NewLC( KMaxPath );
    TPtr fileNamePtr = fileName->Des();
    fileNamePtr = *iStorage->DestFilename();
    HBufC* uniqueName = NULL;
    TInt index( 0 );
    TBool bFound( EFalse );
    do
        {
        CreateIndexedNameL(uniqueName , fileNamePtr , index);
        if( !BaflUtils::FileExists( rFs , *uniqueName ) )
        //Check if file name exist in Destination path
        //Generate Unique name if exist 
            {
            bFound =ETrue;
            break;
            }
        iDlNameChanged = ETrue;
            
        }while( !bFound );
    CleanupStack::PopAndDestroy( fileName );           

  	if( iDlNameChanged )
  	    {
  	    HBufC16* destFileName ;
  	    destFileName = iStorage->DestFilename();           
  	    TPtr destFileNamePtr = destFileName->Des();
  	    destFileNamePtr.Replace(0, destFileNamePtr.Length() , *uniqueName);    
  	    TInt lastSlashPos = destFileNamePtr.LocateReverse( '\\' );
  	    TPtr dlName = destFileNamePtr.MidTPtr(lastSlashPos +1 );
        TInt dotPos = iDlName->LocateReverse( '.' );
        if( dotPos == KErrNotFound )
            {
            //Remove Extension from dlName as it was not present in old iDlName 
            dotPos = dlName.LocateReverse( '.' );
            if(dotPos != KErrNotFound )
                {
                dlName.Copy( dlName.Left(dotPos));
                }            
            }
  	    //download name has changed
  	    ReallocateStringL( iDlName, dlName, KDownloadNameMaxSize );
  	    }      
  	    
  	TInt err =iFileMan->Move( *iStorage->LocalFilename(), 
                                        *iStorage->DestFilename(), 
                                        CFileMan::EOverWrite,
                                        iStatus );
    if(err != KErrNone)
    	{
    	iMoveInProgress = EFalse;
    	CLOG_WRITE("setting iMoveInProgress false when move fails");
    	}
    	
    User::LeaveIfError( err ); 
    // waiting for move to complete
    SetActive();
    SetDownloadStatus( EHttpProgMovingContentFile, iDlState );
    }

// -----------------------------------------------------------------------------
// CHttpDownload::GetIntAttributeL
// ?implementation_description
// (other items were commented in a header).
// -----------------------------------------------------------------------------
//
EXPORT_C void CHttpDownload::GetIntAttributeL( THttpDownloadAttrib aAttribute, 
							                   TInt32& aValue )
    {
    LOGGER_ENTERFN( "GetIntAttributeL" );
    CLOG_WRITE_1( "Attr(%d)", aAttribute );

    iNoRealError = ETrue;

    switch( aAttribute )
        {
        case EDlAttrState:
            {
            if(iDlState == EHttpDlMultipleMOCompleted )
                {
                 aValue = EHttpDlCompleted;
                }
            else if(iDlState == EHttpDlMultipleMOFailed )
                {
                aValue = EHttpDlFailed;
                }
            else
                {
                aValue = iDlState;
                }
            }
            break;

        case EDlAttrProgressState:
            {
            aValue = iProgState;
            }
            break;

        case EDlAttrUserData:
            {
            aValue = iUserData;
            }
            break;

        case EDlAttrId:
            {
            aValue = iId;
            }
            break;

        case EDlAttrMultipleMOLength:
            {
            if ( iCodDownload )
                {
                aValue = iMoLength;    
                }
            else
                {
                aValue = iStorage->Length();
                }
            }
            break;

        case EDlAttrMultipleMODownloadedSize:
            {
            if( iCodDownload )
                {
                aValue = iStorage->MoDownloadedSize();    
                }
            else
                {
                aValue = iStorage->DownloadedSize();
                }
            }
            break;
            
        case EDlAttrLength:
            {
            aValue = iStorage->Length();
            }
            break;

        case EDlAttrDownloadedSize:
            {
            aValue = iStorage->DownloadedSize();
            }
            break;

        case EDlAttrStatusCode:
            {
            aValue = iStatusCode;
            }
            break;

        case EDlAttrAction:
            {
            aValue = iAction;
            }
            break;

        case EDlAttrPort:
            {
            aValue = iPort;
            }
            break;

        case EDlAttrRestartAction:
            {
            aValue = iRestartAction;
            }
            break;

        case EDlAttrErrorId:
            {
            aValue = iLastError;
            }
            break;

        case EDlAttrGlobalErrorId:
            {
            aValue = iGlobalErrorId;
            }
            break;

        case EDlAttrTargetApp:
            {
            aValue = iTargetApp;
            }
            break;

        case EDlAttrAuthScheme:
            {
            aValue = iAuthScheme;
            }
            break;

        case EDlAttrRequestHeaderAddonLength:
            {
            aValue = 0;

            for( TInt i = 0; i < iRequestHeaders->Count(); ++i )
                {
                aValue += (*iRequestHeaders)[i]->FieldName()->Length() +
                          (*iRequestHeaders)[i]->FieldRawData()->Length() +
                          2;    // +2 = KColon + KHttpFieldSeparator
                }
            }
            break;

        case EDlAttrMethod:
            {
            aValue = iMethod;
            }
            break;

        case EDlAttrFotaPckgId:
            {     
            aValue = iFotaPckgId;
            }
            break;
            
        case EDlAttrNumMediaObjects:
            {
            aValue = 1;
            if(iCodDlData)
                {
                aValue = iCodDlData->Count();
                }
            }
            break;
        case EDlAttrActiveDownload:
            {
            aValue = iActiveDownload;
            }
            break;
        case EDlAttrActivePlayedDownload:
            {
            aValue = iActivePlayedDownload;
            }
            break;    
            
        default:
            {
            CLOG_WRITE_1( "Unknown int attrib: %d", aAttribute );
#ifdef __WINS__
            DMPanic( KErrArgument );
#else
            User::Leave( KErrArgument );
#endif
            }
            break;
        }
    
    iNoRealError = EFalse;
    }
    
// -----------------------------------------------------------------------------
// CHttpDownload::GetIntAttributeL
// ?implementation_description
// (other items were commented in a header).
// -----------------------------------------------------------------------------
//
EXPORT_C void CHttpDownload::GetIntAttributeL( THttpDownloadAttrib aAttribute, 
							                   TInt32& aMoIndex,
							                   TInt32& aValue )
    {
    LOGGER_ENTERFN( "GetIntAttributeL" );
    CLOG_WRITE_1( "Attr(%d)", aAttribute );
    
    if (!iCodDlData)
    	{
    	aValue = 0;
    	return;
    	}
    if ((aMoIndex <= KNonMoIndex) || (aMoIndex > iCodDlData->Count()))
    	{
    	User::Leave( KErrArgument );
    	}
    
    CMediaDataBase* mediaData = (*iCodDlData)[aMoIndex];
    iNoRealError = ETrue;

    switch( aAttribute )
        {
        case EDlAttrMultipleMOLength:
            {
			aValue = iMoLength;
            }
            break;

        case EDlAttrMultipleMODownloadedSize:
            {
            // Calculate downloaded size of current media object from
            // album downloaded size.
            TInt dlSize = iStorage->DownloadedSize();
            for (TInt index = 0; index < iCodDlData->Count(); ++index)
            	{
            	CMediaDataBase* moData = (*iCodDlData)[index+1];
            	if ((moData->State() == ESucceeded) || (moData->State() == EInProgress))
            		dlSize -= moData->DownloadedSize();
            	}
            
            aValue = dlSize;
            }
            break;
            
        case EDlAttrLength:
	        {
	        aValue = iStorage->Length();
	        }
	        break;

        case EDlAttrDownloadedSize:
            {
            aValue = iStorage->DownloadedSize();
            }
            break;

        case EDlAttrErrorId:
            {
            aValue = mediaData->LastErrorId();
            }
            break;

        case EDlAttrGlobalErrorId:
            {
            aValue = mediaData->GlobalErrorId();
            }
            break;

        case EDlAttrMethod:
            {
            aValue = mediaData->Method();
            }
            break;

        default:
            {
            CLOG_WRITE_1( "Unknown int attrib: %d", aAttribute );
#ifdef __WINS__
            DMPanic( KErrArgument );
#else
            User::Leave( KErrArgument );
#endif
            }
            break;
        }
    
    iNoRealError = EFalse;
    }

// -----------------------------------------------------------------------------
// CHttpDownload::GetBoolAttributeL
// ?implementation_description
// (other items were commented in a header).
// -----------------------------------------------------------------------------
//
EXPORT_C void CHttpDownload::GetBoolAttributeL( THttpDownloadAttrib aAttribute, 
								                TBool& aValue )
    {
    LOGGER_ENTERFN( "GetBoolAttributeL" );
    CLOG_WRITE_1( "Attr(%d): %d", aAttribute );

    iNoRealError = ETrue;

    switch( aAttribute )
        {
        case EDlAttrNoContentTypeCheck:
            {
            aValue = iNoContentTypeCheck;
            }
            break;

        case EDlAttrDisconnectOnReset:
            {
            aValue = iDisconnectOnReset;
            }
            break;

        case EDlAttrDisconnectOnPause:
            {
            aValue = iDisconnectOnPause;
            }
            break;

        case EDlAttrNoMedia:
            {
            aValue = iNoMedia;
            }
            break;

        case EDlAttrRedirected:
            {
            aValue = iRedirect;
            }
            break;

        case EDlAttrPausable:
            {
            aValue = iPausable;
            }
            break;

        case EDlAttrHidden:
            {
            aValue = iHidden;
            }
            break;

        case EDlAttrSilent:
            {
            aValue = iSilentMode;
            }
            break;

        case EDlAttrContinue:
            {
            aValue = iContinueDownload;
            }
            break;

        case EDlAttrCodDownload:
            {
            aValue = iCodDownload;
            }
            break;            
   
        case EDlAttrProgressive:
            {
            aValue = iStorage->ProgressiveMode();
            }
            break;
   
        case EDlAttrDestRemovable:
            {
            aValue = iStorage->RemovableDest();
            }
            break;

        case EDlAttrCodPdAvailable:
            {
            aValue = iCodPdAvailable;
            }
            break;
        default:
            {
            CLOG_WRITE_1( "Unknown bool attrib: %d", aAttribute );

#ifdef __WINS__
            DMPanic( KErrArgument );
#else
            User::Leave( KErrArgument );
#endif
            }
            break;
        }
    
    iNoRealError = EFalse;
    }

// -----------------------------------------------------------------------------
// CHttpDownload::GetBoolAttributeL
// ?implementation_description
// (other items were commented in a header).
// -----------------------------------------------------------------------------
//
EXPORT_C void CHttpDownload::GetBoolAttributeL( THttpDownloadAttrib aAttribute, 
								                TInt32& aMoIndex,
								                TBool& aValue )
    {
    LOGGER_ENTERFN( "GetBoolAttributeL" );
    CLOG_WRITE_1( "Attr(%d): %d", aAttribute );
    
    if (!iCodDlData)
    	{
    	aValue = 0;
    	return;
    	}
    if ((aMoIndex <= KNonMoIndex) || (aMoIndex > iCodDlData->Count()))
    	{
    	User::Leave( KErrArgument );
    	}
    	
    CMediaDataBase* mediaData = (*iCodDlData)[aMoIndex];
    iNoRealError = ETrue;

    switch( aAttribute )
        {
        case EDlAttrRedirected:
            {
            aValue = mediaData->Redirected();
            }
            break;

        case EDlAttrPausable:
            {
            aValue = mediaData->Pausable();
            }
            break;

        case EDlAttrProgressive:
            {
            aValue = mediaData->ProgressiveDownload();
            }
            break;
   
        case EDlAttrDestRemovable:
            {
            aValue = mediaData->DesRemovable();
            }
            break;

        default:
            {
            CLOG_WRITE_1( "Unknown bool attrib: %d", aAttribute );

#ifdef __WINS__
            DMPanic( KErrArgument );
#else
            User::Leave( KErrArgument );
#endif
            }
            break;
        }
    
    iNoRealError = EFalse;
    }

// -----------------------------------------------------------------------------
// CHttpDownload::GetStringAttributeL
// ?implementation_description
// (other items were commented in a header).
// -----------------------------------------------------------------------------
//
EXPORT_C HBufC* CHttpDownload::GetStringAttributeL( THttpDownloadAttrib aAttribute, 
                                                    TBool& aDelete )
    {
    LOGGER_ENTERFN( "GetStringAttributeL" );
    CLOG_WRITE_1( "Attr(%d): %d", aAttribute );

    iNoRealError = ETrue;
    HBufC* attr = NULL;
    HBufC8* attr8 = NULL;

    aDelete = EFalse;

    switch( aAttribute )
        {
        case EDlAttrReqUrl:
            {
            attr8 = iUrl;
            }
            break;

        case EDlAttrRedirUlr:
            {
            attr8 = iRedirUrl;
            }
            break;

        case EDlAttrCurrentUrl:
            {
            attr8 = iCurrentUrl;
            }
            break;

        case EDlAttrContentType:
            {
            attr8 = iContentType;
            }
            break;

        case EDlAttrDDType:
            {
            attr8 = iDDType;
            }
            break;            

        case EDlAttrRealm:
            {
            attr8 = iHttpRealm;
            }
            break;

        case EDlAttrUsername:
            {
            attr8 = iHttpUsername;
            }
            break;

        case EDlAttrProxyUsername:
            {
            attr8 = iHttpProxyUsername;
            }
            break;

        case EDlAttrRequestHeaderAddon:
            {
            TChar colon( KColon );
            TInt32 length( 0 );

            GetIntAttributeL( EDlAttrRequestHeaderAddonLength, length );
            if( length )
                {
                attr8 = HBufC8::NewLC( length );

                aDelete = ETrue;

                for( TInt i = 0; i < iRequestHeaders->Count(); ++i )
                    {
                    TPtrC8 fieldName( *(*iRequestHeaders)[i]->FieldName() );
                    TPtrC8 fieldData( *(*iRequestHeaders)[i]->FieldRawData() );

                    attr8->Des().Append( fieldName );
                    attr8->Des().Append( colon );
                    attr8->Des().Append( fieldData );
                    attr8->Des().Append( KHttpFieldSeparator() );
                    }

                CleanupStack::Pop();
                }
            }
            break;

        case EDlAttrDestFilename:
            {
            attr = iStorage->DestFilename();
            }
            break;

        case EDlAttrLocalFileName:
            {
            attr = iStorage->LocalFilename();
            }
            break;
            
        case EDlAttrDdFileName:
        	{
        	attr = iStorage->DdFileName();
        	}
        	break;

        case EDlAttrName:
            {
            attr = iDlName;
            }
            break;

        // Response headers
//        case EDlAttrCharSet:
        case EDlAttrResponseCharSet:
        case EDlAttrResponseAge:
        case EDlAttrResponseETag:
        case EDlAttrResponseLocation:
        case EDlAttrResponseRetryAfter:
        case EDlAttrResponseServer:
        case EDlAttrResponseVary:
            {
            for( TInt i = 0; KResponseHeaderConvTable[i][0]; ++i )
                {
                if( KResponseHeaderConvTable[i][0] == aAttribute )
                    {
                    attr8 = HeaderFieldL( iResponseHeaders, KResponseHeaderConvTable[i][1] );
                    break;
                    }
                }
            }
            break;

        // Request headers
        case EDlAttrRequestAccept:
        case EDlAttrRequestAcceptCharSet:
        case EDlAttrRequestAcceptLanguage:
        case EDlAttrRequestExpect:
        case EDlAttrRequestFrom:
        case EDlAttrRequestHost:
        case EDlAttrRequestMaxForwards:
        case EDlAttrRequestPragma:
        case EDlAttrRequestReferer:
        case EDlAttrRequestUserAgent:
        case EDlAttrRequestVary:
            {
            for( TInt i = 0; KRequestHeaderConvTable[i][0]; ++i )
                {
                if( KRequestHeaderConvTable[i][0] == aAttribute )
                    {
                    attr8 = HeaderFieldL( iRequestHeaders, KRequestHeaderConvTable[i][1] );
                    break;
                    }
                }
            }
            break;

        // Entity header fields
        case EDlAttrEntityAllow:
        case EDlAttrEntityContentEncoding:
        case EDlAttrEntityContentLanguage:
        case EDlAttrEntityContentLocation:
        case EDlAttrEntityExpires:
        case EDlAttrEntityLastModified:
            {
            for( TInt i = 0; KEntityHeaderConvTable[i][0]; ++i )
                {
                if( KEntityHeaderConvTable[i][0] == aAttribute )
                    {
                    attr8 = HeaderFieldL( iEntityHeaders, KEntityHeaderConvTable[i][1] );
                    break;
                    }
                }
            for( TInt i = 0; KResponseHeaderConvTable[i][0]; ++i )
                {
                if( KResponseHeaderConvTable[i][0] == aAttribute )
                    {
                    attr8 = HeaderFieldL( iResponseHeaders, KResponseHeaderConvTable[i][1] );
                    break;
                    }
                }
            }
            break;

        // General header fields
        case EDlAttrGeneralCacheControl:
        case EDlAttrGeneralDate:
        case EDlAttrGeneralPragma:
        case EDlAttrGeneralVia:
        case EDlAttrGeneralWarning:
            {
            for( TInt i = 0; KGeneralHeaderConvTable[i][0]; ++i )
                {
                if( KGeneralHeaderConvTable[i][0] == aAttribute )
                    {
                    attr8 = HeaderFieldL( iGeneralHeaders, KGeneralHeaderConvTable[i][1] );
                    break;
                    }
                }
            for( TInt i = 0; KResponseHeaderConvTable[i][0]; ++i )
                {
                if( KResponseHeaderConvTable[i][0] == aAttribute )
                    {
                    attr8 = HeaderFieldL( iResponseHeaders, KResponseHeaderConvTable[i][1] );
                    break;
                    }
                }
            }
            break;
        
        case EDlAttrAlbumName:
            {
            if (iCodDlData && (iCodDlData->Name().Compare(KNullDesC)))
                {
                attr = iCodDlData->Name().AllocL();
                aDelete = ETrue;
                }
            else
                {
                attr = iDlName;
                }
            }
            break;
            
        default:
            {
                {
                CLOG_WRITE_1( "Unknown string8 attrib: %d", aAttribute );
#ifdef __WINS__
            DMPanic( KErrArgument );
#else
            User::Leave( KErrArgument );
#endif
                }
            }
            break;
        }

    if( !attr && !attr8 )
        {
        CLOG_WRITE_1( "NULL attrib: %d", aAttribute );
        User::Leave( KErrNotFound );
        }

    if( attr8 )
        // it is an 8-bit attribute
        // need to be converted to 16-bits
        {
        if( aDelete )
            {
            CleanupStack::PushL( attr8 );
            }

        ReallocateStringL( attr, *attr8 );
        if( aDelete )
            {
            CleanupStack::PopAndDestroy( attr8 );
            }

        // it is always true because of the conversion.
        aDelete = ETrue;
        }

    iNoRealError = EFalse;

    return attr;
    }

// -----------------------------------------------------------------------------
// CHttpDownload::GetStringAttributeL
// ?implementation_description
// (other items were commented in a header).
// -----------------------------------------------------------------------------
//
EXPORT_C HBufC* CHttpDownload::GetStringAttributeL( THttpDownloadAttrib aAttribute, 
                                                    TInt32& aMoIndex,
                                                    TBool& aDelete )
    {
    LOGGER_ENTERFN( "GetStringAttributeL" );
    CLOG_WRITE_1( "Attr(%d): %d", aAttribute );

	if (!iCodDlData)
    	{
    	return (KNullDesC().AllocL());
    	}
    if ((aMoIndex <= KNonMoIndex) || (aMoIndex > iCodDlData->Count()))
    	{
    	User::Leave( KErrArgument );
    	}
    	
    CMediaDataBase* mediaData = (*iCodDlData)[aMoIndex];
    iNoRealError = ETrue;
    HBufC* attr = NULL;
    HBufC8* attr8 = NULL;

    aDelete = EFalse;

    switch( aAttribute )
        {
        case EDlAttrReqUrl:
            {
            attr8 = mediaData->Url().AllocL();
            aDelete = ETrue;
            }
            break;

        case EDlAttrRedirUlr:
            {
            attr8 = mediaData->RedirUrl().AllocL();
            aDelete = ETrue;
            }
            break;

        case EDlAttrContentType:
            {
            attr8 = mediaData->Type().AllocL();
            aDelete = ETrue;
            }
            break;

        case EDlAttrDestFilename:
            {
            attr = mediaData->DestFilename().AllocL();
            aDelete = ETrue;
            }
            break;

        case EDlAttrName:
            {
            if (aMoIndex == iActiveDownload)
            	{
            	attr = iDlName;
            	}
            else
	            {
	            attr = mediaData->Name().AllocL();
            	aDelete = ETrue;
    	        }
            }
            break;

        default:
            {
                {
                CLOG_WRITE_1( "Unknown string8 attrib: %d", aAttribute );
#ifdef __WINS__
            DMPanic( KErrArgument );
#else
            User::Leave( KErrArgument );
#endif
                }
            }
            break;
        }

    if( !attr && !attr8 )
        {
        CLOG_WRITE_1( "NULL attrib: %d", aAttribute );
        User::Leave( KErrNotFound );
        }

    if( attr8 )
        // it is an 8-bit attribute
        // need to be converted to 16-bits
        {
        if( aDelete )
            {
            CleanupStack::PushL( attr8 );
            }

        ReallocateStringL( attr, *attr8 );
        if( aDelete )
            {
            CleanupStack::PopAndDestroy( attr8 );
            }

        // it is always true because of the conversion.
        aDelete = ETrue;
        }

    iNoRealError = EFalse;

    return attr;
    }

// -----------------------------------------------------------------------------
// CHttpDownload::GetString8AttributeL
// ?implementation_description
// (other items were commented in a header).
// -----------------------------------------------------------------------------
//
EXPORT_C HBufC8* CHttpDownload::GetString8AttributeL( THttpDownloadAttrib aAttribute, 
                                                      TBool& aDelete )
    {
    LOGGER_ENTERFN( "GetString8AttributeL" );
    CLOG_WRITE_1( "Attr(%d): %d", aAttribute );

    iNoRealError = ETrue;
    HBufC8* attr = NULL;
    HBufC* attr16 = NULL;

    aDelete = EFalse;

    switch( aAttribute )
        {
        case EDlAttrReqUrl:
            {
            attr = iUrl;
            }
            break;

        case EDlAttrRedirUlr:
            {
            attr = iRedirUrl;
            }
            break;

        case EDlAttrCurrentUrl:
            {
            attr = iCurrentUrl;
            }
            break;

        case EDlAttrRealm:
            {
            attr = iHttpRealm;
            }
            break;

        case EDlAttrUsername:
            {
            attr = iHttpUsername;
            }
            break;

        case EDlAttrProxyUsername:
            {
            attr = iHttpProxyUsername;
            }
            break;

        case EDlAttrContentType:
            {
            attr = iContentType;
            }
            break;

        case EDlAttrDDType:
            {
            attr = iDDType;
            }
            break;            

        case EDlAttrRequestHeaderAddon:
            {
            TChar colon( KColon );
            TInt32 length( 0 );

            GetIntAttributeL( EDlAttrRequestHeaderAddonLength, length );
            if( length )
                {
                attr = HBufC8::NewLC( length );

                for( TInt i = 0; i < iRequestHeaders->Count(); ++i )
                    {
                    TPtrC8 fieldName( *(*iRequestHeaders)[i]->FieldName() );
                    TPtrC8 fieldData( *(*iRequestHeaders)[i]->FieldRawData() );

                    attr->Des().Append( fieldName );
                    attr->Des().Append( colon );
                    attr->Des().Append( fieldData );
                    attr->Des().Append( KHttpFieldSeparator() );
                    }

                CleanupStack::Pop();
                aDelete = ETrue;
                }
            }
            break;

        case EDlAttrResponseCharSet:
        // Response headers
        case EDlAttrResponseAge:
        case EDlAttrResponseETag:
        case EDlAttrResponseLocation:
        case EDlAttrResponseRetryAfter:
        case EDlAttrResponseServer:
        case EDlAttrResponseVary:
            {
            for( TInt i = 0; KResponseHeaderConvTable[i][0]; ++i )
                {
                if( KResponseHeaderConvTable[i][0] == aAttribute )
                    {
                    attr = HeaderFieldL( iResponseHeaders, KResponseHeaderConvTable[i][1] );
                    }
                }
            }
            break;

        // Request headers
        case EDlAttrRequestAccept:
        case EDlAttrRequestAcceptCharSet:
        case EDlAttrRequestAcceptLanguage:
        case EDlAttrRequestExpect:
        case EDlAttrRequestFrom:
        case EDlAttrRequestHost:
        case EDlAttrRequestMaxForwards:
        case EDlAttrRequestPragma:
        case EDlAttrRequestReferer:
        case EDlAttrRequestUserAgent:
        case EDlAttrRequestVary:
            {
            for( TInt i = 0; KRequestHeaderConvTable[i][0]; ++i )
                {
                if( KRequestHeaderConvTable[i][0] == aAttribute )
                    {
                    attr = HeaderFieldL( iRequestHeaders, KRequestHeaderConvTable[i][1] );
                    break;
                    }
                }
            }
            break;

        // Entity header fields
        case EDlAttrEntityAllow:
        case EDlAttrEntityContentEncoding:
        case EDlAttrEntityContentLanguage:
        case EDlAttrEntityContentLocation:
        case EDlAttrEntityExpires:
        case EDlAttrEntityLastModified:
            {
            for( TInt i = 0; KEntityHeaderConvTable[i][0]; ++i )
                {
                if( KEntityHeaderConvTable[i][0] == aAttribute )
                    {
                    attr = HeaderFieldL( iEntityHeaders, KEntityHeaderConvTable[i][1] );
                    break;
                    }
                }
            for( TInt i = 0; KResponseHeaderConvTable[i][0]; ++i )
                {
                if( KResponseHeaderConvTable[i][0] == aAttribute )
                    {
                    attr = HeaderFieldL( iResponseHeaders, KResponseHeaderConvTable[i][1] );
                    }
                }
            }
            break;

        // General header fields
        case EDlAttrGeneralCacheControl:
        case EDlAttrGeneralDate:
        case EDlAttrGeneralPragma:
        case EDlAttrGeneralVia:
        case EDlAttrGeneralWarning:
            {
            for( TInt i = 0; KGeneralHeaderConvTable[i][0]; ++i )
                {
                if( KGeneralHeaderConvTable[i][0] == aAttribute )
                    {
                    attr = HeaderFieldL( iGeneralHeaders, KGeneralHeaderConvTable[i][1] );
                    break;
                    }
                }
            for( TInt i = 0; KResponseHeaderConvTable[i][0]; ++i )
                {
                if( KResponseHeaderConvTable[i][0] == aAttribute )
                    {
                    attr = HeaderFieldL( iResponseHeaders, KResponseHeaderConvTable[i][1] );
                    }
                }
            }
            break;

        case EDlAttrHashedMsgBody:
            { 
            attr = iHashedMsgBody;
            }
            break;
   
        case EDlAttrMediaType:
            {
            attr = iMediaType;
            }
            break;
            
        case EDlAttrMediaTypeBoundary:
            {
            attr = GetParamFromMediaTypeL( KBoundary() ).AllocL();
            aDelete = ETrue;
            }
            break;
            
        default:
            {
                {
                CLOG_WRITE_1( "Unknown string8 attrib: %d", aAttribute );
#ifdef __WINS__
            DMPanic( KErrArgument );
#else
            User::Leave( KErrArgument );
#endif
                }
            }
            break;
        }

    if( !attr && !attr16 )
        {
        CLOG_WRITE_1( "NULL attrib: %d", aAttribute );
        User::Leave( KErrNotFound );
        }

    if( attr16 )
        // it is an 8-bit attribute
        // need to be converted to 16-bits
        {
        if( aDelete )
            {
            CleanupStack::PushL( attr16 );
            }
        ReallocateStringL( attr, *attr16 );
        if( aDelete )
            {
            CleanupStack::PopAndDestroy( attr16 );
            }

        // it is always true because of the conversion.
        aDelete = ETrue;
        }

    iNoRealError = EFalse;

    return attr;
    }

// -----------------------------------------------------------------------------
// CHttpDownload::GetString8AttributeL
// ?implementation_description
// (other items were commented in a header).
// -----------------------------------------------------------------------------
//
EXPORT_C HBufC8* CHttpDownload::GetString8AttributeL( THttpDownloadAttrib aAttribute, 
                                                      TInt32& aMoIndex,
                                                      TBool& aDelete )
    {
    LOGGER_ENTERFN( "GetString8AttributeL" );
    CLOG_WRITE_1( "Attr(%d): %d", aAttribute );

	if (!iCodDlData)
    	{
    	return (KNullDesC8().AllocL());
    	}
    if ((aMoIndex <= KNonMoIndex) || (aMoIndex > iCodDlData->Count()))
    	{
    	User::Leave( KErrArgument );
    	}
    	
    CMediaDataBase* mediaData = (*iCodDlData)[aMoIndex];
    iNoRealError = ETrue;
    HBufC8* attr = NULL;
    HBufC* attr16 = NULL;

    aDelete = EFalse;

    switch( aAttribute )
        {
        case EDlAttrReqUrl:
            {
            attr = mediaData->Url().AllocL();
            aDelete = ETrue;
            }
            break;

        case EDlAttrRedirUlr:
            {
            attr = mediaData->RedirUrl().AllocL();
            aDelete = ETrue;
            }
            break;

        case EDlAttrContentType:
            {
            attr = mediaData->Type().AllocL();
            aDelete = ETrue;
            }
            break;
            
        default:
            {
                {
                CLOG_WRITE_1( "Unknown string8 attrib: %d", aAttribute );
#ifdef __WINS__
            DMPanic( KErrArgument );
#else
            User::Leave( KErrArgument );
#endif
                }
            }
            break;
        }

    if( !attr && !attr16 )
        {
        CLOG_WRITE_1( "NULL attrib: %d", aAttribute );
        User::Leave( KErrNotFound );
        }

    if( attr16 )
        // it is an 8-bit attribute
        // need to be converted to 16-bits
        {
        if( aDelete )
            {
            CleanupStack::PushL( attr16 );
            }
        ReallocateStringL( attr, *attr16 );
        if( aDelete )
            {
            CleanupStack::PopAndDestroy( attr16 );
            }

        // it is always true because of the conversion.
        aDelete = ETrue;
        }

    iNoRealError = EFalse;

    return attr;
    }

// -----------------------------------------------------------------------------
// CHttpDownload::GetFileHandleAttributeL
// ?implementation_description
// (other items were commented in a header).
// -----------------------------------------------------------------------------
//
EXPORT_C RFile* CHttpDownload::GetFileHandleAttributeL()
    {
    LOGGER_ENTERFN( "GetFileHandleAttributeL" );
    
    if( !iStorage->File() )
        // destination file is not opened
        {
        User::Leave( KErrArgument );
        }

    return iStorage->File();
    }

// -----------------------------------------------------------------------------
// CHttpDownload::SetIntAttributeL
// ?implementation_description
// (other items were commented in a header).
// -----------------------------------------------------------------------------
//
EXPORT_C void CHttpDownload::SetIntAttributeL( THttpDownloadAttrib aAttribute, 
                                               const TInt32 aValue )
    {
    LOGGER_ENTERFN( "SetIntAttributeL" );
    CLOG_WRITE_2( "Attr(%d): %d", aAttribute, aValue );
    TBool store( ETrue );

    iNoRealError = ETrue;

    switch( aAttribute )
        {
        case EDlAttrUserData:
            {
            iUserData = aValue;
            }
            break;

        case EDlAttrAction:
        	{
            TBool PdSupported(EFalse);
            
            iAction = (THttpDownloadMgrAction)aValue;
            
            if(iClAppInstance)
            	{
            	TRAP_IGNORE(iClAppInstance->GetBoolAttributeL(EDlMgrProgressiveDownload, PdSupported));
            	}

            if(!PdSupported)
                {
                iAction = (THttpDownloadMgrAction)(iAction & ~(EPdLaunch));
                }
        	}
            break;

        case EDlAttrPort:
            iPort = aValue;
            break;

        case EDlAttrRestartAction:
            iRestartAction = (THttpRestartActions)aValue;
            break;

        case EDlAttrAuthScheme:
            {
            if( iContinueDownload && iDlState == EHttpDlMultipleMOStarted )
                {
                iAuthScheme = aValue;
                }
            }
            break;

        case EDlAttrLength:
            {
            if( (iContinueDownload && iDlState == EHttpDlMultipleMOStarted) ||
                ( iCodDownload && iDlState == EHttpDlInprogress ) )
                {
                iStorage->SetLength( aValue );
                }
            else
                {
                store = EFalse;
                }
            }
            break;

        case EDlAttrMultipleMOLength:
            {
            iMoLength = aValue;            
            }
            break;
            
        case EDlAttrDownloadedSize:
            {
            if( (iCodDownload || iContinueDownload) && iDlState == EHttpDlInprogress )
                {            
                iStorage->SetDownloadedSize( aValue );
                // Calculate downloaded size of current media object from
                // album downloaded size.
                TInt dlSize = iStorage->DownloadedSize();
                if( iCodDlData )
                    {
                    for (TInt index = 0; index < iCodDlData->Count() ; ++index)
                    	{               	
                    	if( iActiveDownload - 1 == index )
                    	    {
                    	    //the size of active download has already been taken into account
                    	    continue;
                    	    }
                    	CMediaDataBase* moData = (*iCodDlData)[index+1];
                    	if ((moData->State() == ESucceeded) || (moData->State() == EInProgress))
                    		dlSize += moData->DownloadedSize();
                    	}
                    iStorage->SetMoDownloadedSize(dlSize);                    	                
                    }                
                if( iStorage->Length() != KDefaultContentLength &&
                    iStorage->DownloadedSize() > iStorage->Length() )
                    // we don't know actually how many bytes will come down.
                    {
                    CLOG_WRITE( "Length modified" );
                    iStorage->SetLength( KDefaultContentLength );
                    StoreDownloadInfoL();
                    }                             
                TriggerEvent( EHttpDlInprogress, EHttpProgResponseBodyReceived );
                }
                
            store = EFalse;
            }
            break;

        case EDlAttrSucceeded:
            {
            if(!aValue)
                DownloadSucceededL();
            else
                iMoDownloadCompleted = ETrue;//Download of MO has been Completed so change State ,But PD is on           
                                         //So MOVE will be issued by PD Client 

            store = EFalse;
            }
            break;

        case EDlAttrFailed:
            {
            // This is an exeption!
            iNoRealError = EFalse;
            OnError( aValue, ETransactionFailed );
            store = EFalse;
            }
            break;

        case EDlAttrDefaultEvent:
            {
            }
            break;
            
        case EDlAttrMethod:
            {
            if( iContinueDownload && iDlState == EHttpDlMultipleMOStarted &&
                ( aValue == EMethodGET ||
                  aValue == EMethodPOST ||
                  aValue == EMethodHEAD ) )
                {
                iMethod = (THttpMethod)aValue;
                }
            else
                {
                User::Leave( KErrArgument );
                }
            }
            break;

        case EDlAttrFotaPckgId:
            {     
            iFotaPckgId = aValue;
            store = EFalse;
            }
            break;
        case EDlAttrActiveDownload:
            {
            iActiveDownload = aValue;
            
            // Active MO changed. Notify clients.
           	TriggerEvent( EHttpDlCreated, EHttpProgNone );
            }
            break;
            
        case EDlAttrActivePlayedDownload:
            {
            iActivePlayedDownload = aValue;
            }
            
            break;
        default:
            {
#ifdef __WINS__
            DMPanic( KErrArgument );
#else
            User::Leave( KErrArgument );
#endif
            }
            break;
        }

    UpdatePausable();

    iNoRealError = EFalse;
    
    if( store )
        {
        StoreDownloadInfoL();
        }
    }

// -----------------------------------------------------------------------------
// CHttpDownload::SetBoolAttributeL
// ?implementation_description
// (other items were commented in a header).
// -----------------------------------------------------------------------------
//
EXPORT_C void CHttpDownload::SetBoolAttributeL( THttpDownloadAttrib aAttribute, 
								                const TBool aValue )
    {
    LOGGER_ENTERFN( "SetBoolAttributeL" );
    CLOG_WRITE_2( "Attr(%d): %d", aAttribute, aValue );
    TBool store( ETrue );

    iNoRealError = ETrue;

    switch( aAttribute )
        {
        case EDlAttrNoContentTypeCheck:
            {
            iNoContentTypeCheck = aValue;
            }
            break;

        case EDlAttrDisconnectOnReset:
            {
            iDisconnectOnReset = aValue;
            }
            break;

        case EDlAttrDisconnectOnPause:
            {
            iDisconnectOnPause = aValue;
            }
            break;

        case EDlAttrContinue:
            {
            if( iDlState == EHttpDlMultipleMOStarted )
                {
                iContinueDownload = aValue;
                }
            else
                {
                User::Leave( KErrInUse );
                }
                
            store = EFalse;
            }
            break;

        case EDlAttrHidden:
            {
            iHidden = aValue;
            }
            break;

        case EDlAttrSilent:
            {
            iSilentMode = aValue;
            }
            break;

        case EDlAttrCodDownload:
            {
            SetCodFlag( aValue );
            }
            break;
            
        case EDlAttrProgressive:
            {
            TBool PdSupported(EFalse);
            
            if(iClAppInstance)
            	{
            	TRAP_IGNORE(iClAppInstance->GetBoolAttributeL(EDlMgrProgressiveDownload, PdSupported));
            	}

            if(PdSupported)
                {
                iStorage->SetProgressiveMode( aValue );	
                
                if(!aValue)
                    {
                    iActivePlayedDownload = 0;
                    }

                if (iCodDlData)                
                	{
                	// Update for Active media object.
	                TInt active = iActiveDownload;
	                CMediaDataBase* mediaData = (*iCodDlData)[active];
	                mediaData->SetProgressiveDownload( aValue );
                	}
                	
                if( iProgState != EHttpProgMovingContentFile )
                    {
                    TriggerEvent( iDlState, aValue ? EHttpDlProgProgressive : EHttpDlProgNonProgressive);
                    }
                }
            else
                {
				TriggerEvent( iDlState, EHttpDlProgNonProgressive);
				}
            }
            break;
            
        case EDlAttrCodDescriptorAccepted:
            {
            TriggerEvent( EHttpDlInprogress, EHttpProgCodDescriptorAccepted );
            }
            break;
            
        case EDlAttrCodLoadEnd:
            {
            SetDownloadStatus(EHttpProgCodLoadEnd,EHttpDlInprogress);
            }
            break;

        case EDlAttrCodPdAvailable:
            {
            iCodPdAvailable = aValue;
            TriggerEvent( EHttpDlInprogress, EHttpProgCodPdAvailable );
            }
            break;
            
        case EDlAttrDestRemovable:
            {
            if( iCodDownload )
                {
                iStorage->SetRemovableDest( aValue );

                if (iCodDlData)                
                	{
	                // Update for Active media object.
	                TInt active = iActiveDownload;
	                CMediaDataBase* mediaData = (*iCodDlData)[active];
	                mediaData->SetDesRemovable( aValue );
                	}
                }
            }
            break;

        case EDlAttrDownloadUpdatedDDUri:
            {
            iUpdatedDDUriSet = aValue;
			}
            break;


        case EDlAttrCodPausable:
            {
            iPausable = aValue;
			
			// Update for Active media object.
            TInt active = iActiveDownload;
            CMediaDataBase* mediaData = (*iCodDlData)[active];
            mediaData->SetPausable( aValue );
			
            // inform client about change
            TriggerEvent( iPausable ? EHttpDlPausable : EHttpDlNonPausable );
			}
            break;
            
                    
        default:
#ifdef __WINS__
            DMPanic( KErrArgument );
#else
            User::Leave( KErrArgument );
#endif
            break;
        }

    UpdatePausable();
    
    iNoRealError = EFalse;

    if( store )
        {
        StoreDownloadInfoL();
        }
    }



// -----------------------------------------------------------------------------
// CHttpDownload::SetStringAttributeL
// ?implementation_description
// (other items were commented in a header).
// -----------------------------------------------------------------------------
//
EXPORT_C void CHttpDownload::SetStringAttributeL( THttpDownloadAttrib aAttribute, const TInt32 aMOIndex,
								                  const TDesC16& aValue )
    {
    LOGGER_ENTERFN( "SetStringAttributeL" );
    CLOG_WRITE_2( "Attr(%d - %d)", aAttribute, aValue.Length () );

    iNoRealError = ETrue;

    CheckAttribMaxLengthL( aAttribute, aValue );

    switch( aAttribute )
        {
        case EDlAttrDestFilename:
            {
            TBool updateFName = EFalse;
            
            if( iDlState == EHttpDlMultipleMOStarted ||
                iDlState == EHttpDlMultipleMOCompleted ||
                iCodDownload )
                // cannot set this attribute while 
                // download is in progress
                {
                if( !aValue.Length() )
                    {
                    updateFName = ETrue;
                    }
                else if( iClientApp->Engine()->Fs().IsValidName( aValue ) )
                    {
                    TUint attrib;
                    TInt attErr = iClientApp->Engine()->Fs().Att( aValue, attrib );

                    if( (attErr == KErrNone && !(attrib & KEntryAttDir)) ||
                        attErr == KErrNotFound )
                        // File exists and not directory or not exists
                        {
                        updateFName = ETrue;
                        }
                    else
                        {
                        User::Leave( KErrArgument ); 
                        }
                    }
                else
                    // Invalid filename passed
                    {
                    User::Leave( KErrArgument );
                    }
                }
            else
                {
                User::Leave( KErrInUse );
                }
            
            if (updateFName)
            	{
                iStorage->UpdateDestinationFilenameL( aValue, ETrue );
                if (iCodDlData)                
                	{
	            	CMediaDataBase* mediaData = (*iCodDlData)[aMOIndex];
	            	mediaData->SetDestFilenameL( aValue );
	            	}
            	}
            }
            break;
        }
    }
    
    
// -----------------------------------------------------------------------------
// CHttpDownload::SetStringAttributeL
// ?implementation_description
// (other items were commented in a header).
// -----------------------------------------------------------------------------
//
EXPORT_C void CHttpDownload::SetStringAttributeL( THttpDownloadAttrib aAttribute, 
								                  const TDesC16& aValue )
    {
    LOGGER_ENTERFN( "SetStringAttributeL" );
    CLOG_WRITE_2( "Attr(%d - %d)", aAttribute, aValue.Length () );
    TBool store( ETrue );

    iNoRealError = ETrue;

    CheckAttribMaxLengthL( aAttribute, aValue );

    switch( aAttribute )
        {
        case EDlAttrReqUrl:
            // this is only for internal testing usage!!!
            {
            if( iDlState == EHttpDlMultipleMOStarted )
                {
                ReallocateStringL( iUrl, aValue, KMaxUrlLength );
                ParseRequestedUrlL();   // iCurrentUrl is initialized there
                ParseDownloadNameL();
                }
            }
            break;

        case EDlAttrContentType:
            {
            if( iDlState == EHttpDlInprogress )
                {
                CLOG_WRITE( "EDlAttrContentType updated" );
                ReallocateStringL( iContentType, aValue, KMaxContentTypeLength );
                TriggerEvent( EHttpDlInprogress, EHttpProgContentTypeChanged );
                
                // Update for Active media object.
                HBufC8* type8 = HBufC8::NewLC( aValue.Length() );
                type8->Des().Copy( aValue );

                if (iCodDlData)                
                	{
	                TInt active = iActiveDownload;
	                CMediaDataBase* mediaData = (*iCodDlData)[active];
	                mediaData->SetTypeL( type8->Des() );
	                CleanupStack::PopAndDestroy( type8 );
                	}
            	}
            }
            break;

        case EDlAttrRealm:
            {
            if( iContinueDownload && iDlState == EHttpDlMultipleMOStarted )
                {
                ReallocateStringL( iHttpRealm, aValue, KMaxRealmLength );
                }
                
            store = EFalse;
            }
            break;

        case EDlAttrUsername:
            {
            ReallocateStringL( iHttpUsername, aValue, KMaxDefAttrLength );
            store = EFalse;
            }
            break;

        case EDlAttrPassword:
            {
            ReallocateStringL( iHttpPassword, aValue, KMaxDefAttrLength );
            store = EFalse;
            }
            break;

        case EDlAttrProxyRealm:
            {
            if( iContinueDownload && iDlState == EHttpDlMultipleMOStarted )
                {
                ReallocateStringL( iHttpProxyRealm, aValue, KMaxRealmLength );
                }
            store = EFalse;
            }
            break;

        case EDlAttrProxyUsername:
            {
            ReallocateStringL( iHttpProxyUsername, aValue, KMaxDefAttrLength );
            store = EFalse;
            }
            break;

        case EDlAttrProxyPassword:
            {
            ReallocateStringL( iHttpProxyPassword, aValue, KMaxDefAttrLength );
            store = EFalse;
            }
            break;

        case EDlAttrDestFilename:
            {
            TBool updateFName = EFalse;
            
            if( iDlState == EHttpDlMultipleMOStarted ||
                iDlState == EHttpDlMultipleMOCompleted ||
                iCodDownload )
                // cannot set this attribute while 
                // download is in progress
                {
                if( !aValue.Length() )
                    {
                    updateFName = ETrue;
                    }
                else if( iClientApp->Engine()->Fs().IsValidName( aValue ) )
                    {
                    TUint attrib;
                    TInt attErr = iClientApp->Engine()->Fs().Att( aValue, attrib );

                    if( (attErr == KErrNone && !(attrib & KEntryAttDir)) ||
                        attErr == KErrNotFound )
                        // File exists and not directory or not exists
                        {
                        updateFName = ETrue;
                        }
                    else
                        {
                        User::Leave( KErrArgument ); 
                        }
                    }
                else
                    // Invalid filename passed
                    {
                    User::Leave( KErrArgument );
                    }
                }
            else
                {
                User::Leave( KErrInUse );
                }
            
            if (updateFName)
            	{
            	iStorage->UpdateDestinationFilenameL( aValue, ETrue );
            	
                if (iCodDlData)                
                	{
                    TInt moIndex(0);
                    if( iActiveDownload != iActivePlayedDownload && iStorage->ProgressiveDownload() )
                        {
                        //MP has set the Destination File Name
                        moIndex = iActivePlayedDownload;
                        }
                    else
                        {
                        // Update for Active media object.
                    	moIndex = iActiveDownload;                        
                        }
	            	CMediaDataBase* mediaData = (*iCodDlData)[moIndex];
	            	mediaData->SetDestFilenameL( aValue );
	            	}
            	}
            }
            break;

        case EDlAttrLocalFileName:
			{
			iStorage->SetLocalFilenameL(aValue);
			}
			break;

        case EDlAttrRequestHeaderAddon:
            {
            if( aValue.Length() )
                {
                HBufC8* value = HBufC8::NewLC( aValue.Length() );

                value->Des().Copy( aValue );
                ParseRequestHeaderAddOnL( *value );

                CleanupStack::PopAndDestroy( value );
                }
            }
            break;

        case EDlAttrResponseHeader:
            {
            if( iContinueDownload && iDlState == EHttpDlMultipleMOStarted )
                {
                HBufC8* temp = HBufC8::NewLC( aValue.Length() );
                temp->Des().Copy( aValue );

                ContinueDownloadStoreResponseHeaderL( *temp );

                CleanupStack::PopAndDestroy( temp );
                }
            }
            break;

        case EDlAttrName:
            {
            if( iCodDownload )
                {
                SetDownloadNameL( aValue );

                if (iCodDlData)
	                {                
	                // Update for Active media object.
	            	TInt active = iActiveDownload;
	            	CMediaDataBase* mediaData = (*iCodDlData)[active];
	            	mediaData->SetNameL( aValue );
	                }
                }
            }
            break;

        // Request headers
        case EDlAttrRequestAccept:
        case EDlAttrRequestAcceptCharSet:
        case EDlAttrRequestAcceptLanguage:
        case EDlAttrRequestExpect:
        case EDlAttrRequestFrom:
        case EDlAttrRequestHost:
        case EDlAttrRequestMaxForwards:
        case EDlAttrRequestPragma:
        case EDlAttrRequestReferer:
        case EDlAttrRequestUserAgent:
        case EDlAttrRequestVary:
            {
            HBufC8* value = HBufC8::NewLC( aValue.Length() );

            AddHeaderL( aAttribute, *value, KRequestHeaderConvTable, iRequestHeaders );

            CleanupStack::PopAndDestroy( value );
            }
            break;

        // General header fields
        case EDlAttrGeneralCacheControl:
        case EDlAttrGeneralPragma:
            {
            HBufC8* value = HBufC8::NewLC( aValue.Length() );

            AddHeaderL( aAttribute, *value, KGeneralHeaderConvTable, iGeneralHeaders );

            CleanupStack::PopAndDestroy( value );
            }
            break;

        default:
#ifdef __WINS__
            DMPanic( KErrArgument );
#else
            User::Leave( KErrArgument );
#endif
            break;
        }

    UpdatePausable();

    iNoRealError = EFalse;

    if( store )
        {
        StoreDownloadInfoL();
        }
    }

// -----------------------------------------------------------------------------
// CHttpDownload::SetStringAttributeL
// ?implementation_description
// (other items were commented in a header).
// -----------------------------------------------------------------------------
//
EXPORT_C void CHttpDownload::SetStringAttributeL( THttpDownloadAttrib aAttribute, 
								                  const TDesC8& aValue )
    {
    LOGGER_ENTERFN( "SetStringAttributeL(8)" );
    CLOG_WRITE_2( "Attr(%d - %d)", aAttribute, aValue.Length () );
    TBool store( ETrue );

    iNoRealError = ETrue;

    CheckAttribMaxLengthL( aAttribute, aValue );

    switch( aAttribute )
        {
        case EDlAttrReqUrl:
            // this is only for internal testing usage!!!
            {
            if( iDlState == EHttpDlMultipleMOStarted )
                {
                ReallocateStringL( iUrl, aValue, KMaxUrlLength );
                ParseRequestedUrlL();   // iCurrentUrl is initialized there
                ParseDownloadNameL();
                }
            }
            break;

        case EDlAttrContentType:
            {
            if( iDlState == EHttpDlInprogress )
                {
                ReallocateStringL( iContentType, aValue, KMaxContentTypeLength );
                TriggerEvent( EHttpDlInprogress, EHttpProgContentTypeChanged );
                }
            else if (iDlState == EHttpDlMultipleMOCompleted )//Allow to change content type even if state is completed
                {
                ReallocateStringL( iContentType, aValue, KMaxContentTypeLength );                            
                //No need to trigger any event
                }                
            }
            break;

        case EDlAttrRealm:
            {
            if( iContinueDownload && iDlState == EHttpDlMultipleMOStarted )
                {
                ReallocateStringL( iHttpRealm, aValue, KMaxRealmLength );
                }
            store = EFalse;
            }
            break;

        case EDlAttrUsername:
            {
            ReallocateStringL( iHttpUsername, aValue, KMaxDefAttrLength );
            store = EFalse;
            }
            break;

        case EDlAttrPassword:
            {
            ReallocateStringL( iHttpPassword, aValue, KMaxDefAttrLength );
            store = EFalse;
            }
            break;

        case EDlAttrProxyRealm:
            {
            if( iContinueDownload && iDlState == EHttpDlMultipleMOStarted )
                {
                ReallocateStringL( iHttpProxyRealm, aValue, KMaxRealmLength );
                }
            store = EFalse;
            }
            break;

        case EDlAttrProxyUsername:
            {
            ReallocateStringL( iHttpProxyUsername, aValue, KMaxDefAttrLength );
            store = EFalse;
            }
            break;

        case EDlAttrProxyPassword:
            {
            ReallocateStringL( iHttpProxyPassword, aValue, KMaxDefAttrLength );
            store = EFalse;
            }
            break;

        case EDlAttrRequestHeaderAddon:
            {
            if( aValue.Length() )
                {
                ParseRequestHeaderAddOnL( aValue );
                }
            }
            break;

        case EDlAttrResponseHeader:
            {
            if( iContinueDownload && iDlState == EHttpDlMultipleMOStarted )
                {
                ContinueDownloadStoreResponseHeaderL( aValue );
                }
            }
            break;

        // Request headers
        case EDlAttrRequestAccept:
        case EDlAttrRequestAcceptCharSet:
        case EDlAttrRequestAcceptLanguage:
        case EDlAttrRequestExpect:
        case EDlAttrRequestFrom:
        case EDlAttrRequestHost:
        case EDlAttrRequestMaxForwards:
        case EDlAttrRequestPragma:
        case EDlAttrRequestReferer:
        case EDlAttrRequestUserAgent:
        case EDlAttrRequestVary:
            {
            AddHeaderL( aAttribute, aValue, KRequestHeaderConvTable, iRequestHeaders );
            }
            break;

        // General header fields
        case EDlAttrGeneralCacheControl:
        case EDlAttrGeneralPragma:
            {
            AddHeaderL( aAttribute, aValue, KGeneralHeaderConvTable, iGeneralHeaders );
            }
            break;

        case EDlAttrHashedMsgBody:
            {
            ReallocateStringL( iHashedMsgBody, aValue, KHashLength );
            }
            break;
   
        case EDlAttrRedirectedPermanently:
            {
            RedirectedPermanentlyL( aValue );
            
            if (iCodDlData)
	            {                
	            // Update for Active media object.
	            TInt active = iActiveDownload;
	            CMediaDataBase* mediaData = (*iCodDlData)[active];
	            if (!mediaData->Redirected())
	            	mediaData->SetRedirUrlL( aValue );
	            }
            }
            break;
            
        case EDlAttrRedirectedTemporary:
            {
            RedirectedTemporaryL( aValue );
            
            if (iCodDlData)
	            {                
	            // Update for Active media object.
	            TInt active = iActiveDownload;
	            CMediaDataBase* mediaData = (*iCodDlData)[active];
	            mediaData->SetRedirected( ETrue );
	            }
            }
            break;
 
        case EDlAttrContinueBody:
            {
            iNoRealError = EFalse;
            ResponseBodyReceivedL( aValue );
            store = EFalse;
            }
            break;

        case EDlAttrUpdatedDDUri:
            {
            ReallocateStringL( iUrl, aValue, KMaxUrlLength );
            }
            break;

        default:
#ifdef __WINS__
            DMPanic( KErrArgument );
#else
            User::Leave( KErrArgument );
#endif
            break;
        }
    
    UpdatePausable();
    
    iNoRealError = EFalse;

    if( store )
        {
        StoreDownloadInfoL();
        }
    }

// -----------------------------------------------------------------------------
// CHttpDownload::SetStringAttributeL
// ?implementation_description
// (other items were commented in a header).
// -----------------------------------------------------------------------------
//
EXPORT_C void CHttpDownload::SetFileHandleAttributeL( RFile* aFile )
    {
    LOGGER_ENTERFN( "SetFileHandleAttributeL" );
    
    iStorage->AdoptFileHandleL( aFile );
    }

// -----------------------------------------------------------------------------
// CHttpDownload::SetDownloadDataAttributeL
// ?implementation_description
// (other items were commented in a header).
// -----------------------------------------------------------------------------
//
EXPORT_C void CHttpDownload::SetDownloadDataAttributeL( HBufC8* dlData )
	{
    LOGGER_ENTERFN( "SetDownloadDataAttributeL" );
    
    if (iCodDlData)
        {
    	delete iCodDlData;	
        iCodDlData = NULL;
        }
    	
    iCodDlData = CDownloadDataServ::NewL(*dlData);
    TInt downloadedSize = 0 ;
    TBool activeDownloadChanged = EFalse;
    
    iMoLength = 0 ;
    for ( TInt i = 1; i <= iCodDlData->Count() ; ++i )
        {
        downloadedSize = downloadedSize + (*iCodDlData)[i]->DownloadedSize();
        iMoLength += (*iCodDlData)[i]->Size();

        // Below code is executed only when download is paused.
        // Set the ActiveDownload, DownloadedSize and Length.
        if (((*iCodDlData)[i]->State() == EInProgress) && !activeDownloadChanged)
            {
            iActiveDownload = i;
            iStorage->SetDownloadedSize( (*iCodDlData)[i]->DownloadedSize() );
            iStorage->SetLength( (*iCodDlData)[i]->Size() );
            activeDownloadChanged = ETrue;
            }
        }
    iStorage->SetMoDownloadedSize( downloadedSize );                
    }
// -----------------------------------------------------------------------------
// CHttpDownload::SetTrackDataAttributeL
// ?implementation_description
// (other items were commented in a header).
// -----------------------------------------------------------------------------
//
EXPORT_C void CHttpDownload::SetTrackDataAttributeL( TInt aIndex, HBufC8* dlData )
    {
    LOGGER_ENTERFN( "SetTrackDataAttributeL" );
    
	if (iCodDlData)
    	{
    	CMediaDataServ* updatedMediaData = CMediaDataServ::NewL(*dlData);
    	CMediaDataBase* mediaData = (*iCodDlData)[aIndex];
    	mediaData->SetNameL(updatedMediaData->Name());
    	mediaData->SetUrlL(updatedMediaData->Url());
    	mediaData->SetSize(updatedMediaData->Size());
    	mediaData->SetIconL( updatedMediaData->Icon() );
	    mediaData->SetSourceUriL( updatedMediaData->SourceUri() );
	    mediaData->SetProgressiveDownload( updatedMediaData->ProgressiveDownload() );
	    mediaData->SetState( updatedMediaData->State() );
	    mediaData->SetResult( updatedMediaData->Result() );
	    mediaData->SetDownloadedSize( updatedMediaData->DownloadedSize() );
	    mediaData->SetDestFilenameL( updatedMediaData->DestFilename() );
	    mediaData->SetTempFilenameL( updatedMediaData->DestFilename() );
	    	    
    	mediaData->ResetTypes();
    	for (TInt type = 0; type < updatedMediaData->TypesCount(); ++type)
        	mediaData->AddTypeL( updatedMediaData->Types().MdcaPoint(type) );
        
        TInt result = updatedMediaData->Result();
        
        //New track download Begins.Hence make track size as 0
        //iStorage->SetDownloadedSize ( 0 );
        // Active MO completed OR failed. Notify clients.
        if (mediaData->Result() == 0)
            {
            iGlobalErrorId = 0;
	        iLastError = 0;
        	TriggerEvent( EHttpDlCompleted, EHttpProgNone );
            }
        else
            {
            // Set the error codes for single track albums
            if(iCodDlData->Count() == 1)
                {
                if ( result <= -1000 )
	        	    {
	        	    iGlobalErrorId = KErrGeneral;
	        	    iLastError = (THttpDownloadMgrError)result;
	           	    }
	            else
	        	    {
	        	    iGlobalErrorId = result;
	        	    iLastError = EGeneral;
	           	    }
                }
    	    TriggerEvent( EHttpDlFailed, EHttpProgNone );
            }
    	}
    }
// -----------------------------------------------------------------------------
// CHttpDownload::ClientAppInstance
// ?implementation_description
// (other items were commented in a header).
// -----------------------------------------------------------------------------
//
EXPORT_C CHttpClientAppInstance* CHttpDownload::ClientAppInstance() const
    {
    return iClAppInstance;
    }

// -----------------------------------------------------------------------------
// CHttpDownload::OnError
// ?implementation_description
// (other items were commented in a header).
// -----------------------------------------------------------------------------
//
EXPORT_C void CHttpDownload::OnError( TInt aError,
                                      THttpDownloadMgrError aDlError )
    {
    LOGGER_ENTERFN( "OnError" );
    CLOG_WRITE_2( "OnError1: %d - %d", aError, aDlError );

    if( iNoRealError )
        // Leave occured in Get/Set function. This leave must NOT stop
        // download process.
        {
        CLOG_WRITE( "No real error" );
        iNoRealError = EFalse;

        return;
        }    
    
    if( iCodDlData && iCodDlData->Count() > 1 )
        {
        if( aDlError == KErrMultipeObjectDownloadFailed )
            {
            //Permanently failed error in CodHandler
            //Delete the download
            SetDownloadStatus( EHttpProgNone,
                   EHttpDlMultipleMOFailed,
                   aDlError,
                   aError );            
            return;                       
            } 
        else
            {
            SetDownloadStatus( EHttpProgNone,
                               EHttpDlPaused,
                               aDlError,
                               aError );
            return;                                           
            
            }
        }

    if( iDlState < EHttpDlCreated )
        // error occured during download object construction -> nothing to do here
        {
        return;
        }


    //For COD Downloads, the error code may be set from COD handler
    //In that case if the download is paused just set the global and download error
    
    if( iCodDownload && iDlState == EHttpDlPaused )  
        {
        iLastError = aDlError;
        iGlobalErrorId = aError;
        TRAP_IGNORE( StoreDownloadInfoL() );
        return;
        }


    CancelTransaction();
    Cancel();
    Disconnect();
    // forget downloaded but not persisted content in case of OOM
    CHttpStorage::TFileCloseOperation closeOp = CHttpStorage::EKeepFile;
    if ( !Pausable() && ( iCodDlData && iCodDlData->Count() == 1 ) )
        {
        closeOp = CHttpStorage::EReplaceFile;
        }
        
    iStorage->CloseDestinationFile( closeOp );
    CLOG_WRITE_1( "OnError1 : iDlState : %d ", iDlState );

    if( iDlState != EHttpDlMultipleMOFailed )
        {

        // HTTP error code range (-7200 to -7399)
        if((aError <= KHttpErrorBase && aError >= KHttpErrorBase - 199)||
            aError == KErrConnectionTerminated ||
            aError == KErrCannotFindProtocol )
        	{
            if(!iPausable)
                {
                TriggerEvent( EHttpDlNonPausableNetworkLoss );
                }
            }

        if( aError == KErrHttpPartialResponseReceived )
            {
            //Partial response has been received and connection has been disconnected. This error will be 
            //propagated to the client only, if the HTTP:ENotifyOnDisconnect property is set with a value
            //HTTP::EEnableDisconnectNotification
            
            //This error code was cancelling the pausable download. This error shud be ignored to keep the
            //paused download.
            //TSW Err ID : SXUU-77SRWL
            
            SetDownloadStatus( EHttpProgNone,
                               EHttpDlPaused,
                               aDlError,
                               aError );            

            }
        else if( aDlError == EConnectionFailed && iPausable)
            {
            //Whenever connection error occurs and download can be paused.
            //Keep the download in paused state.
            SetDownloadStatus( EHttpProgNone,
                               EHttpDlPaused,
                               aDlError,
                               aError );               
            }
        else if ( aDlError == EMMCRemoved )
            {
            // MMC removed. Pause the download.
            SetDownloadStatus( EHttpProgNone,
                               EHttpDlPaused,
                               aDlError,
                               aError );
            }
        else
            {

            SetDownloadStatus( EHttpProgNone,
                               EHttpDlMultipleMOFailed,
                               aDlError,
                               aError );
            if(!iCodDlData)
                {
              	TriggerEvent( EHttpDlFailed, EHttpProgNone );
              	}
            }
        }
    else if( ( EHttpDlMultipleMOFailed == iDlState ) && iCodDownload )
        {
        TriggerEvent( EHttpDlMultipleMOFailed );
        }

    TRAP_IGNORE( StoreDownloadInfoL() );
    }


// -----------------------------------------------------------------------------
// CHttpDownload::DetachClientInstance
// ?implementation_description
// (other items were commented in a header).
// -----------------------------------------------------------------------------
//
EXPORT_C TBool CHttpDownload::DetachClientInstance( CHttpClientAppInstance* aInstance )
    {
    if( iClAppInstance == aInstance )
        {
        iClAppInstance = NULL;
        }
    else if( iPDClAppInstance == aInstance )
        {
        iPDClAppInstance = NULL;
        }
        
    return (iPDClAppInstance || iClAppInstance);
    }
    
    
// -----------------------------------------------------------------------------
// CHttpDownload::ClientApp
// ?implementation_description
// (other items were commented in a header).
// -----------------------------------------------------------------------------
//
CHttpClientApp* CHttpDownload::ClientApp() const
    {
    return iClientApp;
    }

// -----------------------------------------------------------------------------
// CHttpDownload::PDClientAppInstance
// ?implementation_description
// (other items were commented in a header).
// -----------------------------------------------------------------------------
//
CHttpClientAppInstance* CHttpDownload::PDClientAppInstance() const
    {
    return iPDClAppInstance;
    }

// -----------------------------------------------------------------------------
// CHttpDownload::Id
// ?implementation_description
// (other items were commented in a header).
// -----------------------------------------------------------------------------
//
TInt CHttpDownload::Id() const
    {
    return iId;
    }

// -----------------------------------------------------------------------------
// CHttpDownload::State
// ?implementation_description
// (other items were commented in a header).
// -----------------------------------------------------------------------------
//
THttpDownloadState CHttpDownload::State() const
    {
    return iDlState;
    }

// -----------------------------------------------------------------------------
// CHttpDownload::ProgState
// ?implementation_description
// (other items were commented in a header).
// -----------------------------------------------------------------------------
//
THttpProgressState CHttpDownload::ProgState() const
    {
    return iProgState;
    }

// -----------------------------------------------------------------------------
// CHttpDownload::ConnHandler
// ?implementation_description
// (other items were commented in a header).
// -----------------------------------------------------------------------------
//
CHttpConnHandler* CHttpDownload::ConnHandler() const
    {
    return iConnHandler;
    }

// -----------------------------------------------------------------------------
// CHttpDownload::NoMedia
// ?implementation_description
// (other items were commented in a header).
// -----------------------------------------------------------------------------
//
TBool CHttpDownload::NoMedia() const
    {
    return iNoMedia;
    }

// -----------------------------------------------------------------------------
// CHttpDownload::MediaRemoved
// ?implementation_description
// (other items were commented in a header).
// -----------------------------------------------------------------------------
//
void CHttpDownload::MediaRemoved( TUint aUid, TBool aDontCheckMediaUid )
    {
    LOGGER_ENTERFN( "MediaRemoved" );
    CLOG_WRITE_3( "Uid: %d, dontCheck: %d, iNoMedia: %d", 
                        aUid, 
                        aDontCheckMediaUid, 
                        iNoMedia );

    if( iNoMedia )
        // it is already known for us.
        {
        CLOG_WRITE("already know it");
        return;
        }

    if( !aDontCheckMediaUid && iStorage->GetDestinationDriveId() != aUid )
        // destination drive is not media card
        {
        CLOG_WRITE("who cares");
        return;
        }

    iNoMedia = ETrue;

    TRAP_IGNORE( InternalPauseL() );

    TriggerEvent( EHttpDlMediaRemoved );
    
    if( iDlState == EHttpDlInprogress )
        // it's happened during the download process
        // in case of e.g completed download it's not error
        {
        OnError( KErrGeneral, EMMCRemoved );
        }
    
    TRAP_IGNORE( StoreDownloadInfoL() );
    }

// -----------------------------------------------------------------------------
// CHttpDownload::MediaInserted
// ?implementation_description
// (other items were commented in a header).
// -----------------------------------------------------------------------------
//
void CHttpDownload::MediaInserted( TUint aUid )
    {
    LOGGER_ENTERFN( "MediaInserted" );

    if( iStorage->GetDestinationDriveId() != aUid )
        // this is not our media card
        {
        return;
        }

    iNoMedia = EFalse;
    TriggerEvent( EHttpDlMediaInserted );
    }
    
// -----------------------------------------------------------------------------
// CHttpDownload::GetDestinationDriveID
// ?implementation_description
// (other items were commented in a header).
// -----------------------------------------------------------------------------
//
TInt CHttpDownload::GetDestinationDriveID() const
    {
    return (TInt)iStorage->GetDestinationDriveId();
    }
    
// -----------------------------------------------------------------------------
// CHttpDownload::SetClientInstance
// ?implementation_description
// (other items were commented in a header).
// -----------------------------------------------------------------------------
//
void CHttpDownload::SetClientInstance( CHttpClientAppInstance* aInstance,
                                       TBool aNoMoveEvent )
    {
    iClAppInstance = aInstance;

    if( iClAppInstance )
        {
        __ASSERT_DEBUG( iClAppInstance->Observer(), DMPanic( KErrCorrupt ) );
        if( iClAppInstance->Observer() && !aNoMoveEvent )
            // for this short moment download state becomes EHttpDlMoved
            // to inform client app about that it grabbed this download
            {
            TriggerEvent( EHttpDlMoved, iProgState );
            }
        }

    else
        // No reason to keep it PD.
        {
          if (iStorage)
		  {
          iStorage->SetProgressiveMode( EFalse );
		  }
        }
    }


// -----------------------------------------------------------------------------
// CHttpDownload::SetConnHandler
// ?implementation_description
// (other items were commented in a header).
// -----------------------------------------------------------------------------
//
void CHttpDownload::SetConnHandler( CHttpConnHandler* aConnHandler )
    {
    iConnHandler = aConnHandler;
    }

// -----------------------------------------------------------------------------
// CHttpDownload::Pausable
// ?implementation_description
// (other items were commented in a header).
// -----------------------------------------------------------------------------
//
TBool CHttpDownload::Pausable() const
    {
    return iPausable;
    }

// -----------------------------------------------------------------------------
// CHttpDownload::SetDownloadNameL
// -----------------------------------------------------------------------------
//
void CHttpDownload::SetDownloadNameL( const TDesC& aNewName )
    {
    CLOG_WRITE_1( "New download name: [%S]", &aNewName );
    
    ReallocateStringL( iDlName, aNewName, KDownloadNameMaxSize );
    
    FixDownloadNameL();
    
    TriggerEvent( EHttpDlInprogress, EHttpProgDlNameChanged );
    }

// -----------------------------------------------------------------------------
// CHttpDownload::MHFRunL
// ?implementation_description
// (other items were commented in a header).
// -----------------------------------------------------------------------------
//
void CHttpDownload::MHFRunL( RHTTPTransaction /*aTransaction*/, 
                             const THTTPEvent& aEvent )
    {
    switch ( aEvent.iStatus )
        {
        case THTTPEvent::EGotResponseHeaders:
            {
            CLOG_WRITE( "Response header received" );
            ResponseHeaderReceivedL();
            } 
            break;

        case THTTPEvent::EGotResponseBodyData:
            {
            MHTTPDataSupplier* respBody = iTrans.Response().Body();
            TPtrC8 buf;

            respBody->GetNextDataPart( buf );

            ResponseBodyReceivedL( buf );

            respBody->ReleaseData();
            } 
            break;

        case THTTPEvent::EResponseComplete:
            {
            CLOG_WRITE( "Response complete" );
            } 
            break;

        case THTTPEvent::ESucceeded:
            {
            CLOG_WRITE( "Transaction succeeded" );
            
            DownloadSucceededL();
            } 
            break;

        case THTTPEvent::EFailed:
        case THTTPEvent::EMoreDataReceivedThanExpected:
        case THTTPEvent::EUnrecoverableError:
        case THTTPEvent::ETooMuchRequestData:
            {
            CLOG_WRITE_1( "Failed event: %d", aEvent.iStatus );
            if( iTransValid )
                {
                iTrans.Close();
                iTransValid = EFalse;
                }
            iDlStartedByClient = EFalse;
            } 
            break;

        case THTTPEvent::ERedirectedPermanently:
            {
            RedirectedPermanentlyL( iTrans.Request().URI().UriDes() );
            } 
            break;

        case THTTPEvent::ERedirectedTemporarily:
            {
            RedirectedTemporaryL( iTrans.Request().URI().UriDes() );
            } 
            break;

        default:
            {
            CLOG_WRITE_1( "Event: %d", aEvent.iStatus );
            if( aEvent.iStatus < 0 )
                // error occured -> leave will be handled in OnError()
                {
                User::Leave( aEvent.iStatus );
                }
            } 
            break;
        }
    }

// -----------------------------------------------------------------------------
// CHttpDownload::MHFRunError
// ?implementation_description
// (other items were commented in a header).
// -----------------------------------------------------------------------------
//
TInt CHttpDownload::MHFRunError( TInt aError, 
                                 RHTTPTransaction /*aTransaction*/, 
                                 const THTTPEvent& /*aEvent*/ )
    {
    CLOG_WRITE_1( "MHFRunError: %d", aError );

    OnError( aError, ETransactionFailed );

    return KErrNone;
    }

// -----------------------------------------------------------------------------
// CHttpDownload::DoCancel
// ?implementation_description
// (other items were commented in a header).
// -----------------------------------------------------------------------------
//
void CHttpDownload::DoCancel()
    {
    LOGGER_ENTERFN( "DoCancel" );

    if( iProgState == EHttpProgMovingContentFile )
        {
        delete iFileMan;
        iFileMan = NULL;

        if( iStatus == KRequestPending )
            // No cancel function in CFileMan
            {
            SelfComplete( KErrCancel );
            }
        }
    }

// -----------------------------------------------------------------------------
// CHttpDownload::RunL
// ?implementation_description
// (other items were commented in a header).
// -----------------------------------------------------------------------------
//
void CHttpDownload::RunL()
    {
    LOGGER_ENTERFN( "RunL" );

    switch( iProgState )
        // Keep progress states consistent with SetDownloadStatus()
        {
        case EHttpStarted:
            {
            iUpdatedDDUriSet = EFalse;
            Connect();
            }
            break;

        case EHttpProgConnected:
            {
            if( iStatus == KErrNone )
                {
                if( iCodDownload )
                    {
                    TriggerEvent( EHttpDlInprogress, EHttpProgCodDownloadShouldResume );
                    }
                else
                    {
                    RequestContentL();
                    }                
                }
                
            }
            break;

        case EHttpProgMovingContentFile:
            // Move completed
            // State remains in completed 
            // and move result stored in error attribs
            {
            CLOG_WRITE_1( "Move result: %d", iStatus.Int() );
            // In case of PDL for OMA2 the MP/VP moves the file after the playback is done.
			// So, the download status should be changed after that
			//but we again send the progress state as EHttpProgContentFileMoved because we need to display
			//where file is saved(saved to gallery)
			//Change Dl State to Download Completed if not already           

		    if(_OMADLOTA2_MULTI_DOWNLOAD)
				{
				TPtrC fileNamePtr = ((*iCodDlData)[iMOMoved])->DestFilename();
				NotifyMediaGalleryL(fileNamePtr);

				// Initiate async move for the next media object
				iMOMoved++;
				if(iMOMoved <= iCodDlData->Count())
					{
					MoveDownloadedMediaObjectL(iMOMoved);
					break;
					}
				}

            SetDownloadStatus( iDlNameChanged ? EHttpProgContentFileMovedAndDestFNChanged : EHttpProgContentFileMoved, 
                               iDlState = EHttpDlMultipleMOCompleted, 
                               iStatus == KErrNone ? ENoError : EMoveFailed,
                               iStatus.Int() );
            
            if(iStatus == KErrNone)
            	{
            	iMoveInProgress = EFalse;	
            	CLOG_WRITE("setting iMoveInProgress false when move is completed");
            	}
            
            
            delete iFileMan; iFileMan = NULL;
            
			if( !_OMADLOTA2_MULTI_DOWNLOAD)
				{
				TPtr fileNamePtr(iStorage->DestFilename()->Des());
				NotifyMediaGalleryL(fileNamePtr);
				}
            }
            break;

        default:
            {
            DMPanic( KErrUnknown );
            }
        }
    }

// -----------------------------------------------------------------------------
// CHttpDownload::RunError
// ?implementation_description
// (other items were commented in a header).
// -----------------------------------------------------------------------------
//
TInt CHttpDownload::RunError(TInt aError)
    {
    // Untrapped leave occured in RunL() -> status must be update and
    // client app has to be informed.
    OnError( aError );

    return KErrNone;
    }

// -----------------------------------------------------------------------------
// CHttpDownload::Connected
// ?implementation_description
// (other items were commented in a header).
// -----------------------------------------------------------------------------
//
void CHttpDownload::Connected()
    {
    LOGGER_ENTERFN( "Connected" );

    if( iProgState == EHttpProgCreatingConnection )
        // In any other progress state we're not interested in this event
        {
        SetDownloadStatus( EHttpProgConnected, EHttpDlInprogress );
        }
    }

// -----------------------------------------------------------------------------
// CHttpDownload::Suspended
// ?implementation_description
// (other items were commented in a header).
// -----------------------------------------------------------------------------
//
void CHttpDownload::Suspended()
    {
    LOGGER_ENTERFN( "Suspended" );

    if( iDlState != EHttpDlInprogress )
        // we are not interested in this event,
        // only if the download is in progress.
        {
        return;
        }

    SetDownloadStatus( EHttpProgConnectionSuspended );
    }

// -----------------------------------------------------------------------------
// CHttpDownload::Disconnected
// ?implementation_description
// (other items were commented in a header).
// -----------------------------------------------------------------------------
//
void CHttpDownload::Disconnected()
    {
    LOGGER_ENTERFN( "Disconnected" );

    if( iDlState != EHttpDlInprogress )
        // we are not interested in this event,
        // only if the download is in progress.
        {
        return;
        }
        
    //Set the errors 
    TRAP_IGNORE( PauseL( ETrue ) );
    
    iLastError = EConnectionFailed;
    iGlobalErrorId = KErrCommsLineFail;
    }


// -----------------------------------------------------------------------------
// CHttpDownload::ConnectionFailed
// ?implementation_description
// (other items were commented in a header).
// -----------------------------------------------------------------------------
//
void CHttpDownload::ConnectionFailed( TInt aError )
    {
    OnError( aError, EConnectionFailed );
    }

// -----------------------------------------------------------------------------
// CHttpDownload::DoReset
// ?implementation_description
// (other items were commented in a header).
// -----------------------------------------------------------------------------
//
void CHttpDownload::DoReset( TBool aOnDelete )
    {
    LOGGER_ENTERFN( "DoReset" );

    // Do not inform user about what we do while reseting
    ++iDontFireEvent;

    Cancel();

    CancelTransaction();

    if( iDisconnectOnReset )
        {
        Disconnect();
        }

    delete iFileMan; iFileMan = NULL;

    ReInitializeDownload();

    // these values are not initialized in ReInitializeDownload()
    delete iContentType; iContentType = NULL;
    delete iDDType; iDDType = NULL;
    delete iHttpRealm; iHttpRealm = NULL;
    delete iHttpNonce; iHttpNonce = NULL;
    TRAP_IGNORE( ReallocateStringL( iRedirUrl, *iUrl, KMaxUrlLength ) );
    TRAP_IGNORE( ReallocateStringL( iCurrentUrl, *iUrl, KMaxUrlLength ) );
    iRedirect = EFalse;
    iDlStartedByClient = EFalse;
    iPausableDRM = ETrue;
    iDrmContentLengthValid = ETrue;

    // content type is unknown -> download might be pausable again
    UpdatePausable();
    
    if( !aOnDelete )
        {
        TRAP_IGNORE( StoreDownloadInfoL() );
        }

    --iDontFireEvent;

    SetDownloadStatus( EHttpProgNone, EHttpDlMultipleMOStarted );
    }

// -----------------------------------------------------------------------------
// CHttpDownload::StoreDownloadInfoL
// ?implementation_description
// (other items were commented in a header).
// -----------------------------------------------------------------------------
//
void CHttpDownload::StoreDownloadInfoL()
    {
    LOGGER_ENTERFN( "StoreDownloadInfoL" );
    TInt bufSz = KDownloadInfoIncrSize + 
                 (iDownloadInfo ? iDownloadInfo->Length(): 0);
    HBufC8* newInfo = HBufC8::NewLC( bufSz );
    TPtr8 newInfoPtr = newInfo->Des();

    APPEND_BUF_INT( newInfoPtr, KDMgrInfoFileId );
    APPEND_BUF_INT( newInfoPtr, KDmgrVersionNumber );
    APPEND_BUF_INT( newInfoPtr, iDlState );
    APPEND_BUF_INT( newInfoPtr, iProgState );
    APPEND_BUF_INT( newInfoPtr, iLastError );
    APPEND_BUF_INT( newInfoPtr, iGlobalErrorId );
    APPEND_BUF_INT( newInfoPtr, iAction );
    APPEND_BUF_INT( newInfoPtr, iRestartAction );
    APPEND_BUF_INT( newInfoPtr, iNoContentTypeCheck );

    CLOG_WRITE("2");
    AppendBufL( newInfoPtr, iUrl );
    AppendBufL( newInfoPtr, iRedirUrl );
    APPEND_BUF_INT( newInfoPtr, iPort );
    AppendBufL( newInfoPtr, iCurrentUrl );
    APPEND_BUF_INT( newInfoPtr, iRedirect );
    APPEND_BUF_INT( newInfoPtr, iTargetApp );
    iStorage->AppendStorageInfoL( newInfoPtr );
    AppendBufL( newInfoPtr, iDlName );
    AppendBufL( newInfoPtr, iHashedMsgBody );
    APPEND_BUF_INT( newInfoPtr, iCodDownload );
    APPEND_BUF_INT( newInfoPtr, iNoMedia );

    CLOG_WRITE("3");
    APPEND_BUF_INT( newInfoPtr, iPreferencies );
    APPEND_BUF_INT( newInfoPtr, iDisconnectOnPause );
    APPEND_BUF_INT( newInfoPtr, iDisconnectOnReset );

    CLOG_WRITE("4");
    AppendBufL( newInfoPtr, iContentType );
    AppendBufL( newInfoPtr, iDDType );
    APPEND_BUF_INT( newInfoPtr, iDate );
    APPEND_BUF_INT( newInfoPtr, iExpires );
    APPEND_BUF_INT( newInfoPtr, iMaxAge );

    CLOG_WRITE("5");

    AppendHeadersL( newInfoPtr, iResponseHeaders );
    AppendHeadersL( newInfoPtr, iRequestHeaders );
    AppendHeadersL( newInfoPtr, iEntityHeaders );
    AppendHeadersL( newInfoPtr, iGeneralHeaders );

    CLOG_WRITE("6");
    
    APPEND_BUF_INT( newInfoPtr, iFotaPckgId );
    
    CLOG_WRITE("7");
    
    // check if download info is unchanged from previous update
    if( iDownloadInfo && ( iDownloadInfo->Compare(*newInfo) == 0 ))
        {
        // no change
        CLOG_WRITE("DownloadInfo unchanged - no need to update");
        CleanupStack::PopAndDestroy( newInfo );
        }
    else
        {
        CLOG_WRITE("DownloadInfo changed - replace info file");
        delete iDownloadInfo;
        iDownloadInfo = newInfo;
        CleanupStack::Pop( newInfo );

        HBufC* folderBuf = HBufC::NewLC( KMaxPath );
        TPtr folder = folderBuf->Des();
        HBufC* fileNameBuf = HBufC::NewLC( KMaxPath );
        TPtr fileName = fileNameBuf->Des();
        iClientApp->Engine()->DownloadInfoFolder( iClientApp, folder );
        fileName.Format( _L("%S%d"), &folder, iId );
        CLOG_WRITE_1( "info: %S", &fileName );
    
        RFile outFile;
        CleanupClosePushL<RFile>( outFile );
        User::LeaveIfError( outFile.Replace( iClientApp->Engine()->Fs(), 
                                             fileName, 
                                             EFileShareExclusive | 
                                             EFileStream | 
                                             EFileWrite ) );

        outFile.Write( newInfoPtr );
        User::LeaveIfError( outFile.Flush() );
        CleanupStack::PopAndDestroy( 2, fileNameBuf );
        CleanupStack::PopAndDestroy(); // outFile
        }
    CLOG_WRITE("CHttpDownload::StoreDownloadInfoL() - exit");
    }

// -----------------------------------------------------------------------------
// CHttpDownload::LoadDownloadInfoL
// ?implementation_description
// (other items were commented in a header).
// -----------------------------------------------------------------------------
//
void CHttpDownload::LoadDownloadInfoL()
    {
    LOGGER_ENTERFN( "LoadDownloadInfoL" );

    HBufC* folderBuf = HBufC::NewLC( KMaxPath );
    TPtr folder = folderBuf->Des();
    HBufC* fileNameBuf = HBufC::NewLC( KMaxPath );
    TPtr fileName = fileNameBuf->Des();

    iClientApp->Engine()->DownloadInfoFolder( iClientApp, folder );

    fileName.Format( _L("%S%d"), &folder, iId );
    CLOG_WRITE_1( "info: %S", &fileName );

    RFile inFile;
    User::LeaveIfError( inFile.Open( iClientApp->Engine()->Fs(), 
                                     fileName, 
                                     EFileShareReadersOnly | 
                                     EFileRead ) );

    CLOG_WRITE("1");
    CleanupClosePushL<RFile>( inFile );

    TInt32 id;
    READ_INT_L( inFile, id );

    if( id == KDMgrInfoFileId )
        {
        TInt version;
        READ_INT_L( inFile, version );

        if( version != KDmgrVersionNumber )
            {
            User::Leave( KErrNotSupported );
            }

        READ_INT_L( inFile, iDlState );
        }
    else
        {
        iDlState = (THttpDownloadState)id;
        }

    READ_INT_L( inFile, iProgState );
    READ_INT_L( inFile, iLastError );
    READ_INT_L( inFile, iGlobalErrorId );
    READ_INT_L( inFile, iAction );
    READ_INT_L( inFile, iRestartAction );
    READ_INT_L( inFile, iNoContentTypeCheck );

    CLOG_WRITE("2");
    ReadHBufCL( inFile, iUrl );
    ReadHBufCL( inFile, iRedirUrl );
    READ_INT_L( inFile, iPort );
    ReadHBufCL( inFile, iCurrentUrl );
    READ_INT_L( inFile, iRedirect );
    READ_INT_L( inFile, iTargetApp );
    iStorage->LoadStorageInfoL( inFile );
    ReadHBufCL( inFile, iDlName );
    ReadHBufCL( inFile, iHashedMsgBody );
    READ_INT_L( inFile, iCodDownload );
    READ_INT_L( inFile, iNoMedia );
    

    CLOG_WRITE("3");
    READ_INT_L( inFile, iPreferencies );
    READ_INT_L( inFile, iDisconnectOnPause );
    READ_INT_L( inFile, iDisconnectOnReset );

    CLOG_WRITE("4");
    ReadHBufCL( inFile, iContentType );
    ReadHBufCL( inFile, iDDType );
    READ_CUST_L( inFile, iDate );
    READ_CUST_L( inFile, iExpires );
    READ_CUST_L( inFile, iMaxAge );

    CLOG_WRITE("5");

    LoadHeadersL( inFile, iResponseHeaders );
    LoadHeadersL( inFile, iRequestHeaders );
    LoadHeadersL( inFile, iEntityHeaders );
    LoadHeadersL( inFile, iGeneralHeaders );
    
    CLOG_WRITE("6");
    
    READ_INT_L( inFile, iFotaPckgId );

    CleanupStack::PopAndDestroy(); // inFile
    CleanupStack::PopAndDestroy( 2, folderBuf ); // also fileNameBuf

    CLOG_WRITE("9");
    
    UpdatePausable();
    }

// -----------------------------------------------------------------------------
// CHttpDownload::IsExpired
// ?implementation_description
// (other items were commented in a header).
// -----------------------------------------------------------------------------
//
TBool CHttpDownload::IsExpired()
    {
    TBool expired = EFalse;
    TTime now;

    // Set UTC
    now.UniversalTime();

    if( iMaxAge.Int() )
        {
        TTime date( iDate );

        if( date + iMaxAge < now )
            {
            expired = ETrue;
            }
        }
    else if( iExpires.Year() )
        {
        TTime expires( iExpires );

        if( expires < now )
            {
            expired = ETrue;
            }
        }

    return expired;
    }

// -----------------------------------------------------------------------------
// CHttpDownload::IsContentFileStorageType
// ?implementation_description
// (other items were commented in a header).
// -----------------------------------------------------------------------------
//

TBool CHttpDownload::IsContentFileStorageType()
    {
    
     
     if( iCodDownload 
         && iContentType->Compare( KRoapMimeType ) 
         && iContentType->Compare( KRoapPduMimeType ) 
         && iContentType->Compare( KFotaPackageDataType)  )
         {
     	 return ETrue;
         }
            
     return EFalse;
     
    }

// -----------------------------------------------------------------------------
// CHttpDownload::OnCompletedL
// ?implementation_description
// (other items were commented in a header).
// -----------------------------------------------------------------------------
//
void CHttpDownload::OnCompletedL()
    {
    LOGGER_ENTERFN( "OnCompletedL" );

    if( 1 == iCodDownload )
        {
        iCodDownload++;
        TriggerEvent( EHttpDlInprogress, EHttpProgCodDescriptorDownloaded );
        TriggerEvent( EHttpDlInprogress, EHttpProgCodDownloadStarted );
        }
    else
        {
        if( !iContTypeRecognitionAvailSent )
            {
            CLOG_WRITE( "CHttpDownload::OnCompletedL(): triggering event EHttpResponseForContentType" );
            TriggerEvent( EHttpDlInprogress, EHttpContTypeRecognitionAvail );
            iContTypeRecognitionAvailSent = ETrue;
            }
        //for correct display of string in download list for COD download we set progress state to moved            
        if(IsContentFileStorageType())
            {
           // Retrieve the file name from the whole paths
            HBufC* fileName = iStorage->DestFilename();
            TInt lastSlashPos = fileName->LocateReverse( '\\' );
            if( lastSlashPos == KErrNotFound )
                lastSlashPos = 0;

            HBufC* name = HBufC::NewLC(KMaxFileName);
            TPtr namePtr( name->Des() );
            namePtr.Copy( fileName->Right(fileName->Length()-lastSlashPos-1) );

            TInt findDot = iDlName->LocateReverse( '.' );
            if( findDot == KErrNotFound )
                {
                //if Name displayed does not have Extension then 
                // Remove extention from retrieved name
                TInt dotInd = namePtr.LocateReverse( '.' );
                 if( dotInd == KErrNotFound )
                    dotInd = namePtr.Length();
                namePtr.Copy( namePtr.Left( dotInd ) );       
            
                }

            //we never get file moved and Download complete for Cod download becuase move is inherent
            //to Install() state i.e  Download is in progress so display in download list is incorrect.
            //related to bug  HCHA-753D6G  
             
            if(namePtr.Compare(*iDlName))
                {
                ReallocateStringL( iDlName, namePtr, KDownloadNameMaxSize );
                SetDownloadStatus( EHttpProgContentFileMovedAndDestFNChanged, EHttpDlMultipleMOCompleted );
                }
           else
                {
                SetDownloadStatus( EHttpProgContentFileMoved, EHttpDlMultipleMOCompleted );
                }
           CleanupStack::PopAndDestroy( name );          
           
            }
        else            
            {
            TriggerEvent( EHttpDlCompleted, EHttpProgNone );
            SetDownloadStatus( EHttpProgNone, EHttpDlMultipleMOCompleted );
            }
       }

    ++iDontFireEvent;

    Cancel();
    Disconnect();

    iStorage->OnComplete();
    
    // this is a special case because transaction don't need to be 
    // canceled, only deleted
    iContinueDownload = EFalse;
    if( iTransValid )
        {
        iTrans.Close();
        iTransValid = EFalse;
        }

    --iDontFireEvent;

    TRAP_IGNORE( StoreDownloadInfoL() );
    }

// -----------------------------------------------------------------------------
// CHttpDownload::GetParamFromMediaTypeL
// ?implementation_description
// (other items were commented in a header).
// -----------------------------------------------------------------------------
//
TPtrC8 CHttpDownload::GetParamFromMediaTypeL( const TDesC8& aAttribute )
    {
    if( !iMediaType )
        {
        User::Leave( KErrNotFound );
        }
    TInt length = iMediaType->Length();
    TInt start = iMediaType->Des().FindF( aAttribute );
    start = ( ( start + aAttribute.Length() ) >= length ) ? KErrNotFound : start;
    User::LeaveIfError( start );
    start += aAttribute.Length();
    TInt end = iMediaType->Des().Mid( start, length-start ).Locate( KSemiColon );
    TInt boundaryLength = ( KErrNotFound == end ) ? length - start : end;
    TPtrC8 ptr = iMediaType->Des().Mid( start, boundaryLength );
    return ptr;    
    }

// -----------------------------------------------------------------------------
// CHttpDownload::ReInitializeDownload
// ?implementation_description
// (other items were commented in a header).
// -----------------------------------------------------------------------------
//
void CHttpDownload::ReInitializeDownload()
    {
    LOGGER_ENTERFN( "ReInitializeDownload" );

    iResponseHeaders->ResetAndDestroy();
    iEntityHeaders->ResetAndDestroy();

    iStorage->ResetAndDestroy();

    iLastError = ENoError;
    iMaxAge = 0;
    iExpires.Set( 0, EJanuary, 1, 0, 0, 0, 0 );
    iDate.Set( 0, EJanuary, 1, 0, 0, 0, 0 );

    iNoMedia = EFalse;
    }

// -----------------------------------------------------------------------------
// CHttpDownload::CancelTransaction
// ?implementation_description
// (other items were commented in a header).
// -----------------------------------------------------------------------------
//
void CHttpDownload::CancelTransaction()
    {
    LOGGER_ENTERFN( "CancelTransaction" );
    if( iTransValid )
        {
        iTrans.Close();
        iTransValid = EFalse;
        }

    if( iContinueDownload )
        {
        TriggerEvent( EHttpDlCancelTransaction );
        }
        
    iContinueDownload = EFalse;

    iDlStartedByClient = EFalse;
    }

// -----------------------------------------------------------------------------
// CHttpDownload::InternalPauseL
// ?implementation_description
// (other items were commented in a header).
// -----------------------------------------------------------------------------
//
void CHttpDownload::InternalPauseL( TBool aDisconnect )
    {
    LOGGER_ENTERFN( "InternalPauseL" );

    CHttpStorage::TFileCloseOperation closeOp = CHttpStorage::EKeepFile;
    if ( !Pausable() && ( iCodDlData && iCodDlData->Count() == 1 ) )
        {
        closeOp = CHttpStorage::EReplaceFile;
        }
    iStorage->CloseDestinationFile( closeOp );
    CancelTransaction();

    if( aDisconnect )
        {
		// Indicate all clients about network loss if the downlolad is not pausable
		if(!iPausable)
			{
			TriggerEvent(EHttpDlNonPausableNetworkLoss);
			}
		Disconnect();
		}
	}

// -----------------------------------------------------------------------------
// CHttpDownload::SetDownloadStatus
// ?implementation_description
// (other items were commented in a header).
// -----------------------------------------------------------------------------
//
void CHttpDownload::SetDownloadStatus( THttpProgressState aProgState,
                                       THttpDownloadState aStatus,
                                       THttpDownloadMgrError aErrorId,
                                       TInt aGlobalErrorId )
    {
#ifdef __DOWNLOADMGR_LOG__  // to filter out EHttpProgResponseBodyReceived
    if( aProgState != EHttpProgResponseBodyReceived )
        {
        CLOG_WRITE_2( "SetDownloadStatus: %d - %d", aStatus, aProgState );
        }
#endif

    TBool eventTriggered( EFalse );

    switch( aStatus )
        {
        case EHttpDlMultipleMOStarted:
		case EHttpDlDeleting:
            {
            iDlState = aStatus;
            iProgState = aProgState;
            }
            break;

        case EHttpDlFailed:
        case EHttpDlMultipleMOCompleted:
        case EHttpDlMultipleMOFailed:
            {
            iDlState = aStatus;
            iProgState = aProgState;
            iLastError = aErrorId;
            iGlobalErrorId = aGlobalErrorId;
            }
            break;

        case EHttpDlInprogress:
            {
            iDlState = aStatus;
            iProgState = aProgState;

            if( aProgState == EHttpStarted ||
                aProgState == EHttpProgConnected )
                // in the other progress state there's no need
                // to go into RunL()
                // Keep it consistente with Runl()
                {
                SelfComplete();
                }
            }
            break;

        case EHttpDlPaused:
            {
            iDlState = aStatus;
            iProgState = aProgState;
            iLastError = aErrorId;
            iGlobalErrorId = aGlobalErrorId;
            Cancel();
            }
            break;

        case EHttpDlMoved:
        case EHttpDlMediaRemoved:
        case EHttpDlMediaInserted:
            {
            TriggerEvent( EHttpDlMoved, EHttpProgNone );
            eventTriggered = ETrue;
            }
            break;

        default:
            {
            DMPanic( KErrArgument );
            }
        }
        
    TRAP_IGNORE( StoreDownloadInfoL() ); //saving the state

    if( !eventTriggered )
        {
        TriggerEvent( iDlState, iProgState );
        }
    }

// -----------------------------------------------------------------------------
// CHttpDownload::ResponseHeaderReceivedL
// ?implementation_description
// (other items were commented in a header).
// -----------------------------------------------------------------------------
//
void CHttpDownload::ResponseHeaderReceivedL()
    {
    LOGGER_ENTERFN( "ResponseHeaderReceivedL" );

    RHTTPResponse resp = iTrans.Response();
    iStatusCode = resp.StatusCode();

    CLOG_WRITE_1( "iStatusCode: %d", iStatusCode );

    if( iProgState == EHttpContentTypeRequested )
        {
        // HEAD method
        switch( iStatusCode )
            {
            case 200:   // OK
            case 201:   // Created
            case 202:   // Accepted
            case 203:   // Non-Authoritative Information
            case 204:   // No Content
            case 205:   // Reset Content
                {
                if( iStorage->ProgressiveDownload() && iStorage->DownloadedSize() )
                    // progressive download cannot be resumed this way.
                    // it's always an error case.
                    {
                    OnError( KErrUnknown, EHttpRestartFailed );
                    }
                else
                    {
                    // store response header only after first request
                    StoreResponseHeaderL();
                    ContentTypeReceivedL();
                    StoreDownloadInfoL();
                    }
                }
                break;

            case 401:   // Unauthorized
                {
                HttpResponse401L();
                }
                break;

            case 407:   // Proxy Authentication Required
                {
                HttpResponse407L();
                }
                break;

            case 404:   // Not Found
                {
                OnError( KErrUnknown, EObjectNotFound );
                }
                break;
                
            default:
                {
                SetDownloadStatus( EHttpProgNone, 
                                   EHttpDlFailed, 
                                   EHttpUnhandled, 
                                   GLOBAL_HTTP_ERROR( iStatusCode ) );
                }
            }
        }
    else
        // GET method
        {
        TBool respOk = EFalse;

        switch( iStatusCode )
            {
            case 200:   // OK
            case 201:   // Created
            case 202:   // Accepted
            case 203:   // Non-Authoritative Information
            case 204:   // No Content
            case 205:   // Reset Content
                // full content download
                // If ERestartNoIfCompleted comes with 200 and
                // iDownloadedSize != 0 it means http server
                // doesn't support conditional range download
                {
                ReInitializeDownload();
                // store response header only after first request
                StoreResponseHeaderL();
                iStorage->CreateDestinationFileL();
                StoreDownloadInfoL();
                respOk = ETrue;
                }
                break;

            case 206:   // Partial Content
                // partial content download
                {
                StoreResponseHeaderL();
                iStorage->CreateDestinationFileL();

                respOk = ETrue;
                }
                break;

            case 304:   // Not Modified
                // content is not modified since download paused
                {
                iStorage->CreateDestinationFileL();
                OnCompletedL();
                }
                break;

            case 412:   // Precondition Failed
            case 416:   // content range is wrong. Most probably expired, or modified.
                {
                if( iRestartAction == ERestartIfExpired ||
                    iRestartAction == ERestartForced )
                    {
                    // Forget a previous redirect
                    ReallocateStringL( iRedirUrl, *iUrl, KMaxUrlLength );
                    ReallocateStringL( iCurrentUrl, *iRedirUrl, KMaxUrlLength );
                    iRedirect = EFalse;

                    CancelTransaction();

                    ReInitializeDownload();

                    SetDownloadStatus( EHttpStarted );
                    }
                else
                    // ERestartNoIfCompleted => content modified since last partial download
                    {
                    OnError( KErrUnknown, EPartialContentModified );
                    }
                }
                break;

            case 401:   // Unauthorized
                // HTTP authentication failed
                {
                HttpResponse401L();
                }
                break;

            case 407:   // Proxy Authentication Required
                // Proxy authentication failed
                {
                HttpResponse407L();
                }
                break;

            case 404:   // Not Found
                // Object not found
                {
                OnError( KErrUnknown, EObjectNotFound );
                }

            default:
                {
                OnError( GLOBAL_HTTP_ERROR( iStatusCode ), EHttpUnhandled );
                }
            }

        if( respOk )
            {
            SetDownloadStatus( EHttpProgResponseHeaderReceived );
            }
        else
            {
            CancelTransaction();
            }
        }
    }

// -----------------------------------------------------------------------------
// CHttpDownload::ResponseBodyReceivedL
// ?implementation_description
// (other items were commented in a header).
// -----------------------------------------------------------------------------
//
void CHttpDownload::ResponseBodyReceivedL( const TDesC8& aBuf )
    {    
    if( iMultiPart && !iCodDownload )
        {
        TBool isSupportedMultiPart( EFalse );
        // If it leaves isSupportedMultiPart remains false -> does not supported!
        TRAP_IGNORE( isSupportedMultiPart = IsMultipartSupportedL( aBuf ) );
        if( isSupportedMultiPart )
            {
            SetCodFlag( ETrue );
            TriggerEvent( EHttpDlInprogress, EHttpProgSupportedMultiPart );
            }
        }          
      
    TBool ret(ETrue);
    
    if( iStorage->BufferingEnabled() )
    	{
    	// Buffering is enabled, just pass on the data
    	ret = iStorage->WriteOutNextBodyDataL(aBuf);
    	}
    else
    	{
    	// Buffering not yet enabled, see how much data we still have to write without buffering
    	TInt bytesToWrite = aBuf.Length();
    	TInt downloadedSize = iStorage->DownloadedSize();
    	
    	if(bytesToWrite + downloadedSize < KMinDataSizeToSend)
    		{
    		// Just dump non-buffered write
    		ret = iStorage->WriteOutNextBodyDataL( aBuf );
    		}
    	else
    		{
    		// Necessary to switch to buffered writing
    		
    		TInt leftPartSize = KMinDataSizeToSend - downloadedSize;
    		TInt rightPartSize = bytesToWrite - leftPartSize;
    		
    		TBool ret1 = ETrue;
    		TBool ret2 = ETrue;
    		
    		if(leftPartSize > 0)
    			{
    			// Write left side of the block to get alignment matched
    			ret1 = iStorage->WriteOutNextBodyDataL( aBuf.Left(leftPartSize) );
    			}
    		
    		// Enable buffering
    		iStorage->EnableBufferingL();
    		
    		// And push the rest of this data block
    		if(rightPartSize > 0)
    			{
    			ret2 = iStorage->WriteOutNextBodyDataL( aBuf.Right(rightPartSize) );
    			}
    		
    		if(!ret1 || !ret2)
    			{
    			ret = EFalse;
    			}
    		}
	    }

    if( !ret )
        {
        StoreDownloadInfoL();
        }

    if( !iContTypeRecognitionAvailSent && (iStorage->DownloadedSize() >= KRespSizeForRecognition) )
        {
        TriggerEvent( EHttpDlInprogress, EHttpContTypeRecognitionAvail );
        iContTypeRecognitionAvailSent = ETrue;        
        }
        
    TriggerEvent( EHttpDlInprogress, EHttpProgResponseBodyReceived );
    }

// -----------------------------------------------------------------------------
// CHttpDownload::IsMultipartSupportedL
// ?implementation_description
// (other items were commented in a header).
// -----------------------------------------------------------------------------
//
TBool CHttpDownload::IsMultipartSupportedL( const TDesC8& aBuf )
    {
    TBool ret( EFalse );
    
    if( !iHeaderOfMultipart )
        {
        iHeaderOfMultipart = HBufC8::NewL( KMaxHeaderOfMultipart );
        }
    TInt full_length = iHeaderOfMultipart->Length() + aBuf.Length();
    if( KMaxHeaderOfMultipart >= full_length )
        {
        iHeaderOfMultipart->Des().Append( aBuf );
        }
    else
        {
        ret = EFalse;
        return ret;
        }
    
    TInt pos = iHeaderOfMultipart->Des().Find( KContentType() );

    User::LeaveIfError( pos );

    pos = pos + KContentType().Length();    

    TPtrC8 p = iHeaderOfMultipart->Des().Mid( pos );    
    TInt temp = p.Find( KDoubleEOL() );
    
    TInt posEol = pos + temp;

    TPtrC8 ptr = iHeaderOfMultipart->Des().Mid( pos, ( posEol - pos ) );
    if( 0 == ptr.Find( KDdMimeType() ) ||
        0 == ptr.Find( KDd2MimeType() ) ||
        0 == ptr.Find( KCodMimeType() ))
        {
        ret = ETrue;
        delete iHeaderOfMultipart;
        iHeaderOfMultipart = NULL;
        return ret;            
        }
        
    return ret;  
    }

// -----------------------------------------------------------------------------
// CHttpDownload::Connect
// ?implementation_description
// (other items were commented in a header).
// -----------------------------------------------------------------------------
//
void CHttpDownload::Connect()
    {
    LOGGER_ENTERFN( "ConnectL" );

    SetDownloadStatus( EHttpProgCreatingConnection );

    if( iConnHandler->IsConnected() )
        // we already have connection. Just use it.
        {
        Connected();
        }
    else
        // No connection
        {
        if( iClAppInstance && iClAppInstance->AutoConnect() )
            // Connection w/o question
            {
            TRAPD( err, iConnHandler->ConnectL() );

            if( err )
                {
                OnError( err, EConnectionFailed );
                }
            }
        else
            // ask before connect
            {
            TriggerEvent( EHttpDlInprogress, EHttpProgConnectionNeeded );
            }
        }
    }

// -----------------------------------------------------------------------------
// CHttpDownload::Disconnect
// ?implementation_description
// (other items were commented in a header).
// -----------------------------------------------------------------------------
//
void CHttpDownload::Disconnect()
    {
    LOGGER_ENTERFN( "Disconnect" );

    if( iConnHandler )
        {
        TriggerEvent( iDlState, EHttpProgDisconnected );
        // iConnHandler is set NULL from Disconnect()
        iConnHandler->Disconnect( EFalse, this );

        iConnHandler = NULL;
        }
    }

// -----------------------------------------------------------------------------
// CHttpDownload::SetRequestHeaderL
// ?implementation_description
// (other items were commented in a header).
// -----------------------------------------------------------------------------
//
void CHttpDownload::SetRequestHeaderL( RStringPool& aStringPool,
                                       RHTTPHeaders& aHeaders,
                                       TBool aHeadMethod )
    {
    LOGGER_ENTERFN( "SetRequestHeaderL" );

    // Set default Accept header
    aHeaders.SetRawFieldL( aStringPool.StringF(HTTP::EAccept, RHTTPSession::GetTable()),
                           KDefaultAcceptHeader(),
                           KHttpFieldSeparator );

    SetRequestHeaderAddOnL( aStringPool, aHeaders );
    SetCredentialsInfoL( aStringPool );

    // Find ETag in response header
    RStringF etag = aStringPool.StringF(HTTP::EETag, 
                                        RHTTPSession::GetTable());
    TInt fieldInd = FindHeaderField( iResponseHeaders, etag.DesC() );
    if( fieldInd != KErrNotFound )
        // ETag is known. ETag identifies the content. Set If-Match to see
        // that if it's changed, or a redirection goes to another url.
        // Server will respond with 412 on error.
        {
        RStringF ifMatch = aStringPool.StringF(HTTP::EIfMatch, 
                                        RHTTPSession::GetTable());
        aHeaders.RemoveField( ifMatch );
        aHeaders.SetRawFieldL( ifMatch, 
                               *(*iResponseHeaders)[fieldInd]->FieldRawData(), 
                               KHttpFieldSeparator );
        CLOG_WRITE8_1( "ETag: %S", (*iResponseHeaders)[fieldInd]->FieldRawData() );
        }

    if( aHeadMethod )
        // HEAD method doesn't require any other field to be set
        {
        return;
        }

    CLOG_WRITE_1( "Down: %d", iStorage->DownloadedSize() );
    CLOG_WRITE_1( "Length: %d", iStorage->Length() );

    if( iRestartAction == ERestartNoIfCompleted )
        {
        CLOG_WRITE( "ERestartNoIfCompleted" );

        SetRangeFieldL( aStringPool, aHeaders );

        RStringF field;

        if( iStorage->DownloadedSize() != iStorage->Length() )
            // download from previous point only if the content is unmodified
            {
            field = aStringPool.StringF(HTTP::EIfUnmodifiedSince, 
                                        RHTTPSession::GetTable());

            SetExpireToFieldL( field, aStringPool, aHeaders );
            }
        }
    else if( iRestartAction == ERestartIfExpired )
        // Expire and max-age is already checked in StartL
        // nothing to do if response is 304
        {
        CLOG_WRITE( "ERestartIfExpired" );

        RStringF field;

        if( iStorage->DownloadedSize() != iStorage->Length() )
            // we don't have the entire content
            // start from where we stopped before
            {
            SetRangeFieldL( aStringPool, aHeaders );
            // download entire content if expired
            field = aStringPool.StringF(HTTP::EIfRange, RHTTPSession::GetTable());
            }
        else
            // we have the entire content. Check that content is modified
            // since it's downloaded, or wait for response 304.
            {
            field = aStringPool.StringF(HTTP::EIfModifiedSince, RHTTPSession::GetTable());
            }

        SetExpireToFieldL( field, aStringPool, aHeaders );
        }
    }

// -----------------------------------------------------------------------------
// CHttpDownload::DisablePipeliningL
// ?implementation_description
// (other items were commented in a header).
// -----------------------------------------------------------------------------
//
void CHttpDownload::DisablePipeliningL( RStringPool& aStringPool )
    {
    LOGGER_ENTERFN( "DisablePipeliningL" );

    RStringF pipeline = aStringPool.StringF(HTTP::EHttpPipelining, RHTTPSession::GetTable());
    RStringF disable = aStringPool.StringF(HTTP::EDisablePipelining, RHTTPSession::GetTable());

    iTrans.PropertySet().SetPropertyL(pipeline, disable);
    }

// -----------------------------------------------------------------------------
// CHttpFilterAuthentication::SetPropertyL
// Set property of the transaction
// -----------------------------------------------------------------------------
//
void CHttpDownload::SetPropertyL( RStringPool& aStringPool,
                                  RStringF aPropertyName, 
                                  const TDesC8& aToken )
    {
    RString tokenStr = aStringPool.OpenStringL( aToken );
    THTTPHdrVal tokenVal = tokenStr;
    CleanupClosePushL( tokenStr );
    iTrans.PropertySet().RemoveProperty( aPropertyName );
    iTrans.PropertySet().SetPropertyL( aPropertyName, tokenVal );

    CLOG_WRITE8_2( "SetPropertyL: %S - %S", &aPropertyName.DesC(), &aToken );

    CleanupStack::PopAndDestroy(); // tokenStr
    }

// -----------------------------------------------------------------------------
// CHttpFilterAuthentication::SetPropertyL
// Set property of the transaction
// -----------------------------------------------------------------------------
//
void CHttpDownload::SetPropertyL( RStringF aPropertyName, 
                                  const TInt aValue )
    {
    THTTPHdrVal tokenVal = aValue;

    iTrans.PropertySet().RemoveProperty( aPropertyName );
    iTrans.PropertySet().SetPropertyL( aPropertyName, tokenVal );

    CLOG_WRITE8_2( "SetPropertyL: %S - %d", &aPropertyName.DesC(), aValue );
    }

// -----------------------------------------------------------------------------
// CHttpFilterAuthentication::SetRequestHeaderAddOnL
// Set property of the transaction
// -----------------------------------------------------------------------------
//
void CHttpDownload::SetRequestHeaderAddOnL( RStringPool& aStringPool,
                                            RHTTPHeaders& aHeaders )
    {
    if( !iRequestHeaders->Count() )
        {
        return;
        }

    TPtrC8 fieldName;
    TPtrC8 fieldValue;
    RStringF fieldNameStr;
    THTTPHdrVal value;

    for( TInt i = 0; i < iRequestHeaders->Count(); ++i )
        {
        CLOG_WRITE8_3( "Req(%d): %S: %S", i, (*iRequestHeaders)[i]->FieldName(), (*iRequestHeaders)[i]->FieldRawData() );

        fieldNameStr = aStringPool.OpenFStringL( *(*iRequestHeaders)[i]->FieldName() );
        CleanupClosePushL( fieldNameStr );

//        aHeaders.RemoveField( fieldNameStr );
        if (fieldNameStr == aStringPool.StringF(HTTP::EIfModifiedSince, RHTTPSession::GetTable()) ||
            fieldNameStr == aStringPool.StringF(HTTP::EIfUnmodifiedSince, RHTTPSession::GetTable()))
            {
            TInternetDate date;
            date.SetDateL(*(*iRequestHeaders)[i]->FieldRawData());
            TDateTime modifyTime(date.DateTime());
            aHeaders.SetFieldL(fieldNameStr, modifyTime);
            CleanupStack::PopAndDestroy(); // fieldNameStr
            }
        else
            {
            RStringF valueStr = aStringPool.OpenFStringL( *(*iRequestHeaders)[i]->FieldRawData() );
            value.SetStrF( valueStr );
            CleanupClosePushL( valueStr );

            aHeaders.SetFieldL( fieldNameStr, valueStr );

            CleanupStack::PopAndDestroy( 2 ); // valueStr, fieldNameStr
            }
        }
    }

// -----------------------------------------------------------------------------
// CHttpDownload::SetCredentialsInfoL
// ?implementation_description
// (other items were commented in a header).
// -----------------------------------------------------------------------------
//
void CHttpDownload::SetCredentialsInfoL( RStringPool& aStringPool )
    {
    LOGGER_ENTERFN( "SetCredentialsInfoL" );

    if( iHttpUsername )
        {
        RStringF username = aStringPool.StringF( HTTP::EUsername, 
                                                    RHTTPSession::GetTable() );

        SetPropertyL( aStringPool, username, *iHttpUsername );
        }

    if( iHttpPassword )
        {
        RStringF password = aStringPool.StringF( HTTP::EPassword, 
                                                    RHTTPSession::GetTable() );

        SetPropertyL( aStringPool, password, *iHttpPassword );
        }

    if( iHttpRealm )
        {
        RStringF realm = aStringPool.StringF( HTTP::ERealm, 
                                                    RHTTPSession::GetTable() );
        SetPropertyL( aStringPool, realm, *iHttpRealm );
        }

    if( iHttpProxyRealm )
        {
        RStringF proxyRealmStr = aStringPool.StringF( 
                                        HttpFilterCommonStringsExt::EProxyRealm, 
                                        HttpFilterCommonStringsExt::GetTable() );
        SetPropertyL( aStringPool, proxyRealmStr, *iHttpProxyRealm );
        }

    if( iHttpProxyUsername )
        {
        RStringF proxyUsernameStr = aStringPool.StringF( 
                                    HttpFilterCommonStringsExt::EProxyUsername, 
                                    HttpFilterCommonStringsExt::GetTable() );
        SetPropertyL( aStringPool, proxyUsernameStr, *iHttpProxyUsername );
        }

    if( iHttpProxyPassword )
        {
        RStringF proxyPasswordStr = aStringPool.StringF( 
                                        HttpFilterCommonStringsExt::EProxyPassword, 
                                        HttpFilterCommonStringsExt::GetTable() );
        SetPropertyL( aStringPool, proxyPasswordStr, *iHttpProxyPassword );
        }

    if( iHttpNonce )
        {
        RStringF nonce = aStringPool.StringF( HTTP::ENonce, 
                                                    RHTTPSession::GetTable() );

        SetPropertyL( aStringPool, nonce, *iHttpNonce );
        }
    }

// -----------------------------------------------------------------------------
// CHttpDownload::SetRangeFieldL
// ?implementation_description
// (other items were commented in a header).
// -----------------------------------------------------------------------------
//
void CHttpDownload::SetRangeFieldL( RStringPool& aStringPool,
                                    RHTTPHeaders& aHeaders )
    {
    LOGGER_ENTERFN( "SetRangeFieldL" );

    if( iStorage->DownloadedSize() == 0 )
        // no bytes have been downloaded yet
        {
        return;
        }

    RStringF range = aStringPool.StringF(HTTP::ERange, RHTTPSession::GetTable());

    aHeaders.RemoveField( range );

    TBuf8<48> rawData;

    rawData.Format( _L8("bytes=%d-"), iStorage->DownloadedSize() );

    CLOG_WRITE8_1( "Range: %S", &rawData );
    aHeaders.SetRawFieldL( range, rawData, KHttpFieldSeparator );
    }

// -----------------------------------------------------------------------------
// CHttpDownload::SetExpireToFieldL
// ?implementation_description
// (other items were commented in a header).
// -----------------------------------------------------------------------------
//
void CHttpDownload::SetExpireToFieldL( RStringF& aField, 
                                       RStringPool& aStringPool,
                                       RHTTPHeaders& aHeaders )
    {
    LOGGER_ENTERFN( "SetExpireToFieldL" );

    RStringF expires = aStringPool.StringF(HTTP::EExpires, RHTTPSession::GetTable());
    RStringF lastModified = aStringPool.StringF(HTTP::ELastModified, RHTTPSession::GetTable());

    TInt expInd( KErrNotFound );
    TInt modInd( KErrNotFound );

    for( TInt i = 0; i < iResponseHeaders->Count(); ++i )
        // FindHeaderField, because this is double search for fieldnames 
        {
        if( *(*iResponseHeaders)[i]->FieldName() == expires.DesC() )
            {
            expInd = i;
            continue;
            }
        if( *(*iResponseHeaders)[i]->FieldName() == lastModified.DesC() )
            {
            modInd = i;
            continue;
            }
        }

    if( expInd != KErrNotFound )
        {
        CLOG_WRITE8_1( "Expire: %S", (*iResponseHeaders)[expInd]->FieldRawData() );

        aHeaders.RemoveField( aField );
        aHeaders.SetRawFieldL( aField, 
                               *(*iResponseHeaders)[expInd]->FieldRawData(), 
                               KHttpFieldSeparator );
        }
    else if( modInd != KErrNotFound )
        {
        CLOG_WRITE8_1( "LastMod: %S", (*iResponseHeaders)[modInd]->FieldRawData() );

        aHeaders.RemoveField( aField );
        aHeaders.SetRawFieldL( aField, 
                               *(*iResponseHeaders)[modInd]->FieldRawData(), 
                               KHttpFieldSeparator );
        }
    }

// -----------------------------------------------------------------------------
// CHttpDownload::ParseRequestedUrlL
// ?implementation_description
// (other items were commented in a header).
// -----------------------------------------------------------------------------
//
void CHttpDownload::ParseRequestedUrlL()
    {
    LOGGER_ENTERFN( "ParseRequestedUrlL" );

    __ASSERT_DEBUG( iUrl->Length(), DMPanic( KErrArgument ) );

    TUriParser8 uri; 
    uri.Parse( *iUrl );

    TPtrC8 scheme( uri.Extract( EUriScheme ) );

    if( scheme != KHttpScheme &&
        scheme != KHttpsScheme )
        // unsupported or no scheme in url.
        // Insert 'http://' to the beginning of it.
        {
        HBufC8* tempBuf = HBufC8::NewL( KHttpScheme().Length() + 
                                        KSchemeAddon().Length() + 
                                        iUrl->Length() );

        tempBuf->Des().Append( KHttpScheme );
        tempBuf->Des().Append( KSchemeAddon );
        tempBuf->Des().Append( *iUrl );

        delete iUrl; iUrl = NULL;

        iUrl = tempBuf;

        uri.Parse( *iUrl );
        }

    CUri8* url = CUri8::NewLC();

    url->SetComponentL( uri.Extract( EUriScheme ), EUriScheme );
    url->SetComponentL( uri.Extract( EUriHost ), EUriHost );
    url->SetComponentL( uri.Extract( EUriPath ), EUriPath );
    url->SetComponentL( uri.Extract( EUriUserinfo ), EUriUserinfo );
    url->SetComponentL( uri.Extract( EUriQuery ), EUriQuery );
    url->SetComponentL( uri.Extract( EUriFragment ), EUriFragment );
    
    if( uri.IsPresent( EUriPort ) )
        {
        url->SetComponentL( uri.Extract( EUriPort ), EUriPort );
        }
    else
        {
        if( iPort != KDefaultPort )
            {
            TBuf8<10> port;

            port.Format( _L8("%d"), iPort );

            url->SetComponentL( port, EUriPort );
            }
        }

    CLOG_WRITE8_1( "Parsed URL: %S", &url->Uri().UriDes() );

    // Initially they are the same
    ReallocateStringL( iRedirUrl, url->Uri().UriDes(), KMaxUrlLength );
    ReallocateStringL( iCurrentUrl, url->Uri().UriDes() , KMaxUrlLength);

    CleanupStack::PopAndDestroy( url );
    }

// -----------------------------------------------------------------------------
// CHttpDownload::ParseDownloadNameL
// ?implementation_description
// (other items were commented in a header).
// -----------------------------------------------------------------------------
//
void CHttpDownload::ParseDownloadNameL()
    {
    LOGGER_ENTERFN( "ParseDownloadNameL" );

    // Calculate the download name from the requested URL
    HBufC8* parsedUrl = EscapeUtils::EscapeDecodeL( *iCurrentUrl );
    CleanupStack::PushL( parsedUrl );
    
    TUriParser8 uri; 
    uri.Parse( *parsedUrl );

    TPtrC8 path;

    path.Set( uri.Extract( EUriPath ) );

    HBufC* newDlName = HBufC::NewLC( KDownloadNameMaxSize );
    TPtr newDlNamePtr = newDlName->Des();

    // Here we don't have to deal with that iDlName is longer than KMaxPath
    // ConvertDownloadNameUniqueL() will make the correction
    if( path.Length() )
        // there's path in the url
        {
        TInt slash = path.LocateReverse( '/' );

        if( slash == KErrNotFound )
            {
            slash = path.LocateReverse( '\\' );
            }
            
        if( slash != KErrNotFound && slash != path.Length() )
            // from the last slash this is the filename
            {
            TPtrC8 temp( path.Right( path.Length() - slash - 1 ) );

            if( temp.Length() )
                {
				HBufC *tempstr = EscapeUtils::ConvertToUnicodeFromUtf8L(temp.Left( KDownloadNameMaxSize ));
				newDlNamePtr.Copy(*tempstr);
				delete tempstr;
                }
            else
                // empty path -> default filename is the host
                // filename is KDefDestFilename
                {
                newDlNamePtr.Copy( KDefDestFilename );
                }
            }
        else
            // no slash -> entire path is the filename
            {
			HBufC *tempstr = EscapeUtils::ConvertToUnicodeFromUtf8L(path.Left( KDownloadNameMaxSize ));
			newDlNamePtr.Copy(*tempstr);
			delete tempstr;
            }
        }
    else
        // no path -> default filename is the host
        // filename is KDefDestFilename
        {
        newDlNamePtr.Copy( KDefDestFilename );
        }

    SetDownloadNameL( newDlNamePtr );
    CleanupStack::PopAndDestroy( newDlName );
    CleanupStack::PopAndDestroy( parsedUrl );

    CLOG_WRITE_1( "Name: %S", iDlName );
    }

// -----------------------------------------------------------------------------
// CHttpDownload::StoreResponseHeaderL
// ?implementation_description
// (other items were commented in a header).
// -----------------------------------------------------------------------------
//
void CHttpDownload::StoreResponseHeaderL()
    {
    LOGGER_ENTERFN( "StoreResponseHeaderL" );

    TPtrC8 rawData;
    RStringPool strPool = iConnHandler->Session().StringPool();
    RHTTPHeaders headers( iTrans.Response().GetHeaderCollection() );
    THTTPHdrFieldIter it = headers.Fields();

    // forget the previous headers
    iResponseHeaders->ResetAndDestroy();
    iEntityHeaders->ResetAndDestroy();

    CLOG_WRITE( "Received response header:" );
    while ( !it.AtEnd() )
        {
        RStringTokenF fieldName = it();
        RStringF fieldNameStr = strPool.StringF (fieldName );

        headers.GetRawField( fieldNameStr, rawData );

        CHeaderField* field = CHeaderField::NewL( &fieldNameStr.DesC(), &rawData );
        CleanupStack::PushL( field );

        CLOG_WRITE8_2("%S:%S", &fieldNameStr.DesC(), &rawData);
        iResponseHeaders->AppendL( field );
        
        CleanupStack::Pop( field );
        
        CHeaderField* entityField = CHeaderField::NewL( &fieldNameStr.DesC(), &rawData );
        CleanupStack::PushL( entityField );

        CLOG_WRITE8_2("%S:%S", &fieldNameStr.DesC(), &rawData);
        iEntityHeaders->AppendL( entityField );

        CleanupStack::Pop( entityField );

        ++it;
        }    

    ParseContentTypeL( strPool );
    
    ParseContentDispositionL( strPool);
    if (!iCodDownload)
        {
		if (iUseAttachmentFileName || iUseInlineFileName)
	        {
	        SetDownloadNameL( *iAttachmentFileName );
		    }
        }

    RStringF length = strPool.StringF(HTTP::EContentLength,RHTTPSession::GetTable());
    RStringF date = strPool.StringF(HTTP::EDate,RHTTPSession::GetTable());
    RStringF expires = strPool.StringF(HTTP::EExpires,RHTTPSession::GetTable());
    RStringF maxAge = strPool.StringF(HTTP::EMaxAge,RHTTPSession::GetTable());
    RStringF cacheControl = strPool.StringF(HTTP::ECacheControl,RHTTPSession::GetTable());
    THTTPHdrVal value;

    if( !headers.GetField( length, 0, value ) )
        {
        if( iStorage->Length() == KDefaultContentLength )
            // content size is
            {
            iStorage->SetLength( value );
            }
        else
            //This is a partial response as Length is already set so save this new length as partial Length that needs to be Downloaded.
            {
            iStorage->SetPartialContentLength( value );
            }    
        }
        
    CheckRealDRMContentType();
    if( !iDrmContentLengthValid )
        // Content was original encoded -> we don't know the actual content size.
        {
        iStorage->SetLength( KDefaultContentLength );
        }
        
        
    iMaxAge = 0;
    TInt parts( 0 );
    // this leave is trapped because we can still go on
    TRAPD( err, parts = headers.FieldPartsL( cacheControl ) );

    if( !err )
        // try to find max-age in Cache-control field
        {
        for( TInt i = 0; i < parts; ++i )
            {
            RStringF directive;
            THTTPHdrVal hdrVal;
            TInt err;

            // Get the cache-control from the headers
            // initialise the fieldname
            headers.GetField( cacheControl, i, hdrVal );

            if((hdrVal.Type() == THTTPHdrVal::KStrVal) || (hdrVal.Type() == THTTPHdrVal::KStrFVal))
                {
                RStringF cacheDir = hdrVal.StrF();

                TInt endPos;
                _LIT8(KFind, "=");

                endPos = cacheDir.DesC().Find( KFind );
                if( endPos != -1 )
                    {
                    TRAP(err, directive = strPool.OpenFStringL(cacheDir.DesC().Left(endPos)));
                    if( !err )
                        {
                        if( directive == maxAge )
                            {
                            TInt valueInt( 0 );
                            TLex8 value( cacheDir.DesC().Right(cacheDir.DesC().Length() - endPos - 1) );

                            value.Val( valueInt );
                            iMaxAge = valueInt;
                            }
                        }
                    }
                }
            }
        }

    if( !headers.GetField( expires, 0, value ) )
        {
        iExpires = value;
        }
    else
        {
        iExpires.SetYear( 0 );
        }

    if( !headers.GetField( date, 0, value ) )
        {
        iDate = value;
        }
    else
        {
        iDate.SetYear( 0 );
        }

    UpdatePausable();
    }

// -----------------------------------------------------------------------------
// CHttpDownload::CheckRealDRMContentType
// ?implementation_description
// (other items were commented in a header).
// -----------------------------------------------------------------------------
//
void CHttpDownload::CheckRealDRMContentType()
    {
    LOGGER_ENTERFN( "CheckRealDRMContentType" );

    iPausableDRM = ETrue;
    iDrmContentLengthValid = ETrue;
    
    TInt index = FindHeaderField( iResponseHeaders, KDRMOldContentType );
    if( index != KErrNotFound )
        // this is an old DRM protected content
        // This transaction cannot be paused.
        {
        if( !(*iResponseHeaders)[index]->FieldRawData()->Compare( KDrmMessageMimeType() ) )
            {
            iPausableDRM = EFalse;
//            iDrmContentLengthValid = EFalse;
            }
        }
        
    UpdatePausable();
            
    CLOG_WRITE_2( "Pausable: [%d], Length: [%d]", iPausableDRM, iDrmContentLengthValid );
    }

// -----------------------------------------------------------------------------
// CHttpDownload::SaveCredentialsL
// ?implementation_description
// (other items were commented in a header).
// -----------------------------------------------------------------------------
//
void CHttpDownload::SaveCredentialsL( RStringPool aStringPool )
    {
    LOGGER_ENTERFN( "SaveCredentialsL" );

    RStringF username = aStringPool.StringF( HTTP::EUsername, 
                                                RHTTPSession::GetTable() );
    RStringF password = aStringPool.StringF( HTTP::EPassword, 
                                                RHTTPSession::GetTable() );
    RStringF realm = aStringPool.StringF( HTTP::ERealm, 
                                                RHTTPSession::GetTable() );
    RStringF nonce = aStringPool.StringF( HTTP::ENonce, 
                                                RHTTPSession::GetTable() );

    THTTPHdrVal hdrValue;

    // Realm
    if( iTrans.PropertySet().Property( realm, hdrValue ) )
        {
        if( hdrValue.Str().DesC().Length() )
            // W/o realm authentication is meaningless
            {
            ReallocateStringL( iHttpRealm, hdrValue.Str().DesC(), KMaxDefAttrLength );
            CLOG_WRITE8_1( "Realm: [%S]", iHttpRealm );

            // Username
            if( iTrans.PropertySet().Property( username, hdrValue ) )
                {
                ReallocateStringL( iHttpUsername, hdrValue.Str().DesC(), KMaxDefAttrLength );
                CLOG_WRITE8_1( "uname: [%S]", iHttpUsername );
                }

            // Password
            if( iTrans.PropertySet().Property( password, hdrValue ) )
                {
                ReallocateStringL( iHttpPassword, hdrValue.Str().DesC(), KMaxDefAttrLength );
                CLOG_WRITE8_1( "pwd: [%S]", iHttpPassword );
                }

            if( !iTrans.PropertySet().Property( 
                                    aStringPool.StringF( HTTP::EBasic, 
                                    RHTTPSession::GetTable() ), 
                                    hdrValue ) )
                // this is a digest authentication response
                // store nonce value
                {
                if( iTrans.PropertySet().Property( nonce, hdrValue ) )
                    {
                    ReallocateStringL( iHttpNonce, hdrValue.Str().DesC() );
                    CLOG_WRITE8_1( "nonce: [%S]", iHttpNonce );
                    }
                }
            }
        }
    }

// -----------------------------------------------------------------------------
// CHttpDownload::RequestContentL
// ?implementation_description
// (other items were commented in a header).
// -----------------------------------------------------------------------------
//
void CHttpDownload::RequestContentL()
    {
    LOGGER_ENTERFN( "RequestContentL" );

    RStringPool strPool = iConnHandler->Session().StringPool();
    RStringF method;
    TBool aHead = ETrue;
    
    if( (iContentType && iContentType->Length()) ||
        iNoContentTypeCheck ||
        iSilentMode )
        // we know the content type -> head is already requested or
        // every content type is welcome
        {
        method = strPool.StringF( HTTP::EGET,RHTTPSession::GetTable() );
        aHead = EFalse;
        }
    else
        // content type check needed -> first request HEAD
        {
        method = strPool.StringF( HTTP::EHEAD,RHTTPSession::GetTable() );
        }

    TUriParser8 uri; 
    uri.Parse( *iCurrentUrl );

    CLOG_WRITE8_1( "Req URL: %S", iCurrentUrl );
    CLOG_WRITE8_1( "Method: %S", &method.DesC() );

    __ASSERT_DEBUG( !iTransValid, DMPanic( KErrCorrupt ) );
    if( iTransValid )
        {
        User::Leave( KErrCorrupt );
        }

    iTrans = iConnHandler->Session().OpenTransactionL( uri, *this, method );
    iTransValid = ETrue;

    RHTTPHeaders headers( iTrans.Request().GetHeaderCollection() );

    SetRequestHeaderL( strPool, headers, aHead );

    DisablePipeliningL( strPool );
    SetCookiesL( strPool );

    iTrans.SubmitL();

    if( aHead )
        {
        SetDownloadStatus( EHttpContentTypeRequested );
        }
    else
        {
        SetDownloadStatus( EHttpProgSubmitIssued );
        }
    }

// -----------------------------------------------------------------------------
// CHttpDownload::ContentTypeReceivedL
// ?implementation_description
// (other items were commented in a header).
// -----------------------------------------------------------------------------
//
void CHttpDownload::ContentTypeReceivedL()
    {
    LOGGER_ENTERFN( "ContentTypeReceivedL" );

    InternalPauseL( EFalse );
    SetDownloadStatus( EHttpContentTypeReceived, EHttpDlPaused );
    }

// -----------------------------------------------------------------------------
// CHttpDownload::HttpResponse401L
// ?implementation_description
// (other items were commented in a header).
// -----------------------------------------------------------------------------
//
void CHttpDownload::HttpResponse401L()
    {
    LOGGER_ENTERFN( "HttpResponse401L" );

    THTTPHdrVal hdrValue;
    RStringPool strPool = iConnHandler->Session().StringPool();

    // Check authentication scheme
    TBool basic = iTrans.PropertySet().Property( strPool.StringF( HTTP::EBasic, 
                                                 RHTTPSession::GetTable() ), 
                                                 hdrValue );

    if( basic )
        // property is set -> Basic
        {
        iAuthScheme = EAuthBasic;
        }
    else
        // property not set -> Digest
        {
        iAuthScheme = EAuthDigest;
        }

    RStringF staleStr = strPool.StringF( HTTP::EStale, RHTTPSession::GetTable() );

    SaveCredentialsL( strPool );
    if( iTrans.PropertySet().Property( staleStr, hdrValue ) ||  // 1.
        (iDlStartedByClient && iHttpUsername) )                 // 2.
        // 1. - In case of stale we only have to resubmit the request
        // with the same credentials info
        // 2. - download was started by the client app that has specified
        // the http username -> try to do the authentication
        {
        CancelTransaction();
        SetDownloadStatus( EHttpStarted );
        }
    else
        {
        OnError( KErrUnknown, EHttpAuthenticationFailed );
        }
    }

// -----------------------------------------------------------------------------
// CHttpDownload::HttpResponse407L
// ?implementation_description
// (other items were commented in a header).
// -----------------------------------------------------------------------------
//
void CHttpDownload::HttpResponse407L()
    {
    LOGGER_ENTERFN( "HttpResponse407L" );

    // Check authentication scheme
    THTTPHdrVal hdrValue;

    RStringPool strPool = iConnHandler->Session().StringPool();
    TInt err = iTrans.PropertySet().Property( strPool.StringF( HTTP::EBasic, 
                                               RHTTPSession::GetTable() ), 
                                               hdrValue );

    if( !err )
        // property is set -> Basic
        {
        iAuthScheme = EAuthBasic;
        }
    else
        // property not set -> Digest
        {
        iAuthScheme = EAuthDigest;
        }

    RStringF staleStr = strPool.StringF( HTTP::EStale, RHTTPSession::GetTable() );

    SaveCredentialsL( strPool );
    if( iTrans.PropertySet().Property( staleStr, hdrValue ) ||  // 1.
        (iDlStartedByClient && iHttpUsername) )                 // 2.
        // 1. - In case of stale we only have to resubmit the request
        // with the same credentials info
        // 2. - download was started by the client app that has specified
        // the http username -> try to do the authentication
        {
        CancelTransaction();
        SetDownloadStatus( EHttpStarted );
        }
    else
        {
        OnError( KErrUnknown, EProxyAuthenticationFailed );
        }
    }

// -----------------------------------------------------------------------------
// CHttpDownload::FindHeaderField
// ?implementation_description
// (other items were commented in a header).
// -----------------------------------------------------------------------------
//
TInt CHttpDownload::FindHeaderField( CArrayPtrFlat<CHeaderField>* aHeaders,
                                     const TDesC8& aFieldName ) const
    {
    for( TInt index = 0; index < aHeaders->Count(); ++index )
        {
        if( *(*aHeaders)[index]->FieldName() == aFieldName )
            {
            return index;
            }
        }

    return KErrNotFound;
    }

// -----------------------------------------------------------------------------
// CHttpDownload::ConvertDownloadNameUniqueL
// ?implementation_description
// (other items were commented in a header).
// -----------------------------------------------------------------------------
//
void CHttpDownload::ConvertDownloadNameUniqueL()
    {
    LOGGER_ENTERFN( "ConvertDownloadNameUniqueL" );

    CArrayPtrFlat<CHttpDownload>* downloads = iClientApp->Downloads();
    TBool bFound( EFalse );
    TInt index( 0 );
    HBufC* uniqueName = NULL;

    do
        {
        bFound = EFalse;

        CreateIndexedNameL( uniqueName, *iDlName, index );

        for( TInt i = 0; i < downloads->Count(); ++i )
            {
            if( (*downloads)[i] != this )
                {
                CLOG_WRITE_1( "Compare: %S", (*downloads)[i]->iDlName );
                if( !uniqueName->Des().Compare( *(*downloads)[i]->iDlName ) )
                    {
                    bFound = ETrue;
                    break;
                    }
                }
            }
        }while( bFound );

    delete iDlName;
    iDlName = uniqueName;
    CLOG_WRITE_1( "Unique name: [%S]", iDlName );
    }

// -----------------------------------------------------------------------------
// CHttpDownload::CreateIndexedNameL
// ?implementation_description
// (other items were commented in a header).
// -----------------------------------------------------------------------------
//
void CHttpDownload::CreateIndexedNameL( HBufC* &aUniqueName, 
                                        TDesC& aOrgName, 
                                        TInt& aIndex )
    {
    LOGGER_ENTERFN( "CreateIndexedNameL" );

    TPtrC left;
    TPtrC extension;
    TBuf<KMaxIndexStringLength> indexStr;

    if( aIndex )
        {
        indexStr.Format( KIndexString, aIndex );
        }

    TInt fullLength = aOrgName.Length() + indexStr.Length();
    if( fullLength > KMaxPath )
        // name is longer than KMaxPath.
        {
        OnError( KErrGeneral, EBadUrl );
        User::Leave( KErrGeneral );
        }

    delete aUniqueName; aUniqueName = NULL;

    TInt dotInd = aOrgName.LocateReverse( '.' );
    if( dotInd != KErrNotFound )
        // filename extension found.
        // insert index string between name and extension
        {
        extension.Set( aOrgName.Right( aOrgName.Length() - dotInd ) );
        left.Set( aOrgName.Left( MIN( dotInd, ( KDownloadNameMaxSize -
            indexStr.Length() - extension.Length() ))));
        }
    else
        {
        left.Set( aOrgName.Left( KDownloadNameMaxSize - indexStr.Length() ));
        }

    aUniqueName = HBufC::NewL( fullLength );
    aUniqueName->Des().Format( _L("%S%S%S"), &left, 
                                             &indexStr,
                                             &extension );

    ++aIndex;
    }

// -----------------------------------------------------------------------------
// CHttpDownload::ContinueDownloadStoreResponseHeaderL
// ?implementation_description
// (other items were commented in a header).
// -----------------------------------------------------------------------------
//
void CHttpDownload::ContinueDownloadStoreResponseHeaderL( 
                                                const TDesC8& aResponseHeader )
    {
    LOGGER_ENTERFN( "ContinueDownloadStoreResponseHeaderL" );

    TInt colon( KErrNotFound );
    TInt separator( KErrNotFound );
    TPtrC8 field( aResponseHeader );
    TPtrC8 fieldName;
    TPtrC8 fieldValue;
    RStringPool strPool;

    // forget the previous headers
    iResponseHeaders->ResetAndDestroy();
    iEntityHeaders->ResetAndDestroy();

    strPool.OpenL( RHTTPSession::GetTable() );
    strPool.OpenL( HttpFilterCommonStringsExt::GetTable() );

    do
        {
        separator = KErrNotFound;

        colon = field.Locate( KColon );

        if( colon > 0 )
            // name found and is at least one byte long
            {
            fieldName.Set( field.Left( colon ) );
            field.Set( field.Right( field.Length() - colon - 1 ) );

            separator = field.Locate( KHttpFieldSeparator()[0] );

            if( separator != KErrNotFound )
                // there is more add-on
                {
                fieldValue.Set( field.Left( separator ) );
                field.Set( field.Right( field.Length() - separator - 1 ) );
                }
            else
                // this is the last add-on
                {
                fieldValue.Set( field );
                }

            CHeaderField* newField = CHeaderField::NewL( &fieldName, &fieldValue );
            CleanupStack::PushL( newField );

            CLOG_WRITE8_2("%S:%S", &fieldName, &fieldValue);
            iResponseHeaders->AppendL( newField );

            CleanupStack::Pop( newField );
            
            CHeaderField* newentField = CHeaderField::NewL( &fieldName, &fieldValue );
            CleanupStack::PushL( newentField );

            CLOG_WRITE8_2("%S:%S", &fieldName, &fieldValue);
            iEntityHeaders->AppendL( newentField );

            CleanupStack::Pop( newentField );
            }

        }while( separator != KErrNotFound );

    ParseContentTypeL( strPool );

	ParseContentDispositionL( strPool);
    if (!iCodDownload)
        {
		if (iUseAttachmentFileName || iUseInlineFileName)
	        {
	        SetDownloadNameL( *iAttachmentFileName );
		    }
        }

    CheckRealDRMContentType();

    RStringF length = strPool.StringF(HTTP::EContentLength,RHTTPSession::GetTable());
    RStringF contentEncoding = strPool.StringF( HTTP::EContentEncoding, RHTTPSession::GetTable() );

    TInt index = FindHeaderField( iResponseHeaders, length.DesC() );
    TInt contentEncodingInd = FindHeaderField( iResponseHeaders, contentEncoding.DesC() );
    if( ( index != KErrNotFound && contentEncodingInd == KErrNotFound ) &&
          iDrmContentLengthValid )
        {
        iStorage->SetLength( (*iResponseHeaders)[index]->Int() );
        }
    else
        // in case of content-encoding the content length is size of the compressed content
        // not the decompressed one.
        {
        CLOG_WRITE( "Content is encoded, or DRM" );
        iStorage->SetLength( KDefaultContentLength );
        }

    strPool.Close();
    }

// -----------------------------------------------------------------------------
// CHttpDownload::ParseContentTypeL
// ?implementation_description
// (other items were commented in a header).
// -----------------------------------------------------------------------------
//
void CHttpDownload::ParseContentTypeL( RStringPool& aStrPool )
    {
    LOGGER_ENTERFN( "ParseContentTypeL" );

    RStringF contentType = aStrPool.StringF(HTTP::EContentType,RHTTPSession::GetTable());

    TInt index = FindHeaderField( iResponseHeaders, contentType.DesC() );
    if( index != KErrNotFound )
        // store content-type
        {
        TPtrC8 rawData( *(*iResponseHeaders)[index]->FieldRawData() );
        TPtrC8 mediaType;

        // ';' separates content-type from media type
        TInt semicolon = rawData.Locate( KSemiColon );

        if( semicolon != KErrNotFound )
            {
            mediaType.Set( rawData.Right( rawData.Length() - semicolon - 1 ) );
            Trim( mediaType );
            rawData.Set( rawData.Left( semicolon ) );
            Trim( rawData );
            }

        ReallocateStringL( iContentType, rawData, KMaxContentTypeLength );
        ReallocateStringL( iDDType, rawData, KMaxContentTypeLength );
        ReallocateStringL( iMediaType, mediaType, KMaxContentTypeLength );
        }
        
#ifdef __SYNCML_DM_FOTA        
    if( !iContentType->Des().CompareF( KFotaMimeType ) )
        {
        iStorage->SetStorageMethod( CHttpStorage::EStoreFota );
        }
#endif

    if( ( 0 == iContentType->Des().Compare( KCodMimeType() ) ) ||
        ( 0 == iContentType->Des().Compare( KDdMimeType()  ) ) ||
        ( 0 == iContentType->Des().Compare( KDd2MimeType()  ) ) )
        {
        SetCodFlag( ETrue );
        }
        
    if( 0 == iContentType->Des().Compare( KMultiPartMimeType() ) )
        {
        iMultiPart = ETrue;
        }
        
    }

// -----------------------------------------------------------------------------
// CHttpDownload::ParseContentDispositionL
// ?implementation_description
// (other items were commented in a header).
// -----------------------------------------------------------------------------
//
void CHttpDownload::ParseContentDispositionL( RStringPool& aStrPool )
    {
    LOGGER_ENTERFN( "ParseContentDispositionL" );

    RStringF contentDisposition = aStrPool.StringF(HTTP::EContentDisposition,RHTTPSession::GetTable());

    TInt index = FindHeaderField( iResponseHeaders, contentDisposition.DesC() );
    if( index != KErrNotFound )
        // store content-disposition
        {
        TPtrC8 rawData( *(*iResponseHeaders)[index]->FieldRawData() );
        TPtrC8 fileNameParm;
		TBool isFileNameParam = EFalse;

        // ';' separates disposition-type from disposition parm
        TInt semicolon = rawData.Locate( KSemiColon );

        if( semicolon != KErrNotFound )
            {
            fileNameParm.Set( rawData.Right( rawData.Length() - semicolon - 1 ) );
            Trim( fileNameParm );
			// filename=<AttachmentFileName>
			TInt offset = fileNameParm.FindC( KHttpFileNameParm );
			if (offset != KErrNotFound)
				{
				// '=' separates value of fileName from the <AttachmentFileName>
				TInt equal = fileNameParm.Locate( KEqual );
				if( equal != KErrNotFound )
					{
					fileNameParm.Set( fileNameParm.Right( fileNameParm.Length() - equal - 1 ) );
					Trim( fileNameParm );
					TInt semicolon1 = fileNameParm.Locate( KSemiColon );

					// find '"' around the <AttachmentFileName>
					TInt quote = fileNameParm.Locate( KQuote );
					if (quote != KErrNotFound)
					{
					fileNameParm.Set( fileNameParm.Right( fileNameParm.Length() - quote - 1 ) );
					Trim( fileNameParm );
					}

					TInt quote1 = fileNameParm.Locate( KQuote );
					if (quote1 != KErrNotFound)
					{
					fileNameParm.Set( fileNameParm. Left(quote1) );
					Trim( fileNameParm );
					}

					if( semicolon1 != KErrNotFound )
						{
							fileNameParm.Set( fileNameParm.Left( semicolon1 ) );
						}
					isFileNameParam = ETrue;
                    // we must strip off any directory names from the filename
                    // first check for and remove any trailing '\' or '/' characters
                    if( ( fileNameParm.Right( 1 ).Locate( '\\' ) != KErrNotFound ) ||
                        ( fileNameParm.Right( 1 ).Locate( '/' ) != KErrNotFound ))
                        {
                        fileNameParm.Set( fileNameParm.Left( fileNameParm.Length() - 1 ));
                        }
                    // next find location of last '/' or '\' to remove any directory names
                    TInt lastSlash = fileNameParm.LocateReverse( '/' );
                    if( lastSlash == KErrNotFound )
                        {
                        lastSlash = fileNameParm.LocateReverse( '\\' );
                        }
                    if( lastSlash != KErrNotFound )
                        {
                        fileNameParm.Set( fileNameParm.Mid( lastSlash + 1 ));
                        }
					}
				rawData.Set( rawData.Left( semicolon ) );  // DispositionType
				Trim( rawData );
		        }
			}

        ReallocateStringL( iDispositionType, rawData, KMaxDispositionTypeLength );

		if( isFileNameParam && (0 == iDispositionType->Des().CompareC( KHttpDispositionTypeAttachment()) ) )
			{
			ReallocateStringL( iAttachmentFileName, fileNameParm );
			iUseAttachmentFileName = ETrue;
			}
		if( isFileNameParam && (0 == iDispositionType->Des().CompareC( KHttpDispositionTypeInline()) ) )
			{
			ReallocateStringL( iAttachmentFileName, fileNameParm );
			iUseInlineFileName = ETrue;
			}
        }                        
    }

// -----------------------------------------------------------------------------
// CHttpDownload::TriggerEvent
// ?implementation_description
// (other items were commented in a header).
// -----------------------------------------------------------------------------
//
void CHttpDownload::TriggerEvent( THttpDownloadState aDlState,
                                  THttpProgressState aProgState )
    {
#ifdef __DOWNLOADMGR_LOG__  // to filter out EHttpProgResponseBodyReceived
    if( aProgState != EHttpProgResponseBodyReceived )
        {
        CLOG_WRITE_3( "Trigger: %d - %d - %d", aDlState, aProgState, iActiveDownload );
        }
#endif

    if( iSilentMode )
        {
        if( !((aDlState == EHttpDlInprogress && aProgState == EHttpStarted)
            || aDlState == EHttpDlMultipleMOCompleted || aDlState == EHttpDlFailed ))
            // See EDlAttrSilent
            {
            return;
            }
        }

    if( !iDontFireEvent )
        {
        if( iClAppInstance && iClAppInstance->Observer() )
            {
            // informs client app about status change
            iClAppInstance->Observer()->Event( this, aDlState, aProgState, iActiveDownload );
            }

        if( iPDClAppInstance && iPDClAppInstance->Observer() )
            {
            if( iActiveDownload == iActivePlayedDownload || aDlState == EHttpDlDeleting )
                iPDClAppInstance->Observer()->Event( this, aDlState, aProgState, iActiveDownload );
            }
		}
    }

// -----------------------------------------------------------------------------
// CHttpDownload::UpdatePausable
// ?implementation_description
// (other items were commented in a header).
// -----------------------------------------------------------------------------
//
void CHttpDownload::UpdatePausable()
    {
    LOGGER_ENTERFN( "UpdatePausable" );

    TBool pausable( ETrue );

    if( !iPausableDRM )
        {
        pausable = EFalse;
        }
        
    if( iMethod == EMethodPOST )
        {
        pausable = EFalse;
        }

    if( pausable != iPausable )
        {
        if( !iCodDownload )	
            {
        	iPausable = pausable;
        	
        	// inform client about change
            TriggerEvent( iPausable ? EHttpDlPausable : EHttpDlNonPausable );

            TRAP_IGNORE( StoreDownloadInfoL() );
            }
        }
    }

// -----------------------------------------------------------------------------
// CHttpDownload::ForcedRestartL
// ?implementation_description
// (other items were commented in a header).
// -----------------------------------------------------------------------------
//
void CHttpDownload::ForcedRestartL()
    {
    // Forget a previous redirect
    ReallocateStringL( iRedirUrl, *iUrl );
    ReallocateStringL( iCurrentUrl, *iRedirUrl );
    iRedirect = EFalse;

    ReInitializeDownload();
    }

// -----------------------------------------------------------------------------
// CHttpDownload::HeaderFieldL
// ?implementation_description
// (other items were commented in a header).
// -----------------------------------------------------------------------------
//
HBufC8* CHttpDownload::HeaderFieldL( CArrayPtrFlat<CHeaderField>* aHeaders,
                                             TInt aFieldIndex )
    {
    HBufC8* retVal = NULL;
    RStringPool strPool;

    strPool.OpenL( RHTTPSession::GetTable() );
    // Find field in response header
    RStringF charset = strPool.StringF( aFieldIndex, RHTTPSession::GetTable() );

    TInt index = FindHeaderField( aHeaders, charset.DesC() );
    if( KErrNotFound != index )
        {
        retVal = (*aHeaders)[index]->FieldRawData();
        }

    strPool.Close();

    return retVal;
    }

#ifdef DEAD_CODE
// -----------------------------------------------------------------------------
// CHttpDownload::CheckIfContentUnModified
// ?implementation_description
// (other items were commented in a header).
// -----------------------------------------------------------------------------
//
TBool CHttpDownload::CheckIfContentUnModified()
    {
    CLOG_WRITE( "CheckIfContentUnModified" );

    RStringPool strPool = iConnHandler->Session().StringPool();
    RHTTPHeaders headers( iTrans.Response().GetHeaderCollection() );

    RStringF lastMod = strPool.StringF(HTTP::ELastModified,RHTTPSession::GetTable());
    THTTPHdrVal value;

    if( !headers.GetField( lastMod, 0, value ) )
        {
        TDateTime date( value );

        if( iDate.Year() != date.Year() ||
            iDate.Month() != date.Month() ||
            iDate.Day() != date.Day() ||
            iDate.Hour() != date.Hour() ||
            iDate.Minute() != date.Minute() ||
            iDate.Second() != date.Second() ||
            iDate.MicroSecond() != date.MicroSecond() )
            {
            CLOG_WRITE( "Date changed" );

            return EFalse;
            }
        }

    return ETrue;
    }
#endif

// -----------------------------------------------------------------------------
// CHttpDownload::CheckAttribMaxLengthL
// ?implementation_description
// (other items were commented in a header).
// -----------------------------------------------------------------------------
//
void CHttpDownload::CheckAttribMaxLengthL( THttpDownloadAttrib aAttribute, 
	                                       const TDesC16& aValue )
    {
    for( TInt i = 0; KStringAttribMaxLengths[i][0]; ++i )
        {
        if( aAttribute == KStringAttribMaxLengths[i][0] )
            {
            if( aValue.Length() > KStringAttribMaxLengths[i][1] )
                {
                CLOG_WRITE_2( "Overflow length: %d, max-length: %d", aValue.Length(), 
                                                    KStringAttribMaxLengths[i][1] );
                User::Leave( KErrOverflow );
                }
            }
        }
    }

// -----------------------------------------------------------------------------
// CHttpDownload::CheckAttribMaxLengthL
// ?implementation_description
// (other items were commented in a header).
// -----------------------------------------------------------------------------
//
void CHttpDownload::CheckAttribMaxLengthL( THttpDownloadAttrib aAttribute, 
	                                       const TDesC8& aValue )
    {
    for( TInt i = 0; KStringAttribMaxLengths[i][0]; ++i )
        {
        if( aAttribute == KStringAttribMaxLengths[i][0] )
            {
            if( aValue.Length() > KStringAttribMaxLengths[i][1] )
                {
                CLOG_WRITE_2( "Overflow length: %d, max-length: %d", aValue.Length(), 
                                                    KStringAttribMaxLengths[i][1] );
                User::Leave( KErrOverflow );
                }
            }
        }
    }

// -----------------------------------------------------------------------------
// CHttpDownload::SetCookiesL
// ?implementation_description
// (other items were commented in a header).
// -----------------------------------------------------------------------------
//
void CHttpDownload::SetCookiesL( RStringPool& aStringPool )
    {
    RStringF propName = aStringPool.OpenFStringL( KCookieUsage );

    CleanupClosePushL( propName );

    SetPropertyL( propName, iUseCookies );

    CleanupStack::PopAndDestroy( &propName );
    }

// -----------------------------------------------------------------------------
// CHttpDownload::DownloadSucceededL
// ?implementation_description
// (other items were commented in a header).
// -----------------------------------------------------------------------------
//
void CHttpDownload::DownloadSucceededL()
    {
    CLOG_WRITE( "Transaction succeeded" );

    // inform storage class that it doesn't have to expect any more chunk
    // completed event fired only when the last chunk is persisted
    OnCompletedL();
    iDlStartedByClient = EFalse;
    }

// -----------------------------------------------------------------------------
// CHttpDownload::ParseRequestHeaderAddOnL
// ?implementation_description
// (other items were commented in a header).
// -----------------------------------------------------------------------------
//
void CHttpDownload::ParseRequestHeaderAddOnL( const TDesC8& aValue )
    {
    if( !aValue.Length() )
        {
        return;
        }

    TPtrC8 fieldName;
    TPtrC8 fieldData;
    TPtrC8 value( aValue );

    TInt ind( 0 );
    TBool found( EFalse );

    RStringPool strPool = iClAppInstance->ConnHandler()->Session().StringPool();
    TInt fieldInd;

    do
        {
        fieldInd = KErrNotFound;
        // find KColon in the argument string
        for( ind = 0; ind < value.Length() && value[ind] != KColon; ++ind ){};

        if( value[ind] != KColon )
            // no KColon -> Invalid request header
            {
            User::Leave( KErrArgument );
            }

        // store field name
        fieldName.Set( value.Left( ind ) );
        // and remove it from the argument string
        value.Set( value.Right( value.Length() - ind - 1 ) );

        // find field separator
        ind = value.Find( KHttpFieldSeparator );

        if( ind == KErrNotFound )
            // not found -> no more field
            {
            fieldData.Set( value );
            found = EFalse;
            }
        else
            // found -> store raw data
            // and go to next field
            {
            fieldData.Set( value.Left( ind ) );
            value.Set( value.Right( value.Length() - ind - 1 ) );
            found = ETrue;
            }

        // Find out if this is a native request header field, or not.
        // If not, fieldInd is KErrNotFound
        for( TInt i = 0; KRequestHeaderConvTable[i][0]; ++i )
            {
            RStringF fieldNameStr = strPool.StringF( KRequestHeaderConvTable[i][1], 
                                                     RHTTPSession::GetTable() );

            if( !fieldName.CompareF( fieldNameStr.DesC() ) )
                // this is a native header field name
                {
                fieldInd = i;
                break;
                }
            }

        CHeaderField* field = CHeaderField::NewL( &fieldName, &fieldData, fieldInd );
        CleanupStack::PushL( field );

        iRequestHeaders->AppendL( field );
        CLOG_WRITE8_3("Req(%d): %S:%S", iRequestHeaders->Count(), &fieldName, &fieldData );

        CleanupStack::Pop( field );
        }while( found );
    }

// -----------------------------------------------------------------------------
// CHttpDownload::LoadHeadersL
// -----------------------------------------------------------------------------
//
void CHttpDownload::LoadHeadersL( RFile& aFile, 
                                  CArrayPtrFlat<CHeaderField>* aHeaders )
    {
    TInt headers;
    READ_INT_L( aFile, headers );

    CLOG_WRITE_1("Headers: %d", headers);
    aHeaders->ResetAndDestroy();

    for( TInt i = 0; i < headers; ++i )
        {
        CHeaderField* field = CHeaderField::NewL();
        CleanupStack::PushL( field );

        field->LoadHeaderInfoL( aFile );
        aHeaders->AppendL( field );

/*        if( field->FieldName() && field->FieldRawData() )
            {
            CLOG_WRITE8_1( "%S", field->FieldName() );
            CLOG_WRITE8_1( "%S", field->FieldRawData() );
            }
        else
            {
            CLOG_WRITE8( "Empty field" );
            }
*/    
        CleanupStack::Pop( field );
        }
    }

// -----------------------------------------------------------------------------
// CHttpDownload::AppendHeadersL
// -----------------------------------------------------------------------------
//
void CHttpDownload::AppendHeadersL( TPtr8& aBuf,
                                    CArrayPtrFlat<CHeaderField>* aHeaders )
    {
    TInt headers = aHeaders->Count();
    CLOG_WRITE_1("Headers: %d", headers);

    APPEND_BUF_INT( aBuf, headers );

    HBufC8* fieldName = NULL;
    HBufC8* fieldRawData = NULL;
    for( TInt i = 0; i < headers; ++i )
        {
        fieldName = (*aHeaders)[i]->FieldName();
        fieldRawData = (*aHeaders)[i]->FieldRawData();
        AppendBufL( aBuf, fieldName );
        AppendBufL( aBuf, fieldRawData );
        CLOG_WRITE8_2( "%S:%S", fieldName, fieldRawData );
        }
    }

// -----------------------------------------------------------------------------
// CHttpDownload::AddHeaderL
// -----------------------------------------------------------------------------
//
void CHttpDownload::AddHeaderL( THttpDownloadAttrib aAttribute, 
								const TDesC8& aValue,
                                const TInt aConversionTable[][2],
                                CArrayPtrFlat<CHeaderField>* aHeaders )
    {
    TInt index( KErrNotFound );

    // search for if this field is already in the 
    for( index = 0; aConversionTable[index][0]; ++index )
        {
        if( aConversionTable[index][0] == aAttribute )
            {
            break;
            }
        }

    __ASSERT_DEBUG( index != KErrNotFound, DMPanic( KErrCorrupt ) );

    RStringPool strPool = iClAppInstance->ConnHandler()->Session().StringPool();
    RStringF fieldName = strPool.StringF( aConversionTable[index][1], 
                                          RHTTPSession::GetTable() );
    CleanupClosePushL( fieldName );

    // make a copy of the raw data
    HBufC8* value = HBufC8::NewLC( aValue.Length() );
    value->Des().Copy( aValue );

    CHeaderField* newField = CHeaderField::NewL( &fieldName.DesC(), value, index );

    CleanupStack::Pop( value );
    CleanupStack::PushL( newField );

    aHeaders->AppendL( newField );

    CleanupStack::Pop( 2 ); // newField, fieldName
    }
    
// -----------------------------------------------------------------------------
// CHttpDownload::RedirectedPermanentlyL
// -----------------------------------------------------------------------------
//
void CHttpDownload::RedirectedPermanentlyL( const TDesC8& aNewUrl )
    {
    CLOG_WRITE8_1( "ERedirectedPermanently: %S", &aNewUrl );
    // from now on this new redirected url has to be used
    if( !iRedirect )
        {
        ReallocateStringL( iRedirUrl, aNewUrl, KMaxUrlLength );
        ReallocateStringL( iCurrentUrl, *iRedirUrl, KMaxUrlLength );
        }
    else
        // there has already been a temporary redirection
        // this permanent is not used on next submitted request 
        {
        ReallocateStringL( iCurrentUrl, aNewUrl, KMaxUrlLength );
        }
    ParseDownloadNameL();
    StoreDownloadInfoL();   // to store new url

    TriggerEvent( EHttpDlInprogress, EHttpProgRedirectedPermanently );
    }

// -----------------------------------------------------------------------------
// CHttpDownload::RedirectedPermanentlyL
// -----------------------------------------------------------------------------
//
void CHttpDownload::RedirectedTemporaryL( const TDesC8& aNewUrl )
    {
    CLOG_WRITE8_1( "ERedirectedTemporarily: %S", &aNewUrl );
    iRedirect = ETrue;
    ReallocateStringL( iCurrentUrl, aNewUrl, KMaxUrlLength );
    ParseDownloadNameL();
    StoreDownloadInfoL();   // to store iRedirect

    TriggerEvent( EHttpDlInprogress, EHttpProgRedirectedTemporarily );
    }
    
// -----------------------------------------------------------------------------
// CHttpDownload::FixDownloadNameL
// -----------------------------------------------------------------------------
//
void CHttpDownload::FixDownloadNameL()
    {
    if( !iCodDownload )
        {
        TPtr name( iDlName->Des() );
        
        for( TInt i = 0; i < name.Length(); ++i )
            {
            TChar currChar = (*iDlName)[i];
            
            if( currChar.IsAlphaDigit() ||
                currChar.IsGraph() || 
                currChar == 0x20 )  // space
                {
                continue;
                }
            else
                {
                name[i] = KUrlFixChar;
                }
            }
            
        ConvertDownloadNameUniqueL();
        }
    }

// -----------------------------------------------------------------------------
// CHttpDownload::SetCodFlag
// -----------------------------------------------------------------------------
//
void CHttpDownload::SetCodFlag( TBool aValue )
    {
    if( aValue && iCodDownload )
        {
        // this case we will not overwrite 
        // the value of iCodDownload. iCodDownload might be > 1
        return;
        }
    iCodDownload = aValue;
    }

// -----------------------------------------------------------------------------
// CHttpDownload::SelfComplete
// ?implementation_description
// (other items were commented in a header).
// -----------------------------------------------------------------------------
//
void CHttpDownload::SelfComplete( TInt aReason )
    {
    __ASSERT_DEBUG( !IsActive(), DMPanic( KErrGeneral ) );
    SetActive();

    TRequestStatus* dummy = &iStatus;

    User::RequestComplete( dummy, aReason );
    }

// -----------------------------------------------------------------------------
// CHttpDownload::UpdateDestFileNameL
// -----------------------------------------------------------------------------
//
void CHttpDownload::UpdateDestFileNameL()
    {
    LOGGER_ENTERFN( "UpdateDestFileNameL" );
    RFs fs;
    User::LeaveIfError( fs.Connect() );
    CleanupClosePushL(fs);
    TInt32 downloadedSize(0);
    downloadedSize = iStorage->DownloadedSize();
	HBufC16* fileName ;
	fileName = iStorage->DestFilename();
    TPtr fileNamePtr = fileName->Des();
    TDriveUnit currentDrive(fileNamePtr);
    TBuf<KMaxDrives> driveList;
    TInt err( KErrNone );
    TInt drive( EDriveC );
    TBool criticalSpace( EFalse );
    TBool needToUpdatePath( ETrue );

    CLOG_WRITE_1( " entering fileName: %S", fileName );
#ifdef RD_MULTIPLE_DRIVE
    HBufC8* drivesDynList = iClientApp->Engine()->QueryDynDriveListLC();
    TPtrC8 drives( *drivesDynList ); 
#else
    TPtrC drives( iClientApp->Engine()->iDriveLettersCenRep );
#endif
    // drive letters are separated by semicolons
    for( TInt i = 0; i < drives.Length() && (err || !criticalSpace); i = i + 2 )
        {
        if( ( err = fs.CharToDrive( drives[i], drive )) != KErrNone )
            {
            continue;
            }
        if( drive == currentDrive )//if the current path is same as the path in cenrep then no need to update.The diff is because we must have not known size before hand
            {
            needToUpdatePath = EFalse;
            break;
            }
        else
            {
            TInt bytesToWrite = downloadedSize;
            if (bytesToWrite < 0)
                bytesToWrite = 0;
            
            TRAP( err, criticalSpace = !SysUtil::DiskSpaceBelowCriticalLevelL(
                                                             &fs, bytesToWrite, drive ));
            }             
        }
    if( needToUpdatePath )
        {
        iDlNameChanged = ETrue;
#ifdef RD_MULTIPLE_DRIVE
        // using PathInfo::RootPath to set correct destination folder
        // depending on memory used

        // Getting RootPath for selected Drive
        TFileName rootPath;
        User::LeaveIfError( PathInfo::GetRootPath( rootPath, drive ) );

        // remove path from EDlAttrDestFilename
        if( fileNamePtr.Length() > 0 )
            {
            TInt lastSlashPos = fileNamePtr.LocateReverse( '\\' );
            if( lastSlashPos != KErrNotFound )
                {
                fileNamePtr.Delete( 0, lastSlashPos );
                }
            }
    
        // Setting RootPath for new Destination file
        fileNamePtr.Insert( 0, rootPath );
        // Setting KDownloadPath
        fileNamePtr.Insert( rootPath.Length(), KDownloadPath );
#else
        TChar driveChar;
        fs.DriveToChar(drive, driveChar);
        TBuf<2> buf;
        buf.Append(driveChar);
        fileNamePtr.Replace(0,1,buf);
#endif
        err = fs.MkDirAll( fileNamePtr );//in case the size unknown the dir needs to be formed again as Drive can change
        if ( err != KErrNone && err != KErrAlreadyExists )
            {
            User::Leave( err );
            }
        }
    CLOG_WRITE_1( " exiting fileName: %S", fileName );
#ifdef RD_MULTIPLE_DRIVE
    CleanupStack::PopAndDestroy( drivesDynList ); 
#endif
    CleanupStack::PopAndDestroy( &fs );
    }    

// ---------------------------------------------------------
// CHttpDownload::UpdateDCFRepositoryL()
// Update saved file to DCFRepository  
// ---------------------------------------------------------
// 
void CHttpDownload::UpdateDCFRepositoryL(
    const TDesC& aFileName )
    {
    LOGGER_ENTERFN( "UpdateDCFRepositoryL" );
    CLOG_WRITE_1( " :UpdateDCFRepositoryL() for: %S", &aFileName );
    CDcfEntry* dcfEntry = NULL;
    dcfEntry = CDcfEntry::NewL();    
    CleanupStack::PushL( dcfEntry );
    
    CDcfRep* dcfRep = NULL;
    dcfRep = CDcfRep::NewL();
    CleanupStack::PushL( dcfRep );

    dcfEntry->SetLocationL( aFileName, 0 );    
    CLOG_WRITE(" : SetLocationL OK");
    dcfRep->UpdateL( dcfEntry );
    CLOG_WRITE(" :UpdateL OK");
    CleanupStack::PopAndDestroy(2); // dcfEntry, dcfRep
    }                 

// -----------------------------------------------------------------------------
// CHttpDownload::MoveInDeleteL
// ?implementation_description
// (other items were commented in a header).
// -----------------------------------------------------------------------------
//
TInt CHttpDownload::MoveInDelete(TInt mediaObjectIndex)
	{
	TInt err(KErrNone);
	if(!iCodDlData)
		return err;

	if(	mediaObjectIndex <= iCodDlData->Count())
		{
		TRAP_IGNORE(MoveDownloadedMediaObjectSyncL(mediaObjectIndex));
		TPtrC filenamePtr = ((*iCodDlData)[mediaObjectIndex])->DestFilename();
		if(filenamePtr.Length())
    		{
    		TRAP_IGNORE(NotifyMediaGalleryL( filenamePtr ));    
    		}
		}
	return err;
	}


// -----------------------------------------------------------------------------
// CHttpDownload::MoveDownloadedMediaObjectL
// ?implementation_description
// (other items were commented in a header).
// -----------------------------------------------------------------------------
//
void CHttpDownload::MoveDownloadedMediaObjectL(TInt mediaObjectIndex)
    {
    LOGGER_ENTERFN( "MoveDownloadedMediaObjectsL" );

    if( iDlState != EHttpDlMultipleMOCompleted && !iMoDownloadCompleted )
        {
        iStorage->SetProgressiveMode( EFalse );	
        TriggerEvent( iDlState, EHttpDlProgNonProgressive);
        return;//Move will be Done by COD as MO Completed has not happened
        }

    //__ASSERT_DEBUG( !IsActive(), DMPanic( KErrInUse ) );
    //__ASSERT_DEBUG( !iFileMan, DMPanic( KErrInUse ) );

#if 0
    
#else

    HBufC* filename = HBufC::NewLC(KMaxFileName);
	TPtr filenamePtr1 = filename->Des();
	
    RFs &fs = iClientApp->Engine()->Fs();
	if(!iFileMan)
		{
		iFileMan = CFileMan::NewL(fs);	
		}

    TPtrC filenamePtr2 = ((*iCodDlData)[mediaObjectIndex])->DestFilename();
    if(!filenamePtr2.Length())
    	{
        CleanupStack::PopAndDestroy(filename);
        return;
    	}
    
    TInt firstSlashPos = filenamePtr2.Locate( '\\' );

    if(firstSlashPos < 0)
	    {
	    CleanupStack::PopAndDestroy(filename);
	    return;	
	    }
  	TPtrC dlName = filenamePtr2.Left(firstSlashPos);

    TInt drive;
    
    User::LeaveIfError( fs.CharToDrive( dlName[0], drive ));


    // Getting RootPath for selected Drive
    TFileName rootPath;
    User::LeaveIfError( PathInfo::GetRootPath( rootPath, drive ) );

    // Setting KDownloadPath
    rootPath.Append( KDownloadPath );

    filenamePtr1.Copy(rootPath);
    filenamePtr1.Append(_L("\\"));

    TInt error = fs.MkDirAll(filenamePtr1);
    if (error!=KErrNone && error!=KErrAlreadyExists)
       {
        User::Leave(error);   
       }
	if( mediaObjectIndex == iActivePlayedDownload )
	    {	    
	           	
	    iFname = ((*iCodDlData)[mediaObjectIndex])->TempFilename();
	    }

	else
		{	    
	    
	    iFname = ((*iCodDlData)[mediaObjectIndex])->DestFilename();
		}   
    // Find a unique name to avoid any conflict.
    // Here iFname has full path of current location of file
    // and filename has destination path.
    FindUniqueDestinationFileNameL( iFname, filename );
    
    filenamePtr1 = filename->Des();

    User::LeaveIfError( iFileMan->Move( iFname, filenamePtr1, CFileMan::EOverWrite, iStatus ) );
    // waiting for move to complete
    SetActive();
    iFname = filenamePtr1;
    ((*iCodDlData)[mediaObjectIndex])->SetDestFilenameL(filenamePtr1);

    CleanupStack::PopAndDestroy(filename);
 
#endif
    }

// -----------------------------------------------------------------------------
// CHttpDownload::MoveDownloadedMediaObjectSyncL
// ?implementation_description
// (other items were commented in a header).
// -----------------------------------------------------------------------------
//
void CHttpDownload::MoveDownloadedMediaObjectSyncL(TInt mediaObjectIndex)
    {
    LOGGER_ENTERFN( "MoveDownloadedMediaObjectSyncL" );

    if( !iCodDownload && iDlState != EHttpDlMultipleMOCompleted )
        {
        User::Leave( KErrNotReady );
        }

    //__ASSERT_DEBUG( !IsActive(), DMPanic( KErrInUse ) );
    //__ASSERT_DEBUG( !iFileMan, DMPanic( KErrInUse ) );


    
	RFs &fs = iClientApp->Engine()->Fs();
	if(!iFileMan)
		{
		iFileMan = CFileMan::NewL(fs);	
		}

    HBufC* filename = HBufC::NewLC(KMaxFileName);
    TPtr filenamePtr = filename->Des();
    
    TPtrC fileNamePtr = ((*iCodDlData)[mediaObjectIndex])->DestFilename();
    TInt firstSlashPos = fileNamePtr.Locate( '\\' );
    if(firstSlashPos < 0)
	    {
	    CleanupStack::PopAndDestroy(filename);
	    return;	
	    }
  	TPtrC dlName = fileNamePtr.Left(firstSlashPos);
    TInt drive;
    
    User::LeaveIfError( fs.CharToDrive( dlName[0], drive ));


    // Getting RootPath for selected Drive
    TFileName rootPath;
    User::LeaveIfError( PathInfo::GetRootPath( rootPath, drive ) );

    // Setting KDownloadPath
    rootPath.Append( KDownloadPath );

    filenamePtr.Copy(rootPath);
    filenamePtr.Append(_L("\\"));
    
    TInt error = fs.MkDirAll(filenamePtr);
    if (error!=KErrNone && error!=KErrAlreadyExists)
       {
        User::Leave(error);   
       }
    iFname = ((*iCodDlData)[mediaObjectIndex])->DestFilename();
    
    // Find a unique name to avoid any conflict.
    // Here iFname has full path of current location of file
    // and filename has destination path.
    FindUniqueDestinationFileNameL( iFname, filename );
    
    filenamePtr = filename->Des();

    TInt err = iFileMan->Move(iFname, filenamePtr, CFileMan::EOverWrite);
    if(err != KErrNone)
    	{
    	User::LeaveIfError(err);
    	}
    iFname = filenamePtr;
    ((*iCodDlData)[mediaObjectIndex])->SetDestFilenameL(filenamePtr);

    CleanupStack::PopAndDestroy(filename);
 

    }

// -----------------------------------------------------------------------------
// CHttpDownload::FindUniqueDestinationFileNameL
// -----------------------------------------------------------------------------
//
void CHttpDownload::FindUniqueDestinationFileNameL( TDesC& srcFile, HBufC*& destPath )
    {
        HBufC* fileExtention = HBufC::NewLC(KMaxFileName);
        HBufC* fileName = HBufC::NewLC(KMaxFileName);
        TPtr fileNamePtr( fileName->Des() );

        fileNamePtr = srcFile;
        // Retrieve the file extention.
        TInt dotInd = srcFile.LocateReverse( '.' );
        if( dotInd != KErrNotFound )
            // Filename extension found.
            {
            fileExtention->Des().Copy( srcFile.Right( srcFile.Length() - dotInd ) );
            fileNamePtr.Copy( srcFile.Left( dotInd ) );
            }

        // Retrieve the file name (excluding file extention).
        TInt lastSlashPos = fileNamePtr.LocateReverse( '\\' );
        if( lastSlashPos != KErrNotFound )
            // Filename found.
            {
            fileNamePtr.Copy( fileNamePtr.Right( fileNamePtr.Length() - lastSlashPos - 1 ) );
            }

        // Find a unique file name.
        ConvertDownloadNameUniqueL( destPath, fileName, fileExtention );

        // Found. Append file name and extention to destination path.
        destPath->Des().Append( *fileName );
        destPath->Des().Append( *fileExtention );

        CleanupStack::PopAndDestroy( fileName );
        CleanupStack::PopAndDestroy( fileExtention );
    }
    
 
// ---------------------------------------------------------
// CHttpDownload::NotifyMediaGalleryL()
// Notify media gallery about the new file.
// ---------------------------------------------------------
// 
void CHttpDownload::NotifyMediaGalleryL( const TDesC& aFileName )
    {

	LOGGER_ENTERFN( "CHttpDownload::NotifyMediaGalleryL" );
    CLOG_WRITE_1(" notifying Gallery and DcfReposory about move for: %S",&aFileName);
    //
    // Notify Media Gallery about new media file
    CMGXFileManager* mgFileManager = MGXFileManagerFactory::NewFileManagerL(
        iClientApp->Engine()->Fs() );
    CleanupStack::PushL( mgFileManager );
    if( aFileName.Length() > 0 )
        {
        TRAP_IGNORE( mgFileManager->UpdateL( aFileName ) );
        }
    else
        {
        TRAP_IGNORE( mgFileManager->UpdateL() );
        }
    CleanupStack::PopAndDestroy( mgFileManager );
    //
    // Notify DCF repository
    TRAP_IGNORE( UpdateDCFRepositoryL( aFileName ) );
	}
// -----------------------------------------------------------------------------
// CCodSaver::ConvertDownloadNameUniqueL
// -----------------------------------------------------------------------------
//
void CHttpDownload::ConvertDownloadNameUniqueL( HBufC*& filePath,
                                            HBufC*& fileName,
                                            HBufC*& fileExtn)
    {
    TBool bFound( EFalse );
    TInt index( 0 );
    HBufC* uniqueName = NULL;
    HBufC* fullNameTemp = HBufC::NewLC(KMaxFileName);
    TPtr fullNameTempPtr( fullNameTemp->Des() );

    RFs rFs;
  	User::LeaveIfError( rFs.Connect() );
  	CleanupClosePushL(rFs);

    do
        {
        bFound = EFalse;
        //Generate Unique name.
        CreateIndexedNameL( uniqueName, *fileName, index );

        //Name in \\system\\temp.
        fullNameTempPtr.Copy( *filePath );
        fullNameTempPtr.Append( *uniqueName );
        fullNameTempPtr.Append( *fileExtn );

        if( BaflUtils::FileExists( rFs , fullNameTempPtr ) )
            //Check if file name exist in Destination path.
            {
            bFound =ETrue;
            }

        }while( bFound );

    CleanupStack::PopAndDestroy(&rFs);
    CleanupStack::PopAndDestroy(fullNameTemp);
    
    // This is the unique name that we were looking for.
    CleanupStack::PopAndDestroy(fileName);
    fileName = uniqueName;
    CleanupStack::PushL(fileName);
    }

//  End of File