Remerge fix for bug 1961 RCL_3 PDK_3.0.i
authorWilliam Roberts <williamr@symbian.org>
Wed, 28 Apr 2010 22:20:05 +0100
branchRCL_3
changeset 24 3f3e6714b28a
parent 23 4740b34b83ce (diff)
parent 22 8add8cccb322 (current diff)
child 29 d3550a9452ab
Remerge fix for bug 1961
--- a/mmappcomponents/collectionhelper/src/mpxcollectionhelperimp.cpp	Fri Apr 23 13:55:04 2010 +0100
+++ b/mmappcomponents/collectionhelper/src/mpxcollectionhelperimp.cpp	Wed Apr 28 22:20:05 2010 +0100
@@ -407,7 +407,7 @@
     MPX_FUNC("CMPXCollectionHelperImp::RenameL");
     MPX_DEBUG3("aOldUri = %S, aNewUri = %S", &aOldUri, &aNewUri);
 
-    if (aItemCat != EMPXSong && aItemCat != EMPXPlaylist)
+    if (aItemCat != EMPXSong && aItemCat != EMPXPlaylist && aItemCat != EMPXAbstractAlbum)
         {
         User::Leave(KErrArgument);
         }
--- a/mmappcomponents/harvester/filehandler/group/mpxfilehandler.mmp	Fri Apr 23 13:55:04 2010 +0100
+++ b/mmappcomponents/harvester/filehandler/group/mpxfilehandler.mmp	Wed Apr 28 22:20:05 2010 +0100
@@ -69,9 +69,7 @@
 LIBRARY                 mpxmetadataextractor.lib
 LIBRARY	                caf.lib
 LIBRARY                 DrmServerInterfaces.lib
-#ifdef RD_MULTIPLE_DRIVE
 LIBRARY                 PlatformEnv.lib
-#endif //RD_MULTIPLE_DRIVE
 
 #if defined(ARMCC)
 deffile ../eabi/ 
--- a/mmappcomponents/harvester/filehandler/inc/mpxharvesterdbmanager.h	Fri Apr 23 13:55:04 2010 +0100
+++ b/mmappcomponents/harvester/filehandler/inc/mpxharvesterdbmanager.h	Wed Apr 28 22:20:05 2010 +0100
@@ -54,8 +54,7 @@
     TInt OpenAllDatabasesL();
 
     /**
-    * Reopen a particular database
-    * (For MMC events)
+    * Open a particular database
     * @param TDriveNumber aDrive
     */
     void OpenDatabaseL( TDriveNumber aDrive );
@@ -63,26 +62,38 @@
     /**
     * Close all databases
     */
-    void CloseAllDatabase();
+    void CloseAllDatabases();
+    
+    /**
+    * Close all databases on mass storage drives
+    */
+    void CloseMassStorageDatabases();
 
     /**
     * Close a particular DB
-    * (For MMC events)
     * @param TDriveNumber the Drive
     */
     void CloseDatabase( TDriveNumber aDrive );
+    
 
     /**
     * Get a particular database
     * @param TDriveNumber the Drive
     */
     CMPXHarvesterDB& GetDatabaseL( TDriveNumber aDrive );
-
+	
+	/**
+    * Abruptly close a particular DB without trying to access it
+    * To be used when drive is no more accessible
+    * @param TDriveNumber the Drive
+    */
+    void DropDatabase( TDriveNumber aDrive );
+    
     /**
-     * Remove a particular database from the array
-     * @param TDriveNumber the Drive
+     * Return whether database is open on the specified drive
      */
-    void RemoveDatabaseL( TDriveNumber aDrive );
+    TBool DatabaseIsOpen( TDriveNumber aDrive );
+
 
     /**
     * Return the number of databases
@@ -152,6 +163,18 @@
 #endif //__RAMDISK_PERF_ENABLE
 
 private: // new functions
+	
+	 /**
+	  * Find database index in the internal table
+	  * Return KErrNotFound if not found
+	  */
+   TInt FindDatabaseIndex ( TDriveNumber aDrive );
+   
+	 /**
+	  * Return whether drive exists and is local
+	  */
+   TBool IsLocalDrive( TDriveNumber aDrive );
+
     
 #ifdef __RAMDISK_PERF_ENABLE
     /**
@@ -174,7 +197,7 @@
     /**
     * Copy database from RAM disk
     */
-    void DoCopyDBFromRamL(TDriveUnit aDriveUnit); 
+    TInt DoCopyDBFromRam(TDriveUnit aDriveUnit); 
 
     /**
     * To block a disk space so that it can gurantee for a write back from RAM disk
@@ -193,9 +216,9 @@
     /**
     * Remove dummy file
     *
-    * @return TInt index to the database handler
+    * @param aDrive Drive
     */
-    void RemoveDummyFile( TInt aIndex );
+    void RemoveDummyFile( TDriveNumber aDrive );
     
     /**
      * Update the database from ram drive.
--- a/mmappcomponents/harvester/filehandler/inc/mpxharvesterfilehandlerimp.h	Fri Apr 23 13:55:04 2010 +0100
+++ b/mmappcomponents/harvester/filehandler/inc/mpxharvesterfilehandlerimp.h	Wed Apr 28 22:20:05 2010 +0100
@@ -274,6 +274,13 @@
     * for a list of folders to automatically scan
     */
     void ParseAutoScanL();
+    
+    /**
+     * Refreshes scan drives so that non-existing 
+     * drives are not scanned.
+	 * Used add back drives that were take out because of dismount
+     */
+    void RefreshScanDrivesL();
 
     /***
     * Resets the current scan directory and frees memory
@@ -350,13 +357,6 @@
      */
     RPointerArray<CMPXHarvesterDbItem>* GetDrmFilesL();
 
-    /**
-     * Verifies if aDrive is ready.
-     * @param aDrive, certain drive name, such as EDRIVEE
-     * @return TBool ETrue if aDrive is ready,otherwise EFalse
-     */
-    TBool IsDriveReady( TDriveNumber aDrive );
-
 public:
 
     /**
@@ -392,13 +392,12 @@
     RPointerArray<CMPXFolderMonitor>  iFolderMonitors;  // Multiple drives
     RPointerArray<CMPXCollectionType> iSupportedTypes;
     CDesCArray*                       iContainerTypes;
+    RArray<TPath>                     iConfiguredDrivesToScan;
     RArray<TPath>                     iDrivesToScan;
     RArray<TPath>                     iFilteredDrivesToScan;
     RArray<TPath>                     iPathsToBlock;
     TBool                             iOutOfDisk;
-#ifdef RD_MULTIPLE_DRIVE
-    TInt                              iRemovedDrive;
-#endif // RD_MULTIPLE_DRIVE
+    TBool                             iFilteredOutOfDisk;
 
     // Metadata related
     CMPXMetadataScanner*              iMetadataScanner;
--- a/mmappcomponents/harvester/filehandler/inc/mpxmetadatascanner.h	Fri Apr 23 13:55:04 2010 +0100
+++ b/mmappcomponents/harvester/filehandler/inc/mpxmetadatascanner.h	Wed Apr 28 22:20:05 2010 +0100
@@ -20,6 +20,7 @@
 #define CMPXMETADATASCANNER_H
 
 #include <e32base.h>
+#include <mpxmetadataextractorobserver.h>
 
 class CMPXMedia;
 class CMPXMediaArray;
@@ -33,7 +34,8 @@
     ENewFiles = 0,
     EModFiles = 1,
     EMaxFile  = 2
-    };   
+    };
+
 /**
  *  CMPXMetadataScanner
  *
@@ -42,7 +44,8 @@
  *  @lib mpxfilehandler.lib
  *  @since S60 3.0
  */
-NONSHARABLE_CLASS( CMPXMetadataScanner ): public CActive
+NONSHARABLE_CLASS( CMPXMetadataScanner ): public CActive,
+                                          public MMPXMetadataExtractorObserver
     {
 public:
 
@@ -128,15 +131,43 @@
     * From CActive
     */
     void RunL();
+    
+    /**
+     * From MMPXMetadataExtractorObserver
+     */
+    void HandleCreateMediaComplete( CMPXMedia* aMedia, TInt aError );
 
 private: // New Functions
     
     /**
     * Extract metadata from a few files
-    * @return ETrue if there are no more files to extract
-    *         EFalse otherwise
     */
-    TBool DoExtractL(); 
+    void DoExtractL();
+    
+    /**
+     * Get source array
+     */
+    RPointerArray<HBufC>* GetSource();
+    
+    /**
+     * Is metadata scanner done
+     */
+    TBool IsDone();
+    
+    /**
+     * Run again
+     */
+    void RunAgain();
+    
+    /**
+     * Add metadata to collection
+     */
+    void AddToCollectionL();
+    
+    /**
+     * Complete metadata scanner
+     */
+    void MetadataScannerComplete( TInt aError );
         
 private:
 
@@ -160,8 +191,7 @@
     RPointerArray<HBufC>  iNewFiles;
     RPointerArray<HBufC>  iModifiedFiles;
  
-    CMPXMediaArray* iNewFileProps;
-    CMPXMediaArray* iModifiedFileProps;
+    CMPXMediaArray* iTargetProps;
     
     TBool iExtracting;          // Are we extracting
     TInt  iExtractType; // What are we extracting
@@ -170,7 +200,7 @@
     CMPXMetadataExtractor* iExtractor;  // Metadata Utilities wrapper
     
     MMPXMetadataScanObserver& iObserver;
-    MMPXFileScanStateObserver& iStateObserver;   
+    MMPXFileScanStateObserver& iStateObserver;
     };
 
 #endif // CMPXMETADATASCANNER_H
--- a/mmappcomponents/harvester/filehandler/src/mpxfoldermonitor.cpp	Fri Apr 23 13:55:04 2010 +0100
+++ b/mmappcomponents/harvester/filehandler/src/mpxfoldermonitor.cpp	Wed Apr 28 22:20:05 2010 +0100
@@ -17,22 +17,15 @@
 
 
 #include <e32base.h>
-#ifdef RD_MULTIPLE_DRIVE
 #include <pathinfo.h>
 #include <driveinfo.h>
-#endif //RD_MULTIPLE_DRIVE
 #include <mpxlog.h>
 #include "mpxfoldermonitor.h"
 #include "mpxfileadditionobserver.h"
 #include "mpxfoldermonitorobserver.h"
 
 // CONSTANTS
-#ifdef RD_MULTIPLE_DRIVE
 _LIT( KMPXMusicPath, "\\Music\\");
-#else
-_LIT( KMPXMusicPath, "\\Music\\");
-_LIT( KMPXDataPath, "\\Data\\");
-#endif //RD_MULTIPLE_DRIVE
 
 
 // ---------------------------------------------------------------------------
@@ -94,7 +87,6 @@
     delete iFolderName;
     iFolderName = NULL;
 
-#ifdef RD_MULTIPLE_DRIVE
     switch( aDrive )
         {
         case EDriveC:
@@ -135,46 +127,6 @@
             }
         }
     MPX_DEBUG2("CMPXFolderMonitor::Start: Use %S path", iFolderName);
-#else
-    switch( aDrive )
-        {
-        case EDriveC:
-            {
-            TDriveName driveName = TDriveUnit( aDrive ).Name();
-            TInt length = KMPXDataPath().Length() + driveName.Length();
-
-            iFolderName = HBufC::NewL(length);
-
-            TPtr folderPtr( iFolderName->Des() );
-            folderPtr.Append( driveName );
-            folderPtr.Append( KMPXDataPath );
-
-            break;
-            }
-        case EDriveE:
-        // deliberate fall through, same actions for E & F drive
-
-        case EDriveF:
-            {
-
-            TDriveName driveName = TDriveUnit( aDrive ).Name();
-            TInt length = KMPXMusicPath().Length() + driveName.Length();
-
-            iFolderName = HBufC::NewL(length);
-
-            TPtr folderPtr( iFolderName->Des() );
-            folderPtr.Append( driveName );
-            folderPtr.Append( KMPXMusicPath );
-
-            break;
-            }
-
-        default:
-            {
-            User::Leave( KErrNotSupported );
-            }
-        }
-#endif // RD_MULTIPLE_DRIVE
 
     // Start listening
     //
--- a/mmappcomponents/harvester/filehandler/src/mpxfolderscanner.cpp	Fri Apr 23 13:55:04 2010 +0100
+++ b/mmappcomponents/harvester/filehandler/src/mpxfolderscanner.cpp	Wed Apr 28 22:20:05 2010 +0100
@@ -244,9 +244,9 @@
             TInt err(KErrNone);
             do
                 {
-                MPX_DEBUG1("CMPXFolderScanner::SetupNextDriveToScanL iDirScan->NexL()");
+                MPX_DEBUG1("CMPXFolderScanner::SetupNextDriveToScanL iDirScan->NextL()");
                 TRAP(err, iDirScan->NextL(iDir));
-                MPX_DEBUG1("CMPXFolderScanner::SetupNextDriveToScanL path blocked?");
+                MPX_DEBUG2("CMPXFolderScanner::SetupNextDriveToScanL path %S", &iDirScan->FullPath());
                 blocked = iObserver.IsPathBlockedL( iDirScan->FullPath() );
                 MPX_DEBUG2("CMPXFolderScanner::SetupNextDriveToScanL path blocked %i", blocked);
                 if( blocked )
--- a/mmappcomponents/harvester/filehandler/src/mpxharvesterdb.cpp	Fri Apr 23 13:55:04 2010 +0100
+++ b/mmappcomponents/harvester/filehandler/src/mpxharvesterdb.cpp	Wed Apr 28 22:20:05 2010 +0100
@@ -79,11 +79,12 @@
 //
 TInt CMPXHarvesterDB::OpenL()
     {
-    MPX_FUNC("CMPXHarvesterDB::OpenL");
+    MPX_DEBUG1("-->CMPXHarvesterDB::OpenL");
 
     // There is no need to re-open if it was already open
     if( iDBOpen )
         {
+        MPX_DEBUG1("<--CMPXHarvesterDB::OpenL rtn=0 (already open)");
         return KErrNone;
         }
 
@@ -131,6 +132,7 @@
     if( idErr != KErrNone )
         {
         // Delete the database because this is not readable
+        MPX_DEBUG2("CMPXHarvesterDB::OpenL -- Deleting unreadable DB %i", idErr);
         Close();
         User::LeaveIfError(DeleteDatabase());
         rtn = KErrCorrupt;
@@ -144,7 +146,8 @@
         User::LeaveIfError(DeleteDatabase());
         rtn = OpenL();
         }
-
+    
+    MPX_DEBUG2("<--CMPXHarvesterDB::OpenL rtn=%d", rtn);
     return rtn;
     }
 
@@ -294,6 +297,7 @@
         TRAPD(err, iDatabase->OpenL( iStore, iStore->Root() ) );
         if( err != KErrNone )
             {
+            MPX_DEBUG2("CMPXHarvesterDB::OpenDBL RDbStoreDatabase::OpenL error %d", err);
             delete iDatabase;
             iDatabase = NULL;
             CreateDBL();
--- a/mmappcomponents/harvester/filehandler/src/mpxharvesterdbmanager.cpp	Fri Apr 23 13:55:04 2010 +0100
+++ b/mmappcomponents/harvester/filehandler/src/mpxharvesterdbmanager.cpp	Wed Apr 28 22:20:05 2010 +0100
@@ -17,10 +17,8 @@
 
 
 #include <e32base.h>
-#ifdef RD_MULTIPLE_DRIVE
 #include <pathinfo.h>
 #include <driveinfo.h>
-#endif //RD_MULTIPLE_DRIVE
 
 #ifdef __RAMDISK_PERF_ENABLE
 #include <centralrepository.h>
@@ -129,7 +127,7 @@
     TInt count(iDatabases.Count());
     for (TInt i = 0; i < count; ++i)
         {
-        RemoveDummyFile(i);
+        RemoveDummyFile(iDatabases[i]->GetDbDrive());
         }
 #endif // __RAMDISK_PERF_ENABLE
     iDatabases.ResetAndDestroy();
@@ -149,24 +147,18 @@
 
     // Open drives we are interested in.
     //
-#ifdef RD_MULTIPLE_DRIVE
     TDriveList driveList;
     TInt driveCount(0);
     User::LeaveIfError( DriveInfo::GetUserVisibleDrives(
            iFs, driveList, driveCount ) );
 
-    TInt check(KErrNone);
     for( TInt driveNum = EDriveA; driveNum <= EDriveZ; driveNum++ )
         {
-        if (driveList[driveNum] && !IsRemoteDrive(static_cast<TDriveNumber>(driveNum)))
+        if (driveList[driveNum] && IsLocalDrive(static_cast<TDriveNumber>(driveNum)))
             {
-            TFileName drivePath;
-            User::LeaveIfError(
-                PathInfo::GetRootPath( drivePath, driveNum ) );
-            MPX_DEBUG2("CMPXHarvesterDatabaseManager::OpenAllDatabasesL: opening database in %S drive",
-                &drivePath);
-            TRAP( check, GetDatabaseL(static_cast<TDriveNumber>(driveNum)) );
-            if( check == KErrNotFound )
+            MPX_DEBUG2("CMPXHarvesterDatabaseManager::OpenAllDatabasesL: opening database in drive %d", driveNum);
+            TInt index = FindDatabaseIndex ( (TDriveNumber) driveNum );
+            if ( index == KErrNotFound )
                 {
                 MPX_DEBUG1("CMPXHarvesterDatabaseManager::OpenAllDatabasesL: re-creating database");
                 CMPXHarvesterDB* dB = CMPXHarvesterDB::NewL(
@@ -184,62 +176,19 @@
                     CleanupStack::PopAndDestroy( dB );
                     }
                 }
-            else if( check == KErrNone )
+            else
                 {
-                TRAPD(openError, GetDatabaseL(static_cast<TDriveNumber>(driveNum)).OpenL() );
+                CMPXHarvesterDB* dB = iDatabases[index];
+                TRAPD(openError, rtn |= dB->OpenL() );   //lint !e665
                 if(openError != KErrNone)
                     {
                     MPX_DEBUG2("CMPXHarvesterDatabaseManager::OpenAllDatabasesL: opening failed, error=%d, removing database", openError);
-                    TRAP_IGNORE( RemoveDatabaseL(static_cast<TDriveNumber>(driveNum)));
+                    iDatabases.Remove ( index );
+                    delete dB;
                     }
                 }
             }
         }
-#else
-    TInt check(KErrNone);
-    TRAP( check, GetDatabaseL(EDriveC) );
-    if( check == KErrNotFound )
-        {
-        CMPXHarvesterDB* dB = CMPXHarvesterDB::NewL( EDriveC, iFs );
-        CleanupStack::PushL( dB );
-        iDatabases.AppendL( dB );
-        CleanupStack::Pop( dB );
-        TRAP_IGNORE( rtn = dB->OpenL() ); //lint !e665
-        }
-    else if( check == KErrNone )
-        {
-        TRAPD(openError, GetDatabaseL(EDriveC).OpenL() );
-        if(openError != KErrNone)
-            {
-            TRAP_IGNORE( RemoveDatabaseL(EDriveC));
-            }
-        }
-    TRAP( check, GetDatabaseL(EDriveE) );  //lint !e961
-    if( check == KErrNotFound )
-        {
-        CMPXHarvesterDB* dB = CMPXHarvesterDB::NewL( EDriveE, iFs );
-        CleanupStack::PushL( dB );
-        TRAPD(openError, rtn |= dB->OpenL() );  //lint !e665
-        if(openError == KErrNone)
-            {
-             iDatabases.AppendL( dB );
-             CleanupStack::Pop( dB );
-            }
-        else
-            {
-            CleanupStack::PopAndDestroy( dB );
-            }
-        }
-    else if( check == KErrNone )
-        {
-        TRAPD(openError,GetDatabaseL(EDriveE).OpenL() );
-        if(openError != KErrNone)
-            {
-            TRAP_IGNORE( RemoveDatabaseL(EDriveE));
-            }
-        }
-#endif // RD_MULTIPLE_DRIVE
-
     MPX_DEBUG1("CMPXHarvesterDatabaseManager::OpenAllDatabasesL --->");  //lint !e961
     return rtn;
     }
@@ -250,70 +199,172 @@
 //
 void CMPXHarvesterDatabaseManager::OpenDatabaseL( TDriveNumber aDrive )
     {
-    MPX_DEBUG1("CMPXHarvesterDatabaseManager::OpenDatabaseL <---");
+    MPX_DEBUG2("CMPXHarvesterDatabaseManager::OpenDatabaseL %d <---", aDrive);
 
-    // Re-open a specific database
-    //
-    if (!IsRemoteDrive(aDrive))
+    if ( ! IsLocalDrive( aDrive ) )
+        {
+        MPX_DEBUG1("CMPXHarvesterDatabaseManager::OpenDatabaseL drive not available -->");
+        return;
+        }
+
+    CMPXHarvesterDB * db = NULL;
+    TInt index = FindDatabaseIndex ( aDrive );
+    if ( index == KErrNotFound )
         {
-        TInt count( iDatabases.Count() );
-        for( TInt i=0; i<count; ++i )
-            {
-            CMPXHarvesterDB* db = (CMPXHarvesterDB*) iDatabases[i];
-            if( db->GetDbDrive() == aDrive )
-                {
-                db->OpenL();
-                break;
-                }
-            }
+        db = CMPXHarvesterDB::NewL( aDrive, iFs );
+        CleanupStack::PushL( db );
+        iDatabases.AppendL( db );
+        CleanupStack::Pop( db );
+        }
+    else
+        {
+        db = iDatabases[index];
+        }
+
+    // TRAPD(openError, rtn |= dB->OpenL() );  //lint !e665
+    TRAPD( openError, db->OpenL() );
+    if( openError != KErrNone )
+        {
+        MPX_DEBUG2("CMPXHarvesterDatabaseManager::OpenAllDatabasesL: opening failed, error=%d", openError);
+        iDatabases.Remove(index);
+        delete db;
         }
     MPX_DEBUG1("CMPXHarvesterDatabaseManager::OpenDatabaseL --->");
     }
 
 // ---------------------------------------------------------------------------
-// CMPXHarvesterDatabaseManager::CloseAllDatabase
+// CMPXHarvesterDatabaseManager::CloseAllDatabases
 // ---------------------------------------------------------------------------
 //
-void CMPXHarvesterDatabaseManager::CloseAllDatabase()
+void CMPXHarvesterDatabaseManager::CloseAllDatabases()
     {
     // Close all databases for shutdown
     iDatabases.ResetAndDestroy();
     }
 
+
+// ---------------------------------------------------------------------------
+// CMPXHarvesterDatabaseManager::CloseMassStorageDatabases
+// ---------------------------------------------------------------------------
+//
+void CMPXHarvesterDatabaseManager::CloseMassStorageDatabases()
+    {
+    MPX_FUNC("CMPXHarvesterDatabaseManager::CloseMassStorageDatabases");
+    for (TInt i = 0; i < iDatabases.Count();)
+        {
+        CMPXHarvesterDB * db =iDatabases [i];
+        TDriveNumber drive = db->GetDbDrive();
+        if ( drive != EDriveC )
+            {
+            MPX_DEBUG2("CMPXHarvesterDatabaseManager::CloseMassStorageDatabases closing DB on drive %d", drive);
+        	  db->Close();
+#ifdef __RAMDISK_PERF_ENABLE                
+            if( iRAMDiskPerfEnabled && db->IsUseRamDrive() )
+                {
+                MPX_DEBUG1("CMPXHarvesterDatabaseManager::CloseDatabase DB is on RAM");
+                db->SetRamDriveInfo( iRAMDrive, EFalse ); 
+                TInt err = DoCopyDBFromRam (drive);
+                if ( err )
+                    {
+                    MPX_DEBUG2("CMPXHarvesterDatabaseManager::CloseDatabase DB copy error=%d", err);                
+                    RemoveDummyFile( drive );
+                    }
+                }
+#endif
+            delete db;
+            iDatabases.Remove(i);
+            }
+        else
+            {
+            ++i;
+            }
+        }
+    }
+
 // ---------------------------------------------------------------------------
 // CMPXHarvesterDatabaseManager::CloseDatabase
 // ---------------------------------------------------------------------------
 //
 void CMPXHarvesterDatabaseManager::CloseDatabase( TDriveNumber aDrive )
     {
-     if (!IsRemoteDrive(aDrive))
+    MPX_DEBUG2("-->CMPXHarvesterDatabaseManager::CloseDatabase drive %d", aDrive );
+    TInt index = FindDatabaseIndex( aDrive );
+    if ( index != KErrNotFound )
         {
-        MPX_DEBUG2("CMPXHarvesterDatabaseManager::CloseDatabase drive %d <---", aDrive );
-        TInt count = iDatabases.Count();
-        for ( TInt i=0; i<count; ++i)
-            {
-            CMPXHarvesterDB* db = (CMPXHarvesterDB*) iDatabases[i];
-            if ( db->GetDbDrive() == aDrive)
-                {
-                db->Close();
+        CMPXHarvesterDB * db =iDatabases[index];
+        db->Close();
 #ifdef __RAMDISK_PERF_ENABLE                
-                if( iRAMDiskPerfEnabled && db->IsUseRamDrive() )
-                    {
-                    MPX_DEBUG1("CMPXHarvesterDatabaseManager::CloseDatabase DB is on RAM");
-                    db->SetRamDriveInfo( iRAMDrive, EFalse ); 
-                    TRAPD( err, DoCopyDBFromRamL(aDrive) );
-                    if ( err )
-                        {
-                        MPX_DEBUG2("CMPXHarvesterDatabaseManager::CloseDatabase DB copy error=%d", err);                
-                        RemoveDummyFile(i);
-                        }
-                    }
-#endif
-                break;
+        if( iRAMDiskPerfEnabled && db->IsUseRamDrive() )
+            {
+            MPX_DEBUG1("CMPXHarvesterDatabaseManager::CloseDatabase DB is on RAM");
+            db->SetRamDriveInfo( iRAMDrive, EFalse ); 
+            TInt err = DoCopyDBFromRam(aDrive);
+            if ( err )
+                {
+                MPX_DEBUG2("CMPXHarvesterDatabaseManager::CloseDatabase DB copy error=%d", err);                
+                RemoveDummyFile( aDrive );
                 }
             }
+#endif
+        delete db;
+        iDatabases.Remove(index);
         }
-    MPX_DEBUG1("CMPXHarvesterDatabaseManager::CloseDatabase --->");
+    MPX_DEBUG1("<--CMPXHarvesterDatabaseManager::CloseDatabase");
+    }
+
+// ---------------------------------------------------------------------------
+// CMPXHarvesterDatabaseManager::DropDatabase
+// ---------------------------------------------------------------------------
+//
+void CMPXHarvesterDatabaseManager::DropDatabase( TDriveNumber aDrive )
+    {
+    MPX_DEBUG2("CMPXHarvesterDatabaseManager::DropDatabase drive %d <---", aDrive );
+    TInt index = FindDatabaseIndex( aDrive );
+    if ( index != KErrNotFound )
+        {
+        CMPXHarvesterDB * db =iDatabases[index];
+#ifdef __RAMDISK_PERF_ENABLE                
+        if( iRAMDiskPerfEnabled && db->IsUseRamDrive() )
+            {
+            MPX_DEBUG1("CMPXHarvesterDatabaseManager::DropDatabase DB is on RAM");
+            db->Close();
+            // delete db on ram drive.
+            TFileName src = GenerateHarvesterDbName( TDriveUnit(aDrive), ETrue );
+            BaflUtils::DeleteFile(iFs, src);
+            }
+#endif
+        delete db;
+        iDatabases.Remove(index);
+        }
+    MPX_DEBUG1("CMPXHarvesterDatabaseManager::DropDatabase --->");
+    }
+// ---------------------------------------------------------------------------
+// CMPXHarvesterDatabaseManager::FindDatabaseIndex
+// ---------------------------------------------------------------------------
+//
+TInt CMPXHarvesterDatabaseManager::FindDatabaseIndex ( TDriveNumber aDrive )
+    {
+    TInt count = iDatabases.Count();
+    for( TInt i=0; i<count; ++i )
+        {
+        CMPXHarvesterDB* db = (CMPXHarvesterDB*) iDatabases[i];
+        if( db->GetDbDrive() == aDrive )
+            {
+            MPX_DEBUG3("CMPXHarvesterDatabaseManager::FindDatabaseIndex drive=%d returns index %d ", aDrive, i);
+            return i;
+            }
+        }
+    MPX_DEBUG2("CMPXHarvesterDatabaseManager::FindDatabaseIndex drive=%d returns KErrNotFound", aDrive);
+    return KErrNotFound;
+    }
+
+// ---------------------------------------------------------------------------
+// CMPXHarvesterDatabaseManager::DataaseIsOpen
+// ---------------------------------------------------------------------------
+//
+TBool CMPXHarvesterDatabaseManager::DatabaseIsOpen( TDriveNumber aDrive )
+    {
+    return FindDatabaseIndex( aDrive ) != KErrNotFound;
     }
 
 // ---------------------------------------------------------------------------
@@ -322,54 +373,9 @@
 //
 CMPXHarvesterDB& CMPXHarvesterDatabaseManager::GetDatabaseL( TDriveNumber aDrive )
     {
-    CMPXHarvesterDB* db( NULL );
-
-    // Find the database
-    TInt count = iDatabases.Count();
-    for( TInt i=0; i<count; ++i )
-        {
-        CMPXHarvesterDB* tmp = (CMPXHarvesterDB*) iDatabases[i];
-        if( tmp->GetDbDrive() == aDrive )
-            {
-            db = tmp;
-            break;
-            }
-        }
-
-    // Not found, so we leave
-    if( db == NULL )
-        {
-        User::Leave( KErrNotFound );
-        }
-    return *db;
-    }
-
-// ---------------------------------------------------------------------------
-// CMPXHarvesterDatabaseManager::RemoveDatabase
-// ---------------------------------------------------------------------------
-//
-void CMPXHarvesterDatabaseManager::RemoveDatabaseL( TDriveNumber aDrive )
-    {
-
-    TBool bFound(EFalse);
-    // Find the database
-    TInt count = iDatabases.Count();
-    for(TInt index=0; index<count; ++index )
-        {
-        if((iDatabases[index]!=NULL) && ( iDatabases[index]->GetDbDrive() == aDrive ))
-            {
-            bFound = ETrue;
-            delete iDatabases[index];
-            iDatabases.Remove(index);
-            break;
-            }
-        }
-
-    // Not found, so we leave
-    if( !bFound )
-        {
-        User::Leave( KErrNotFound );
-        }
+    TInt index = FindDatabaseIndex( aDrive );
+    User::LeaveIfError (index); // Not found, so we leave
+    return *iDatabases[index];
     }
 
 // ---------------------------------------------------------------------------
@@ -402,17 +408,27 @@
     {
     MPX_DEBUG1("CMPXHarvesterDatabaseManager::RecreateDatabases <--");
     TInt count( iDatabases.Count() );
-    for( TInt i=0; i<count; ++i )
+    for( TInt i=0; i<count; )
         {
         // Close db, delete and recreate
         //
         MPX_DEBUG2("RecreateDatabasesL() -- %i", i);
-        CMPXHarvesterDB* cur = (CMPXHarvesterDB*)iDatabases[i];
+        CMPXHarvesterDB* cur = iDatabases[i];
         cur->Close();
         cur->DeleteDatabase();
         // trap leave just in case 1 db had err
         //
-        TRAP_IGNORE( cur->OpenL() );
+        TRAPD( openError, cur->OpenL() );
+        if( openError != KErrNone )
+            {
+            MPX_DEBUG2("CMPXHarvesterDatabaseManager::RecreateDatabases: opening failed, error=%d", openError);
+            iDatabases.Remove(i);
+            delete cur;
+            }
+        else 
+            {
+            ++i;
+            }
         }
     }
 
@@ -433,6 +449,18 @@
     }
 
 // ---------------------------------------------------------------------------
+// CMPXHarvesterDatabaseManager::IsLocalDrive
+// ---------------------------------------------------------------------------
+//
+TBool CMPXHarvesterDatabaseManager::IsLocalDrive( TDriveNumber aDrive )
+    {
+    TDriveInfo driveInfo;
+    return (iFs.Drive ( driveInfo, aDrive) == KErrNone )
+           && driveInfo.iType != EMediaNotPresent 
+           && ! (driveInfo.iDriveAtt & KDriveAttRemote);
+    }
+
+// ---------------------------------------------------------------------------
 // CMPXHarvesterDatabaseManager::BeginL
 // ---------------------------------------------------------------------------
 // 
@@ -551,7 +579,7 @@
                 {
                 MPX_DEBUG2("CMPXHarvesterDatabaseManager::CopyDBsToRamL error=%d", err);
                 // delete dummy file
-                RemoveDummyFile(i);
+                RemoveDummyFile( (TDriveNumber)(TInt)drive );
                 
                 // delete db in ram drive
                 TFileName ramDb = GenerateHarvesterDbName( drive, ETrue );
@@ -626,7 +654,7 @@
             TRAP( err, iDatabases[i]->SetDbStateL(EDbClose) );
             if ( err == KErrNone )
                 {
-                TRAP( err, DoCopyDBFromRamL(drive) );
+                err = DoCopyDBFromRam(drive);
                 }
             else
                 {
@@ -640,7 +668,7 @@
                 {
                 MPX_DEBUG2("CMPXHarvesterDatabaseManager::CopyDBsFromRamL copy error=%d", err);                
                 //anyting wrong, delete the temp file.
-                RemoveDummyFile(i);
+                RemoveDummyFile( (TDriveNumber)(TInt)drive );
                 }
 
             // Restore the db state.
@@ -655,40 +683,39 @@
     }
 
 // ---------------------------------------------------------------------------
-// CMPXHarvesterDatabaseManager::DoCopyDBFromRamL
+// CMPXHarvesterDatabaseManager::DoCopyDBFromRam
 // ---------------------------------------------------------------------------
 //
-void CMPXHarvesterDatabaseManager::DoCopyDBFromRamL(TDriveUnit aDriveUnit)
+TInt CMPXHarvesterDatabaseManager::DoCopyDBFromRam(TDriveUnit aDriveUnit)
     {
-    MPX_FUNC("CMPXHarvesterDatabaseManager::DoCopyDBFromRamL");
+    MPX_FUNC("CMPXHarvesterDatabaseManager::DoCopyDBFromRam");
     TFileName dst;
     TFileName src;
     TInt err = KErrNone;
     
     dst = GenerateHarvesterDbName( aDriveUnit );
     src = GenerateHarvesterDbName( aDriveUnit, ETrue );
-    MPX_DEBUG3("CMPXHarvesterDatabaseManager::DoCopyDBFromRamL from %S to %S", &src, &dst );
+    MPX_DEBUG3("CMPXHarvesterDatabaseManager::DoCopyDBFromRam from %S to %S", &src, &dst );
 
     TFileName dummyDbFileName = GenerateDummyDbName( aDriveUnit ); 
 
     //Copy Db from RAM to replace dummy file
     err = BaflUtils::CopyFile(iFs, src, dummyDbFileName);
-    MPX_DEBUG2("CMPXHarvesterDatabaseManager::DoCopyDBFromRamL database copied from ram drive err=%d.", err);
+    MPX_DEBUG2("CMPXHarvesterDatabaseManager::DoCopyDBFromRam database copied from ram drive err=%d.", err);
     
     // delete db on ram drive.
     TInt delErr = BaflUtils::DeleteFile(iFs, src);
-    MPX_DEBUG3("CMPXHarvesterDatabaseManager::DoCopyDBFromRamL db on ram drive deleted file=%S, err=%d", &src, delErr);
+    MPX_DEBUG3("CMPXHarvesterDatabaseManager::DoCopyDBFromRam db on ram drive deleted file=%S, err=%d", &src, delErr);
 
-    // Make sure we del db from ram drive before leaving.
-    User::LeaveIfError( err );
+    // Make sure we del db from ram drive before returning.
+    if (err != KErrNone)
+        {
+        return err;
+        }
     
-    // Delete existing DB on drive
-    delErr = BaflUtils::DeleteFile(iFs, dst);
-    MPX_DEBUG2("CMPXHarvesterDatabaseManager::DoCopyDBFromRamL destination file deleted err=%d", delErr);
-
-    // rename dummy file to real db name
-    User::LeaveIfError( BaflUtils::RenameFile(iFs, dummyDbFileName, dst) );
-    MPX_DEBUG1("CMPXHarvesterDatabaseManager::DoCopyDBFromRamL dummy file renamed.");
+    err = iFs.Replace(dummyDbFileName, dst);
+    MPX_DEBUG2("CMPXHarvesterDatabaseManager::DoCopyDBFromRam dummy file replaced, err=%d.", err);
+    return err;
     }
 
 // ---------------------------------------------------------------------------
@@ -872,12 +899,11 @@
 // CMPXHarvesterDatabaseManager::RemoveDummyFile
 // ---------------------------------------------------------------------------
 //
-void CMPXHarvesterDatabaseManager::RemoveDummyFile( TInt aIndex )
+void CMPXHarvesterDatabaseManager::RemoveDummyFile( TDriveNumber aDrive )
     {
     MPX_FUNC("CMPXHarvesterDatabaseManager::RemoveDummyFile");
     
-    TDriveUnit driveUnit(iDatabases[aIndex]->GetDbDrive());
-    TFileName file = GenerateDummyDbName(driveUnit);
+    TFileName file = GenerateDummyDbName(TDriveUnit(aDrive));
     
     if ( (file.Length() > 0) &&
          (BaflUtils::FileExists(iFs, file)) )
--- a/mmappcomponents/harvester/filehandler/src/mpxharvesterfilehandlerimp.cpp	Fri Apr 23 13:55:04 2010 +0100
+++ b/mmappcomponents/harvester/filehandler/src/mpxharvesterfilehandlerimp.cpp	Wed Apr 28 22:20:05 2010 +0100
@@ -12,7 +12,7 @@
 * Contributors:
 *
 * Description:  Handles all file related activities
-*  Version     : %version: da1mmcf#72.1.14.2.4.1.4.1.2.1.4 % << Don't touch! Updated by Synergy at check-out.
+*  Version     : %version: da1mmcf#72.1.14.2.4.1.4.1.2.1.6 % << Don't touch! Updated by Synergy at check-out.
 *
 */
 
@@ -20,10 +20,8 @@
 #include <e32base.h>
 #include <f32file.h>
 #include <centralrepository.h>
-#ifdef RD_MULTIPLE_DRIVE
 #include <pathinfo.h>
 #include <driveinfo.h>
-#endif //RD_MULTIPLE_DRIVE
 
 #include <mpxlog.h>
 #include <mpxharvestercommon.h>
@@ -124,7 +122,6 @@
     
     // List of watchers for different drives
     //
-#ifdef RD_MULTIPLE_DRIVE
     TDriveList driveList;
     TInt driveCount(0);
     User::LeaveIfError( DriveInfo::GetUserVisibleDrives(
@@ -141,17 +138,6 @@
             CleanupStack::Pop( dw );
             }
         }
-#else
-    CMPXDiskSpaceWatcher* dw_e = CMPXDiskSpaceWatcher::NewL( iFs, EDriveE, *this );
-    CleanupStack::PushL( dw_e );
-    iDiskMonitors.AppendL( dw_e );
-    CleanupStack::Pop( dw_e );
-    CMPXDiskSpaceWatcher* dw_c = CMPXDiskSpaceWatcher::NewL( iFs, EDriveC, *this );
-    CleanupStack::PushL( dw_c );
-    iDiskMonitors.AppendL( dw_c );
-    CleanupStack::Pop( dw_c );
-#endif // RD_MULTIPLE_DRIVE
-   
 
     TInt openerr = iDBManager->OpenAllDatabasesL();
     
@@ -187,6 +173,7 @@
     // Get the scan drives from cenrep.
     //
     ParseScanPathL();
+    RefreshScanDrivesL();
 
     // Get the list of container types
     iContainerTypes = new(ELeave) CDesCArrayFlat(2);  // granularity
@@ -214,13 +201,6 @@
     iDbSynchronizer = CMPXDbSynchronizer::NewL(*this,*iDBManager,iMusicCollectionId,
                                                iPodcastCollectionId,iFs, iDisablePodcasting);
 
-#ifdef RD_MULTIPLE_DRIVE
-    // Use default MMC drive as the Removable drive
-    User::LeaveIfError( DriveInfo::GetDefaultDrive(
-        DriveInfo::EDefaultRemovableMassStorage,
-        iRemovedDrive ) );
-#endif
-
     // Create DRM Notifier and register for AddRemove event
     iDrmNotifier = CDRMNotifier::NewL();
     iDrmNotifier->RegisterEventObserverL( *this, KEventAddRemove );
@@ -270,11 +250,9 @@
         }
     delete iContainerTypes;
 
-    iFilteredDrivesToScan.Reset();
     iFilteredDrivesToScan.Close();
-    iDrivesToScan.Reset();
     iDrivesToScan.Close();
-    iPathsToBlock.Reset();
+    iConfiguredDrivesToScan.Close();
     iPathsToBlock.Close();
 
     // Cleans up the scanning tables and arrays
@@ -337,14 +315,12 @@
    
     iCollectionUtil->Collection().NotifyL( EMcMsgRefreshStart, KErrNone );
 
-    // Reopen databases
-    iDBManager->OpenAllDatabasesL();
-
     // Begin transaction on databases
     iDBManager->BeginL();
     
     //Remove out of disk space drives from scanned drives list
     iFilteredDrivesToScan.Reset();
+    iFilteredOutOfDisk = EFalse;
     CopyArrayL(iDrivesToScan.Array(),iFilteredDrivesToScan);
 
     iOutOfDisk = EFalse;
@@ -371,6 +347,7 @@
                 if (currentDriveNumber == driveNumber)
                     {
                     iFilteredDrivesToScan.Remove(index);
+                    iFilteredOutOfDisk = ETrue;
                     count--;
                     }
                 else
@@ -378,7 +355,7 @@
                     index++;
                     }
                 }
-            TRAP_IGNORE(iDBManager->RemoveDatabaseL(static_cast<TDriveNumber>(currentDriveNumber)));
+            iDBManager->CloseDatabase(static_cast<TDriveNumber>(currentDriveNumber));
             }
         }
 
@@ -440,7 +417,6 @@
     // 6: MTP end we re-open all db, files added already, restart monitor
     // 7: Disk dismount: stop scanning, close the dismounting DB
     //
-#ifdef RD_MULTIPLE_DRIVE
     // Get all visible drives
     TDriveList driveList;
     TInt driveCount(0);
@@ -473,127 +449,64 @@
                 (driveStatus&DriveInfo::EDriveFormatted)?&driveFormatted:&driveNotFormatted);
             }
         }
-#endif //RD_MULTIPLE_DRIVE
+
     switch( aEvent )
         {
         case EFormatStartEvent:
             {
-            MPX_DEBUG1("Disk Format start event");
+            MPX_DEBUG2("Disk Format start event, drive %d", aData);
+            iIdle->Cancel();
             CancelScan();
             iDBManager->CloseDatabase( (TDriveNumber) aData );
+            RefreshScanDrivesL();
             break;
             }
         case EDiskRemovedEvent:
             {
-            MPX_DEBUG1("Disk Removed event");
+            MPX_DEBUG2("Disk Removed event, drive %d", aData);
             iIdle->Cancel();
             CancelScan();
-#ifdef RD_MULTIPLE_DRIVE
-            TBool dbClosed( EFalse );
-            for( TInt driveNum = EDriveA; driveNum <= EDriveZ; driveNum++ )
-                {
-                if (driveList[driveNum] && (!iDBManager->IsRemoteDrive(static_cast<TDriveNumber>(driveNum))))
-                    {
-                    TUint driveStatus(0);
-                    User::LeaveIfError( DriveInfo::GetDriveStatus(
-                        iFs, driveNum, driveStatus ) );
-                    if (!(driveStatus & DriveInfo::EDrivePresent ))
-                        {
-                        // Close database for non-present drive
-                        iDBManager->CloseDatabase( (TDriveNumber) driveNum );
-                        // Save the drive
-                        iRemovedDrive = driveNum;
-                        dbClosed = ETrue;
-                        break;
-                        }
-                    }
-                }
-            
-            if( !dbClosed )
-                {
-                // GetUserVisibleDrives / RFs::DriveList does not return drive at all
-                // if it is dismounted using file server methods. This occurs at least
-                // when removing card using power menu eject. 
-                // If the drive reported as removed is not ready, close db on that drive.
-                TUint driveStatus(0);
-                TInt err( DriveInfo::GetDriveStatus( iFs, aData, driveStatus ) );
-                MPX_DEBUG4("Drive %d status 0x%x, err %d", aData, driveStatus, err);
-                if( err == KErrNotReady )
-                    {
-                    iDBManager->CloseDatabase( (TDriveNumber) aData );
-                    iRemovedDrive = aData;
-                    }
-                }
-#else
-            iDBManager->CloseDatabase( (TDriveNumber) aData );
-#endif // RD_MULTIPLE_DRIVE
+            iDBManager->DropDatabase ( TDriveNumber( aData ) );
+            RefreshScanDrivesL();
             break;
             }
         case EFormatEndEvent:
             {
-            MPX_DEBUG1("Disk Format end event");
+            MPX_DEBUG2("Disk Format end event, drive %d", aData);
             CancelScan();
             iDBManager->OpenDatabaseL( (TDriveNumber) aData );
+            RefreshScanDrivesL();
             break;
             }
         case EDiskInsertedEvent:
             {
-            MPX_DEBUG1("Disk Insert event");
+            MPX_DEBUG2("Disk Insert event %d", aData);
             CancelScan();
-#ifdef RD_MULTIPLE_DRIVE
-            iDBManager->OpenDatabaseL( (TDriveNumber) iRemovedDrive );
-#else
             iDBManager->OpenDatabaseL( (TDriveNumber) aData );
-#endif // RD_MULTIPLE_DRIVE
+            RefreshScanDrivesL();
             break;
             }
         case EUSBMassStorageStartEvent:
             {
             if (iCurUSBEvent == EUSBMassStorageStartEvent)
-            	{
-            	break;
-            	}            
+                {
+                break;
+                }            
             iIdle->Cancel();
+            iDBManager->CloseMassStorageDatabases();
+            RefreshScanDrivesL();
             CancelScan();
-#ifdef RD_MULTIPLE_DRIVE
-            // Close all databases other than the phone memory database
-            for( TInt driveNum = EDriveA; driveNum <= EDriveZ; driveNum++ )
-                {
-                if (driveList[driveNum]  && (!iDBManager->IsRemoteDrive(static_cast<TDriveNumber>(driveNum))))
-                    {
-                    if ( driveNum != EDriveC )
-                        {
-                        iDBManager->CloseDatabase( (TDriveNumber) driveNum );
-                        }
-                    }
-                }
-#else
-            iDBManager->CloseDatabase( (TDriveNumber) aData );
-#endif // RD_MULTIPLE_DRIVE
             iCurUSBEvent = EUSBMassStorageStartEvent;
             break;
             }
         case EUSBMassStorageEndEvent:
             {
-#ifdef RD_MULTIPLE_DRIVE
-            // Open all databases other than the phone memory
-            for( TInt driveNum = EDriveA; driveNum <= EDriveZ; driveNum++ )
-                {
-                if (driveList[driveNum] && (!iDBManager->IsRemoteDrive(static_cast<TDriveNumber>(driveNum))))
-                    {
-                    if ( driveNum != EDriveC )
-                        {
-                        iDBManager->OpenDatabaseL( (TDriveNumber) driveNum );
-                        }
-                    }
-                }
-#else
-            iDBManager->OpenDatabaseL( (TDriveNumber) aData );
-#endif // RD_MULTIPLE_DRIVE
+            iDBManager->OpenAllDatabasesL();
+            RefreshScanDrivesL();
             iCurUSBEvent = EUSBMassStorageEndEvent;
             break;
             }
-        case EUSBMTPNotActiveEvent: // deliberate fall through
+        case EUSBMTPNotActiveEvent:
             {
             if (iCurUSBEvent == EUSBMTPNotActiveEvent)
             	{
@@ -612,21 +525,14 @@
             {
             CancelScan();
             iCurUSBEvent = EUSBMTPStartEvent;
-            // nothing to do, db is needed for MTP
 #ifdef __RAMDISK_PERF_ENABLE
-            // if statement needed because of fall through above.
-            if ( aEvent == EUSBMTPStartEvent )
-                {
-                // copy dbs to ram drive
-                iDBManager->CopyDBsToRamL(ETrue);
-                }
+            iDBManager->CopyDBsToRamL(ETrue);
 #endif //__RAMDISK_PERF_ENABLE
             break;
             }
         case EUSBMTPEndEvent:
             {
             iCurUSBEvent = EUSBMTPEndEvent;
-            // nothing to do, db is updated by MTP
 #ifdef __RAMDISK_PERF_ENABLE
             // copy dbs from ram drive
             iDBManager->CopyDBsFromRamL();
@@ -636,8 +542,17 @@
         case EDiskDismountEvent:
             {
             MPX_DEBUG2("Disk dismount notification, drive %d", aData);
+            iIdle->Cancel();
+            if ( aData < 0 )
+                {
+                iDBManager->CloseMassStorageDatabases();
+                }
+            else
+                {
+                iDBManager->CloseDatabase( (TDriveNumber) aData );
+                }
+            RefreshScanDrivesL();
             CancelScan();
-            iDBManager->CloseDatabase( (TDriveNumber) aData );
             break;
             }
         default:
@@ -930,9 +845,10 @@
 //
 void CMPXHarvesterFileHandlerImp::RecreateDatabases()
     {
-    MPX_DEBUG1("CMPXHarvesterFileHandlerImp::RecreateDatabasesL <--");
+    MPX_DEBUG1("CMPXHarvesterFileHandlerImp::RecreateDatabases <--");
     iDBManager->RecreateDatabases();
-    MPX_DEBUG1("CMPXHarvesterFileHandlerImp::RecreateDatabasesL -->");
+    TRAP_IGNORE(RefreshScanDrivesL());
+    MPX_DEBUG1("CMPXHarvesterFileHandlerImp::RecreateDatabases -->");
     }
 
 // ---------------------------------------------------------------------------
@@ -1259,18 +1175,24 @@
 //
 void CMPXHarvesterFileHandlerImp::HandleDirectoryChangedL( const TDesC& aPath )
     {
+    MPX_DEBUG2("--->CMPXHarvesterFileHandlerImp::HandleDirectoryChangedL path=%S", &aPath);
     // Delay the scanning for a few seconds so the files are finished
     // copying. If already active, means we just append onto the list
-    //
-    iAutoScanPaths.AppendL( aPath );
-    if( !iIdle->IsActive() )
+    // But don't scan if there is no DB == drive does not exist any more
+    TParsePtrC parse( aPath );
+    TDriveUnit drive ( parse.Drive() );
+    if ( iDBManager->DatabaseIsOpen ((TDriveNumber) (TInt) drive) )
         {
-        TCallBack cb( Callback, this );
-        iIdle->Start( TTimeIntervalMicroSeconds32( KAutoScanDelay ),
-                      TTimeIntervalMicroSeconds32( KAutoScanAfter ),
-                      cb );
+        MPX_DEBUG1("CMPXHarvesterFileHandlerImp::HandleDirectoryChangedL adding in iAutoScanPaths");
+        iAutoScanPaths.AppendL( aPath );
+        if( !iIdle->IsActive() )
+            {
+            TCallBack cb( Callback, this );
+            iIdle->Start( TTimeIntervalMicroSeconds32( KAutoScanDelay ),
+                          TTimeIntervalMicroSeconds32( KAutoScanAfter ),
+                          cb );
+            }
         }
-
     }
 
 // ---------------------------------------------------------------------------
@@ -1280,6 +1202,7 @@
 void CMPXHarvesterFileHandlerImp::HandleOpenDriveL( TDriveNumber aDrive,
                                                     const TDesC& aFolder )
     {
+    MPX_DEBUG3("--->CMPXHarvesterFileHandlerImp::HandleOpenDriveL drive=%d, folder=%S", aDrive, &aFolder);
 #ifdef __PRINTDB__
     if( iCurTable )
         iCurTable->PrintItemsInTableL();
@@ -1294,13 +1217,7 @@
     // EnsureRamSpaceL will copy dbs from ram if ram space is low or dbs exceeded max space.
     iDBManager->EnsureRamSpaceL();
 #endif // __RAMDISK_PERF_ENABLE
-    MPX_TRAPD( err, iCurDB = &iDBManager->GetDatabaseL( aDrive ) );
-    if ( err != KErrNone )
-        {
-        iDBManager->OpenAllDatabasesL();
-        iCurDB = &iDBManager->GetDatabaseL( aDrive );
-        }
-    
+    iCurDB = &iDBManager->GetDatabaseL( aDrive );
     if( iDrivesToScan.Find( aFolder ) != KErrNotFound )
         {
         iCurTable = iCurDB->OpenAllFilesTableL();
@@ -1310,6 +1227,7 @@
         iCurTable = iCurDB->OpenDirectoryL( aFolder );
         }
     iCurList = iCurTable->CreateTableRepresentationL();
+    MPX_DEBUG1("<--CMPXHarvesterFileHandlerImp::HandleOpenDriveL");
     }
 
 // ---------------------------------------------------------------------------
@@ -1834,7 +1752,7 @@
 
     MPX_DEBUG2("ParseScanPathL scanPaths: %S", &scanPath);
     MPX_DEBUG2("ParseScanPathL blockPaths: %S", &blockPath);
-    ::ExtractTokensL( scanPath, iDrivesToScan );
+    ::ExtractTokensL( scanPath, iConfiguredDrivesToScan );
     ::ExtractTokensL( blockPath, iPathsToBlock );
     }
 
@@ -1902,6 +1820,25 @@
     }
 
 // ---------------------------------------------------------------------------
+// Refreshes scan drives
+// ---------------------------------------------------------------------------
+//
+void CMPXHarvesterFileHandlerImp::RefreshScanDrivesL()
+    {
+    iDrivesToScan.Reset();
+    for (TInt i = 0; i < iConfiguredDrivesToScan.Count(); ++i)
+        {
+        const TDesC& path = iConfiguredDrivesToScan[i];
+        TParsePtrC parse(path);
+        TDriveUnit drive(parse.Drive());
+        if ( iDBManager->DatabaseIsOpen( (TDriveNumber)(TInt) drive) )
+            {
+            iDrivesToScan.AppendL(path);
+            }
+        }
+    }
+    
+// ---------------------------------------------------------------------------
 // Resets the scanning table and array
 // ---------------------------------------------------------------------------
 //
@@ -2018,10 +1955,7 @@
     // If no error or cancel, return the final number of items added
     MPX_DEBUG2("Scan error %i", aErr );
     
-    // Reopen databases (in case we removed them for out of disk drives before scan)
-    iDBManager->OpenAllDatabasesL();
-    
-    if( aErr == KErrNone )
+    if( aErr == KErrNone || aErr == KErrCancel )
         {
         // Commit the changes on databases in transaction
         iDBManager->CommitL();
@@ -2037,12 +1971,27 @@
     iDBManager->CopyDBsFromRamL();
 #endif //__RAMDISK_PERF_ENABLE
 
+    // Reopen databases (in case we removed them for out of disk drives before scan)
+    for (TInt i = 0, j = 0; i < iDrivesToScan.Count(); ++i)
+        {
+        if ( j < iFilteredDrivesToScan.Count() && ! iDrivesToScan[i].Compare( iFilteredDrivesToScan[j] ) )
+            {
+             ++j;
+            }
+        else
+            {
+            TParsePtrC fileNameParser ( iDrivesToScan[i] );
+            TDriveUnit drive ( fileNameParser.Drive() );
+            TRAP_IGNORE( iDBManager->OpenDatabaseL( TDriveNumber ( (TInt) drive ) ) );
+            }
+        }
+
     if( aErr == KErrNone || aErr == KErrCancel )
         {
         aErr = iAddedCount;
         }
     
-    if (iFilteredDrivesToScan.Count() != iDrivesToScan.Count())
+    if ( iFilteredOutOfDisk )
         {
         aErr = KErrDiskFull; 
         }
@@ -2194,7 +2143,24 @@
         iRefreshCount++;
         CancelScan();
         Reset();
-        iFolderScanner->ScanL( iAutoScanPaths );
+        // ensure you don't try to scan paths that are on closed drives
+        for (TInt i = 0; i < iAutoScanPaths.Count(); )
+            {
+            TParsePtr parse(iAutoScanPaths[i]);
+            TDriveUnit drive(parse.Drive());
+            if ( iDBManager->DatabaseIsOpen( (TDriveNumber) (TInt) drive ) )
+                {
+                ++i;
+                }
+            else
+                {
+                iAutoScanPaths.Remove(i);
+                }
+            }
+        if ( iAutoScanPaths.Count() )
+            {
+            iFolderScanner->ScanL( iAutoScanPaths );
+            }
 
         // Cleanup
         iAutoScanPaths.Reset();
@@ -2316,7 +2282,6 @@
     
     CleanupStack::PushL( drmFileList );
 
-#ifdef RD_MULTIPLE_DRIVE
     TDriveList driveList;
     TInt driveCount(0);
 
@@ -2347,81 +2312,9 @@
                 }
             }
     	}
-#else
-    //ensure drive E is ready
-    //otherwise GetDataBaseL will leave if MMC is removed
-    if ( IsDriveReady( EDriveE ) )
-        {
-        // Get DRM files from database in E drive
-        db = &iDBManager->GetDatabaseL( EDriveE );
-        table = db->OpenDrmFileL(); 
-        CleanupStack::PushL( table );
-        tempList = table->CreateTableRepresentationL();
-        CleanupStack::PushL( tempList );
-        // copy content to drm file list
-        for ( TInt i=0; i<tempList->Count(); i++ )
-            {
-            drmFileList->AppendL( (*tempList)[i] );
-            }
-        // reset
-        tempList->Reset();
-        CleanupStack::PopAndDestroy( tempList );
-        CleanupStack::PopAndDestroy( table );
-        }
-
-    // Get DRM files from database in C drive
-    db = &iDBManager->GetDatabaseL( EDriveC );
-    table = db->OpenDrmFileL(); 
-    CleanupStack::PushL( table );
-    tempList = table->CreateTableRepresentationL();
-    CleanupStack::PushL( tempList );
-    // copy content to iCurList
-    for ( TInt i=0; i<tempList->Count(); i++ )
-        {
-        drmFileList->AppendL( (*tempList)[i] );
-        }
-    tempList->Reset();
-    CleanupStack::PopAndDestroy( tempList );
-    CleanupStack::PopAndDestroy( table );
-#endif
     CleanupStack::Pop( drmFileList );
     MPX_DEBUG1("CMPXHarvesterFileHandlerImp::GetDrmFiles --->");
     return drmFileList;
     }
 
-// ---------------------------------------------------------------------------
-// Verifies if aDrive is ready.
-// ---------------------------------------------------------------------------
-//
-TBool CMPXHarvesterFileHandlerImp::IsDriveReady( TDriveNumber aDrive )
-    {
-    MPX_DEBUG1("CMPXHarvesterFileHandlerImp::IsDriveReady <---");
-
-    TDriveInfo driveInfo;
-    TInt error = iFs.Drive( driveInfo, aDrive );
-    TBool ready = ETrue;
-    if ( error != KErrNone )
-        {
-        ready = EFalse;
-        }
-    else if ( driveInfo.iDriveAtt == static_cast<TUint>( KDriveAbsent ) )
-        {
-        //aDrive is absent
-        ready = EFalse;
-        }
-    else
-        {
-        TVolumeInfo volumeInfo;
-        TInt errCode = iFs.Volume( volumeInfo, aDrive );
-        if( errCode != KErrNone )
-            {
-            //aDrive is ready for use
-            ready = EFalse;
-            }
-        }
-
-    MPX_DEBUG1("CMPXHarvesterFileHandlerImp::IsDriveReady --->");
-    return ready;
-    }
-
 // END OF FILE
--- a/mmappcomponents/harvester/filehandler/src/mpxmetadatascanner.cpp	Fri Apr 23 13:55:04 2010 +0100
+++ b/mmappcomponents/harvester/filehandler/src/mpxmetadatascanner.cpp	Wed Apr 28 22:20:05 2010 +0100
@@ -12,7 +12,7 @@
 * Contributors:
 *
 * Description:  Active object to extract metadata 
-*  Version     : %version: da1mmcf#16.2.3.1.5 % 
+*  Version     : %version: da1mmcf#16.2.3.1.6 % 
 *
 */
 
@@ -44,8 +44,9 @@
 CMPXMetadataScanner::CMPXMetadataScanner( MMPXMetadataScanObserver& aObs,
                                           MMPXFileScanStateObserver& aStateObs )
                                       : CActive( EPriorityNull ),
+                                        iExtractType( EMaxFile ),
                                         iObserver( aObs ),
-                                        iStateObserver( aStateObs ) 
+                                        iStateObserver( aStateObs )
     {
     CActiveScheduler::Add( this );
     }
@@ -60,8 +61,7 @@
                                       RPointerArray<CMPXCollectionType>& aTypesAry )
     {
     iExtractor = CMPXMetadataExtractor::NewL( aFs, aAppArc, aTypesAry );
-    iNewFileProps = CMPXMediaArray::NewL();
-    iModifiedFileProps = CMPXMediaArray::NewL();
+    iTargetProps = CMPXMediaArray::NewL();
     }
 
 
@@ -114,8 +114,7 @@
     iNewFiles.Close();
     iModifiedFiles.Close();
     
-    delete iNewFileProps;
-    delete iModifiedFileProps;
+    delete iTargetProps;
    
     delete iExtractor;
     }
@@ -128,14 +127,7 @@
     {
     iNewFiles.ResetAndDestroy();
     iModifiedFiles.ResetAndDestroy();
-    if(iNewFileProps)
-        {
-    iNewFileProps->Reset();
-        }
-    if(iModifiedFileProps)
-        {
-    iModifiedFileProps->Reset();
-        }
+    iTargetProps->Reset();
     }
 
 // ---------------------------------------------------------------------------
@@ -144,20 +136,20 @@
 //    
 void CMPXMetadataScanner::Start()
     {
-    MPX_DEBUG1("MPXMetadataScanner::StartL <---");
+    MPX_FUNC("MPXMetadataScanner::StartL()");
     if( !IsActive() )
         {
         // Setup
         iAryPos = 0;
         iExtractType = ENewFiles;
         iExtracting = ETrue;        
-        
+        iTargetProps->Reset();
+                
         // Set Active
         iStatus = KRequestPending;
         SetActive();
         TRequestStatus* status = &iStatus;
         User::RequestComplete( status, KErrNone );    
-        MPX_DEBUG1("MPXMetadataScanner::StartL --->");
         }
     }
 // ---------------------------------------------------------------------------
@@ -166,9 +158,8 @@
 //
 void CMPXMetadataScanner::Stop()
     {
-    MPX_DEBUG1("MPXMetadataScanner::Stop <---");
+    MPX_FUNC("MPXMetadataScanner::Stop()");
     DoCancel();
-    MPX_DEBUG1("MPXMetadataScanner::Stop --->");
     }
 
 // ---------------------------------------------------------------------------
@@ -177,6 +168,7 @@
 //  
 void CMPXMetadataScanner::AddNewFileToScanL( const TDesC& aFile )
     {
+    MPX_FUNC("MPXMetadataScanner::AddNewFileToScanL()");
     HBufC* file = aFile.AllocLC();
     iNewFiles.AppendL( file );
     CleanupStack::Pop( file );
@@ -188,6 +180,7 @@
 //      
 void CMPXMetadataScanner::AddModifiedFileToScanL( const TDesC& aFile )
     {
+    MPX_FUNC("MPXMetadataScanner::AddModifiedFileToScanL()");
     HBufC* file = aFile.AllocLC();
     iModifiedFiles.AppendL( file );
     CleanupStack::Pop( file );
@@ -199,6 +192,7 @@
 //
 CMPXMedia* CMPXMetadataScanner::ExtractFileL( const TDesC& aFile )
     {
+    MPX_FUNC("MPXMetadataScanner::ExtractFileL()");
     CMPXMedia* media;
     iExtractor->CreateMediaL( aFile, media );
     return media;
@@ -210,10 +204,12 @@
 //   
 void CMPXMetadataScanner::DoCancel()
     {
+    MPX_FUNC("MPXMetadataScanner::DoCancel()");
     if( iExtracting )
         {
-        // Callback to observer 
+        iExtractor->CancelRequest();
         Reset();
+        // Callback to observer
         TRAP_IGNORE( iStateObserver.HandleScanStateCompleteL( MMPXFileScanStateObserver::EScanMetadata,
                                                               KErrCancel ) );
         iExtracting = EFalse;
@@ -226,29 +222,13 @@
 //   
 void CMPXMetadataScanner::RunL()
     {
+    MPX_FUNC("CMPXMetadataScanner::RunL()");
     if ( iExtracting )
         {
-        TBool done(EFalse);
-        TRAPD( err, done = DoExtractL() );
-        if ( !iExtracting )
-            {
-            // If DoCancel() was called during DoExtractL(), do nothing.
-            MPX_DEBUG1("CMPXMetadataScanner::RunL - Cancel during RunL");
-            }
-        else if( KErrNone != err || done )
+        TRAPD( err, DoExtractL() );
+        if ( err )
             {
-            // Callback to observer 
-            TRAP_IGNORE( iStateObserver.HandleScanStateCompleteL( MMPXFileScanStateObserver::EScanMetadata,
-                                                              err ) );
-            iExtracting = EFalse;
-            }
-        else
-            {
-            MPX_DEBUG1("CMPXMetadataScanner::RunL -- Run again");
-            iStatus = KRequestPending;
-            SetActive();
-            TRequestStatus* status = &iStatus;
-            User::RequestComplete( status, KErrNone );    
+            MetadataScannerComplete( err );
             }
         }
     }
@@ -257,98 +237,185 @@
 // Extract metadata
 // ---------------------------------------------------------------------------
 //   
-TBool CMPXMetadataScanner::DoExtractL()
+void CMPXMetadataScanner::DoExtractL()
+    {
+    MPX_FUNC("CMPXMetadataScanner::DoExtractL()");
+    
+    RPointerArray<HBufC>* source = GetSource();
+    if ( source->Count() )
+        {
+        // Call asynchronous CreateMedia to get metadata.
+        iExtractor->CreateMediaAsyncL( *(*source)[iAryPos], this );
+        }
+    else
+        {
+        // Source array is empty, go to next array.
+        MPX_DEBUG2("CMPXMetadataScanner::DoExtractL Source array is empty ExtractType = %d.", iExtractType);
+        iAryPos = 0;
+        iExtractType++;
+        RunAgain();
+        }
+    }
+
+// ---------------------------------------------------------------------------
+// Callback for CreateMediaAsyncL
+// ---------------------------------------------------------------------------
+//   
+void CMPXMetadataScanner::HandleCreateMediaComplete( CMPXMedia* aMedia, TInt aError )
     {
-    MPX_DEBUG1("CMPXMetadataScanner::DoExtractL <---");
-    TBool done(EFalse);
+    MPX_FUNC("CMPXMetadataScanner::HandleCreateMediaComplete()");
+    MPX_DEBUG2("CMPXMetadataScanner::HandleCreateMediaComplete error = %d", aError);
+    TInt err = KErrNone;
+    
+    // Scanning cancelled
+    if ( !iExtracting )
+        {
+        delete aMedia;
+        return;
+        }
+    
+    // Add media to target array.
+    if ( ( aError == KErrNone ) && 
+         ( aMedia != NULL ) )
+        {
+        TRAP( err, iTargetProps->AppendL( aMedia ) );
+        if ( err )
+            {
+            delete aMedia;
+            }
+        }
+    
+    iAryPos++;
+    if( iAryPos >= GetSource()->Count() )
+        {
+        // Finished with this array, go to the next array.
+        iAryPos = 0;
+        TRAP( err, AddToCollectionL() );
+        if ( err )
+            {
+            MetadataScannerComplete( err );
+            }
+        iExtractType++;
+        }
+    else
+        {
+        // Batch update collection DBs.
+        if ( iTargetProps->Count() >= KLoopCount )
+            {
+            TRAP( err, AddToCollectionL() );
+            if ( err )
+                {
+                MetadataScannerComplete( err );
+                }
+            }
+        }
+    
+    RunAgain();
+    }    
+
+// ---------------------------------------------------------------------------
+// Get source array
+// ---------------------------------------------------------------------------
+//   
+RPointerArray<HBufC>* CMPXMetadataScanner::GetSource()
+    {
+    MPX_FUNC("CMPXMetadataScanner::GetSource()");
     TExtractType curType = (TExtractType) iExtractType;
-    
-    // Pointer re-direction to generalize extraction
-    RPointerArray<HBufC>* source;
-    CMPXMediaArray* mptarget;
+
     if( curType == ENewFiles )
         {
-        source = &iNewFiles;
-        mptarget = iNewFileProps;
+        return &iNewFiles;
         }
     else if( curType == EModFiles )
         {
-        source = &iModifiedFiles;
-        mptarget = iModifiedFileProps;
+        return &iModifiedFiles;
         }
-    else // All done!
-        {
-        return ETrue;    
-        }
-    
-    // Process at most KLoopCount number of files 
-    //
-    mptarget->Reset();
-    if( source->Count() != 0 )
+    else
+        return NULL;
+    }
+
+// ---------------------------------------------------------------------------
+// Is metadata scanner done
+// ---------------------------------------------------------------------------
+//   
+TBool CMPXMetadataScanner::IsDone()
+    {
+    MPX_FUNC("CMPXMetadataScanner::IsDone()");
+    TExtractType curType = (TExtractType) iExtractType;
+
+    TBool done = EFalse;
+    if ( curType >= EMaxFile )
         {
-        for( TInt i=0; i<KLoopCount; ++i )
-            {
-            CMPXMedia* media(NULL);
-            
-            // TRAP to keep scanning if 1 file fails 
-            TRAPD( err, iExtractor->CreateMediaL( *(*source)[iAryPos], media ) );
-            if ( !iExtracting )
-                {
-                // In case DoCancel() was called while processing iExtractor->CreateMediaL
-                MPX_DEBUG1("CMPXMetadataScanner::DoExtractL - Cancel during CreateMediaL");
-                delete media;
-                return ETrue;
-                }
-            
-            if( err == KErrNone )
-                {
-                CleanupStack::PushL( media );
-                mptarget->AppendL( media );
-                CleanupStack::Pop( media );
-                }
-            
-            iAryPos++;
-            if( iAryPos == source->Count() )
-                {
-                iAryPos = 0;
-                iExtractType++;
-                break;
-                }
-            }    
+        done = ETrue;
+        }
+    return done;
+    }
+
+// ---------------------------------------------------------------------------
+// Run Active Object again
+// ---------------------------------------------------------------------------
+//   
+void CMPXMetadataScanner::RunAgain()
+    {
+    MPX_FUNC("CMPXMetadataScanner::RunAgain()");
+    if ( IsDone() )
+        {
+        MetadataScannerComplete( KErrNone );
         }
-    else // No item in the array
+    else
         {
-        iAryPos = 0;
-        iExtractType++;    
+        MPX_DEBUG1("CMPXMetadataScanner::RunAgain -- Run again");
+        iStatus = KRequestPending;
+        SetActive();
+        TRequestStatus* status = &iStatus;
+        User::RequestComplete( status, KErrNone );    
         }
+    }
+
+// ---------------------------------------------------------------------------
+// Add metadata to collection
+// ---------------------------------------------------------------------------
+//   
+void CMPXMetadataScanner::AddToCollectionL()
+    {
+    MPX_FUNC("CMPXMetadataScanner::AddToCollectionL()");
+    TExtractType curType = (TExtractType) iExtractType;
     
-    // After extraction, get observer to add files to the collection
-    //
     switch( curType )
         {
         case ENewFiles:
             {
-            if( iNewFileProps->Count() )
+            if( iTargetProps->Count() )
                 {
-                iObserver.AddFilesToCollectionL( *iNewFileProps );
+                iObserver.AddFilesToCollectionL( *iTargetProps );
                 }
             break;
             }
         case EModFiles:
             {
-            if( iModifiedFileProps->Count() )
+            if( iTargetProps->Count() )
                 {
-                iObserver.UpdatesFilesInCollectionL( *iModifiedFileProps );
+                iObserver.UpdatesFilesInCollectionL( *iTargetProps );
                 }
             break;
             }
-        case EMaxFile:  // All done.
-            done = ETrue;
-            break;
         default:
             ASSERT(0); 
         }
-        
-    MPX_DEBUG1("CMPXMetadataScanner::DoExtractL --->");    
-    return done; 
+    iTargetProps->Reset();
     }
+
+// ---------------------------------------------------------------------------
+// Complete metadata scanner
+// ---------------------------------------------------------------------------
+//   
+void CMPXMetadataScanner::MetadataScannerComplete( TInt aError )
+    {
+    MPX_FUNC("CMPXMetadataScanner::MetadataScannerCompleteL()");
+    MPX_DEBUG2("CMPXMetadataScanner::MetadataScannerCompleteL error = %d", aError);    
+
+    // Callback to observer 
+    TRAP_IGNORE( iStateObserver.HandleScanStateCompleteL( MMPXFileScanStateObserver::EScanMetadata, aError ) );
+    iExtracting = EFalse;
+    Reset();
+    }
--- a/mmappcomponents/harvester/metadataextractor/bwinscw/mpxmetadataextractorU.DEF	Fri Apr 23 13:55:04 2010 +0100
+++ b/mmappcomponents/harvester/metadataextractor/bwinscw/mpxmetadataextractorU.DEF	Wed Apr 28 22:20:05 2010 +0100
@@ -2,4 +2,6 @@
 	?CreateMediaL@CMPXMetadataExtractor@@QAEXABVTDesC16@@AAPAVCMPXMedia@@H@Z @ 1 NONAME ; void CMPXMetadataExtractor::CreateMediaL(class TDesC16 const &, class CMPXMedia * &, int)
 	?NewL@CMPXMetadataExtractor@@SAPAV1@AAVRFs@@AAVRApaLsSession@@AAV?$RPointerArray@VCMPXCollectionType@@@@@Z @ 2 NONAME ; class CMPXMetadataExtractor * CMPXMetadataExtractor::NewL(class RFs &, class RApaLsSession &, class RPointerArray<class CMPXCollectionType> &)
 	?ExtractAlbumArtL@CMPXMetadataExtractor@@QAEHPAVCMPXMedia@@@Z @ 3 NONAME ; int CMPXMetadataExtractor::ExtractAlbumArtL(class CMPXMedia *)
+	?CancelRequest@CMPXMetadataExtractor@@QAEXXZ @ 4 NONAME ; void CMPXMetadataExtractor::CancelRequest(void)
+	?CreateMediaAsyncL@CMPXMetadataExtractor@@QAEXABVTDesC16@@PAVMMPXMetadataExtractorObserver@@H@Z @ 5 NONAME ; void CMPXMetadataExtractor::CreateMediaAsyncL(class TDesC16 const &, class MMPXMetadataExtractorObserver *, int)
 
--- a/mmappcomponents/harvester/metadataextractor/eabi/mpxmetadataextractorU.DEF	Fri Apr 23 13:55:04 2010 +0100
+++ b/mmappcomponents/harvester/metadataextractor/eabi/mpxmetadataextractorU.DEF	Wed Apr 28 22:20:05 2010 +0100
@@ -6,4 +6,6 @@
 	_ZTV19CMPXFileInfoUtility @ 5 NONAME ; #<VT>#
 	_ZTV21CMPXMetadataExtractor @ 6 NONAME ; #<VT>#
 	_ZN21CMPXMetadataExtractor16ExtractAlbumArtLEP9CMPXMedia @ 7 NONAME
+	_ZN21CMPXMetadataExtractor13CancelRequestEv @ 8 NONAME
+	_ZN21CMPXMetadataExtractor17CreateMediaAsyncLERK7TDesC16P29MMPXMetadataExtractorObserveri @ 9 NONAME
 
--- a/mmappcomponents/harvester/metadataextractor/src/mpxmetadataextractor.cpp	Fri Apr 23 13:55:04 2010 +0100
+++ b/mmappcomponents/harvester/metadataextractor/src/mpxmetadataextractor.cpp	Wed Apr 28 22:20:05 2010 +0100
@@ -12,7 +12,7 @@
 * Contributors:
 *
 * Description:  Extracts metadata from a file
-*  Version     : %version: da1mmcf#38.1.4.2.6.1.9 % << Don't touch! Updated by Synergy at check-out.
+*  Version     : %version: da1mmcf#38.1.4.2.6.1.10 % << Don't touch! Updated by Synergy at check-out.
 *
 */
 
@@ -41,6 +41,7 @@
 #include <mpxmediaaudiodefs.h>
 #include <mpxmediadrmdefs.h>
 #include <mpxmediamtpdefs.h>
+#include <mpxmetadataextractorobserver.h>
 
 #include "mpxmetadataextractor.h"
 #include "mpxfileinfoutility.h"
@@ -82,8 +83,11 @@
                                   : iFs( aFs ),
                                     iAppArc( aAppArc ),
                                     iSupportedTypes( aTypes ),
-                                    iOutstandingThumbnailRequest(0),
-                                    iTNMBlockCount(0)
+                                    iCancelled( EFalse ),
+                                    iObs( NULL ),
+                                    iMedia( NULL ),
+                                    iMetadataOnly( EFalse ),
+                                    iFileOpenError( KErrNone )
     {
 
     }
@@ -98,6 +102,7 @@
     iMetadataUtility = CMetaDataUtility::NewL();
     iDrmMediaUtility = CMPXDrmMediaUtility::NewL();
     iFileInfoUtil    = CMPXFileInfoUtility::NewL();
+    iTaskTimer = CPeriodic::NewL( CActive::EPriorityIdle );
 
 #ifdef RD_MPX_TNM_INTEGRATION
     // Create Thumbnail Manager instance. This object is the observer.
@@ -107,6 +112,8 @@
     // create wait loop
     iTNSyncWait = new (ELeave) CActiveSchedulerWait;
     iTimer = CPeriodic::NewL( CActive::EPriorityIdle );
+    iArrayTNRequestId.Reset();
+    iArrayTasks.Reset();
 #endif //RD_MPX_TNM_INTEGRATION
     }
 
@@ -138,6 +145,8 @@
     delete iMetadataUtility;
     delete iFileInfoUtil;
     delete iDrmMediaUtility;
+    delete iTaskTimer;
+    iFile.Close();
 #ifdef RD_MPX_TNM_INTEGRATION
     delete iTNManager;
     if (iTNSyncWait && iTNSyncWait->IsStarted() )
@@ -146,137 +155,64 @@
         }
     delete iTNSyncWait;
     delete iTimer;
+    iArrayTNRequestId.Close();
+    iArrayTasks.Close();
 #endif //RD_MPX_TNM_INTEGRATION
-    
-    MPX_DEBUG2("CMPXMetadataExtractor: TNM Block Count: %d ", iTNMBlockCount );
     }
 
 // ---------------------------------------------------------------------------
-// Constructs a media properties object
+// Constructs a media properties object : synchronous function
 // ---------------------------------------------------------------------------
 //
 EXPORT_C void CMPXMetadataExtractor::CreateMediaL( const TDesC& aFile,
                                                    CMPXMedia*& aNewProperty,
                                                    TBool aMetadataOnly )
     {
-    // make a copy of aFile
-    HBufC* fileName = HBufC::NewL(KMaxFileName);
-    CleanupStack::PushL( fileName );
-    fileName->Des().Append( aFile );
-    MPX_DEBUG2("CMPXMetadataExtractor::CreateMediaL %S <---", fileName );
-
-    RArray<TInt> contentIDs;
-    contentIDs.AppendL( KMPXMediaIdGeneral );
-    contentIDs.AppendL( KMPXMediaIdAudio );
-    contentIDs.AppendL( KMPXMediaIdMusic );
-    contentIDs.AppendL( KMPXMediaIdDrm );
-    contentIDs.AppendL( KMPXMediaIdMTP );
-    aNewProperty = NULL;
-    CMPXMedia* media = CMPXMedia::NewL( contentIDs.Array() );
-    CleanupStack::PushL( media );
-    contentIDs.Close();
-
-    // CMPXMedia default types
-
-    media->SetTObjectValueL<TMPXGeneralType>( KMPXMediaGeneralType,
-                                              EMPXItem );
-    media->SetTObjectValueL<TMPXGeneralCategory>( KMPXMediaGeneralCategory,
-                                                  EMPXSong );
+    MPX_FUNC("CMPXMetadataExtractor::CreateMediaL()");
+    // check if we are still processing a request.
+    if ( iArrayTasks.Count() )
+        {
+        MPX_DEBUG1("CMPXMetadataExtractor::CreateMediaL Request ongoing. Abort!" );
+        User::Leave( KErrAbort );
+        }
 
-    TParsePtrC parse( *fileName );
-
-    // Title, default is file name
-    media->SetTextValueL( KMPXMediaGeneralTitle,
-                          parse.Name() );
-
-    // Default album track
-    media->SetTextValueL( KMPXMediaMusicAlbumTrack,
-                          KNullDesC );
-
-    // Set the Mime Type and collection UID
-    //
-    if( !aMetadataOnly )
+    iCancelled = EFalse;
+    iFileOpenError = KErrNone;
+    iObs = NULL;
+    aNewProperty = NULL;
+    iFileName = aFile;
+    iMetadataOnly = aMetadataOnly;
+    
+    // populate the task array
+    AddTasksL();
+    
+    // execute all tasks in the array
+    while ( iArrayTasks.Count() )
         {
-        TInt index(KErrNotFound);
-        TInt count( iSupportedTypes.Count() );
-        for (TInt i=0; i <count; ++i)
+        // execute task at index 0
+        TRAPD( error, ExecuteTaskL() );
+        if ( error || iCancelled )
             {
-            TInt index2(KErrNotFound);
-            const CDesCArray& exts = iSupportedTypes[i]->Extensions();
-            const TDesC& ext = parse.Ext();
-            if (!exts.FindIsq(ext, index2))
-                { // found
-                index = i;
-                break;
+            // cleanup
+            if ( iMedia != NULL )
+                {
+                delete iMedia;
+                iMedia = NULL;
                 }
+            iArrayTasks.Reset();
+            if ( error )
+                {
+                CleanUp();
+                User::LeaveIfError( error );
+                }
+            break;
             }
-        if( KErrNotFound != index )
-            {
-            MPX_DEBUG1("CMPXMetadataExtractor::CreateMediaPropertiesL apparc <---" );
-            TInt mimeIndex = SupportedContainerTypeL( *fileName, index );
-            User::LeaveIfError( mimeIndex );
-            MPX_DEBUG1("CMPXMetadataExtractor::CreateMediaPropertiesL apparc --->" );
-
-            media->SetTextValueL( KMPXMediaGeneralMimeType,
-                                  iSupportedTypes[index]->Mimetypes()[mimeIndex] );
-
-            media->SetTObjectValueL( KMPXMediaGeneralCollectionId,
-                                     iSupportedTypes[index]->Uid() );
-            }
-        else
-            {
-            User::Leave(KErrNotSupported);
-            }
-        }
-    else // other case use apparc to fetch and set mimetype
-        {
-        TDataType dataType;
-        TUid dummyUid(KNullUid);
-        iAppArc.AppForDocument(*fileName, dummyUid, dataType);
-        media->SetTextValueL( KMPXMediaGeneralMimeType,dataType.Des() );
-        }
         
-    // Use file handle here
-    //
-    RFile file;
-    TInt err = file.Open( iFs, *fileName, EFileRead | EFileShareReadersOrWriters );
-    CleanupClosePushL(file);
-    
-    // Initially set default tags.
-    SetDefaultL( *media );
-    // Metadata related
-    //
-    if( err == KErrNone )
-        {
-        const TDesC& mimeType = media->ValueText( KMPXMediaGeneralMimeType );
-        HBufC8* mimeType8 = HBufC8::NewLC( mimeType.Length() );
-        mimeType8->Des().Append( mimeType );
-        TRAPD( metadataerror, iMetadataUtility->OpenFileL( file, *mimeType8 ) );
-        MPX_DEBUG2("CMPXMetadataExtractor::CreateMediaL, error %d parsing metadata", 
-            metadataerror );
-        CleanupStack::PopAndDestroy( mimeType8 );
-        
-        // Even if there is error extracting metadata, fill extracted tags.
-        TRAP( metadataerror, SetMediaPropertiesL( *media, *fileName ) ); 
-        MPX_DEBUG2("CMPXMetadataExtractor::CreateMediaL, error %d setting tags", 
-            metadataerror );
-
-        // Reset the utility
-        iMetadataUtility->ResetL();
+        iArrayTasks.Remove( 0 );
         }
     
-    // Common properties that we can extract
-    //
-    SetExtMediaPropertiesL( *media, *fileName, aMetadataOnly, file, err );
-    CleanupStack::PopAndDestroy(&file);
-
-    // Set the pointers now that the object is ready
-    //
-    CleanupStack::Pop( media );
-    aNewProperty = media;
-
-    CleanupStack::PopAndDestroy( fileName );
-    MPX_DEBUG1("CMPXMetadataExtractor::CreateMediaPropertiesL --->");
+    aNewProperty = iMedia;
+    CleanUp();
     }
 
 // ---------------------------------------------------------------------------
@@ -285,6 +221,7 @@
 //
 void CMPXMetadataExtractor::SetDefaultL( CMPXMedia& aMediaProp )
     {
+    MPX_FUNC("CMPXMetadataExtractor::SetDefaultL()");
     // Comment
     aMediaProp.SetTextValueL( KMPXMediaGeneralComment,
                               KNullDesC );
@@ -318,13 +255,21 @@
 // Sets media object attributes from metadata utilities
 // ---------------------------------------------------------------------------
 //
-void CMPXMetadataExtractor::SetMediaPropertiesL( CMPXMedia& aMedia,
-                                                 const TDesC& aFile )
+void CMPXMetadataExtractor::SetMediaPropertiesL()
     {
-    MPX_DEBUG1("CMPXMetadataExtractor::SetMediaPropertiesL <---" );
+    MPX_FUNC("CMPXMetadataExtractor::SetMediaPropertiesL()");
 
-    const CMetaDataFieldContainer& metaCont =
-                                          iMetadataUtility->MetaDataFieldsL();
+    const TDesC& mimeType = iMedia->ValueText( KMPXMediaGeneralMimeType );
+    HBufC8* mimeType8 = HBufC8::NewLC( mimeType.Length() );
+    mimeType8->Des().Append( mimeType );
+    
+    // Continue to extract metadata even if fail.
+    TRAPD( metadataerror, iMetadataUtility->OpenFileL( iFile, *mimeType8 ) );
+    MPX_DEBUG2("CMPXMetadataExtractor::CreateMediaL, error %d parsing metadata", 
+        metadataerror );
+    CleanupStack::PopAndDestroy( mimeType8 );
+    
+    const CMetaDataFieldContainer& metaCont = iMetadataUtility->MetaDataFieldsL();
     TInt count( metaCont.Count() );
     for( TInt i=0; i<count; ++i )
         {
@@ -337,13 +282,12 @@
         if ( fieldType != EMetaDataJpeg )
            {
            TRAPD( err, value = metaCont.At( i, fieldType ).AllocL() );
-           CleanupStack::PushL( value );
            if ( KErrNone != err )
                {
                MPX_DEBUG2("CMPXMetadataExtractor::SetMediaPropertiesL - error = %i", err);           
-               CleanupStack::PopAndDestroy( value );
                continue;
                }     
+           CleanupStack::PushL( value );
            }
         
         switch( fieldType )
@@ -356,7 +300,7 @@
                 if (vallen>0)
                     {
                     FindAndReplaceForbiddenChars(valptr, vallen);
-                    aMedia.SetTextValueL(KMPXMediaGeneralTitle, *value);
+                    iMedia->SetTextValueL(KMPXMediaGeneralTitle, *value);
                     }
                 break;
                 }
@@ -368,7 +312,7 @@
                 if (vallen>0)
                     {
                     FindAndReplaceForbiddenChars(valptr, vallen);
-                    aMedia.SetTextValueL(KMPXMediaMusicArtist, *value);
+                    iMedia->SetTextValueL(KMPXMediaMusicArtist, *value);
                     }
                 break;
                 }
@@ -380,7 +324,7 @@
                 if (vallen>0)
                     {
                     FindAndReplaceForbiddenChars(valptr, vallen);
-                    aMedia.SetTextValueL(KMPXMediaMusicAlbum, *value );
+                    iMedia->SetTextValueL(KMPXMediaMusicAlbum, *value );
                     }
                 break;
                 }
@@ -395,19 +339,19 @@
                 TDateTime dt;
                 dt.SetYear( year );
                 TTime time( dt );
-                aMedia.SetTObjectValueL<TInt64>( KMPXMediaMusicYear,
+                iMedia->SetTObjectValueL<TInt64>( KMPXMediaMusicYear,
                                                  time.Int64() );
                 break;
                 }
             case EMetaDataComment:
                 {
-                aMedia.SetTextValueL( KMPXMediaGeneralComment,
+                iMedia->SetTextValueL( KMPXMediaGeneralComment,
                                       *value );
                 break;
                 }
             case EMetaDataAlbumTrack:
                 {
-                aMedia.SetTextValueL( KMPXMediaMusicAlbumTrack,
+                iMedia->SetTextValueL( KMPXMediaMusicAlbumTrack,
                                       *value );
                 break;
                 }
@@ -419,7 +363,7 @@
                 if (vallen>0)
                     {
                     FindAndReplaceForbiddenChars(valptr, vallen);
-                    aMedia.SetTextValueL(KMPXMediaMusicGenre, *value);
+                    iMedia->SetTextValueL(KMPXMediaMusicGenre, *value);
                     }
                 break;
                 }
@@ -431,54 +375,31 @@
                 if (vallen>0)
                     {
                     FindAndReplaceForbiddenChars(valptr, vallen);
-                    aMedia.SetTextValueL(KMPXMediaMusicComposer, *value);
+                    iMedia->SetTextValueL(KMPXMediaMusicComposer, *value);
                     }
                 break;
                 }
             case EMetaDataUrl:
             case EMetaDataUserUrl:  // fall through
                 {
-                aMedia.SetTextValueL( KMPXMediaMusicURL,
+                iMedia->SetTextValueL( KMPXMediaMusicURL,
                                       *value );
                 break;
                 }
             case EMetaDataJpeg:
                 {
-#ifdef RD_MPX_TNM_INTEGRATION
-                MPX_PERF_START(CMPXMetadataExtractor_SetMediaPropertiesL_JPEG_TNM);
-                TPtrC8 ptr8 = metaCont.Field8( EMetaDataJpeg );
-                HBufC8* value8; 
-                TRAPD( err, value8 = ptr8.AllocL() );
-                if ( KErrNone != err )
-                    {
-                    MPX_DEBUG2("CMPXMetadataExtractor::SetMediaPropertiesL - error jpeg = %i", err);           
-                    }
-                else
-                    {
-                    CleanupStack::PushL( value8 );
-                    TRAPD( err, AddMediaAlbumArtL( aMedia, aFile, *value8 ) );
-                    if ( KErrNone != err )
-                        {
-                        MPX_DEBUG2("CMPXMetadataExtractor::SetMediaPropertiesL - error album art = %i", err);           
-                        }
-                    CleanupStack::Pop( value8 );
-                    }
-                MPX_PERF_END(CMPXMetadataExtractor_SetMediaPropertiesL_JPEG_TNM);
-#else //RD_MPX_TNM_INTEGRATION
-                aMedia.SetTextValueL( KMPXMediaMusicAlbumArtFileName,
-                                      aFile );
-#endif //RD_MPX_TNM_INTEGRATION
+                // Album art handled in AddMediaAlbumArtL()
                 break;
                 }
             case EMetaDataCopyright:
                 {
-                aMedia.SetTextValueL( KMPXMediaGeneralCopyright,
+                iMedia->SetTextValueL( KMPXMediaGeneralCopyright,
                                       *value );
                 break;
                 }
             case EMetaDataDuration:     
                 {                  
-                const TDesC& mimeType = aMedia.ValueText( KMPXMediaGeneralMimeType );
+                const TDesC& mimeType = iMedia->ValueText( KMPXMediaGeneralMimeType );
                 MPX_DEBUG2("CMPXMetadataExtractor::SetExtMediaPropertiesL, mimeType = %S", &mimeType);   
                 
                 // Verify if WMA, get the duration
@@ -492,7 +413,7 @@
                     lexer.Val( duration );   // [second]      
                     duration *= 1000;        // [msec]
                 
-                    aMedia.SetTObjectValueL<TInt32>( KMPXMediaGeneralDuration,
+                    iMedia->SetTObjectValueL<TInt32>( KMPXMediaGeneralDuration,
                                                 duration );      
                 
                     MPX_DEBUG2("CMPXMetadataExtractor::SetMediaPropertiesL- duration = %i", duration);  
@@ -519,21 +440,15 @@
             CleanupStack::PopAndDestroy( value );       
             }
         }
-
-    MPX_DEBUG1("CMPXMetadataExtractor::SetMediaPropertiesL --->" );
     }
 
 // ---------------------------------------------------------------------------
 // Sets extra media properties not returned by metadata utilities
 // ---------------------------------------------------------------------------
 //
-void CMPXMetadataExtractor::SetExtMediaPropertiesL( CMPXMedia& aProp, 
-                                                    const TDesC& aFile,
-                                                    TBool aMetadataOnly,
-                                                    RFile& aFileHandle,
-                                                    TInt aFileErr )
+void CMPXMetadataExtractor::SetExtMediaPropertiesL()
     {
-    MPX_DEBUG1("CMPXMetadataExtractor::SetExtMediaPropertiesL <---");
+    MPX_FUNC("CMPXMetadataExtractor::SetExtMediaPropertiesL()");
 
     // DB Flags to set
     //
@@ -541,18 +456,16 @@
 
     // File Path
     //
-    TParsePtrC parse( aFile );
-    aProp.SetTextValueL( KMPXMediaGeneralUri,
-                         aFile );
-    aProp.SetTextValueL( KMPXMediaGeneralDrive,
-                         parse.Drive() );
+    TParsePtrC parse( iFileName );
+    iMedia->SetTextValueL( KMPXMediaGeneralUri, iFileName );
+    iMedia->SetTextValueL( KMPXMediaGeneralDrive, parse.Drive() );
 
     // DRM Rights
     //
     CMPXMedia* drm = NULL;
-    TRAPD( drmError, iDrmMediaUtility->InitL( aFile );
-                     drm = CMPXMedia::NewL( *iDrmMediaUtility->GetMediaL( KMPXMediaDrmProtected.iAttributeId |
-                                                                          KMPXMediaDrmRightsStatus.iAttributeId ) );
+    TRAPD( drmError, iDrmMediaUtility->InitL( iFileName );
+           drm = CMPXMedia::NewL( *iDrmMediaUtility->GetMediaL( KMPXMediaDrmProtected.iAttributeId |
+                                                                KMPXMediaDrmRightsStatus.iAttributeId ) );
          );
 
     TBool prot(EFalse);
@@ -570,7 +483,7 @@
         if( drm->IsSupported( KMPXMediaDrmRightsStatus ) )
             {
             status = drm->ValueTObjectL<TMPXMediaDrmRightsStatus>(KMPXMediaDrmRightsStatus);
-            aProp.SetTObjectValueL<TInt>(KMPXMediaDrmRightsStatus, status );
+            iMedia->SetTObjectValueL<TInt>(KMPXMediaDrmRightsStatus, status );
             MPX_DEBUG2("CMPXMetadataExtractor::SetExtMediaPropertiesL -- status %i", status);
             }
 
@@ -594,8 +507,8 @@
         User::LeaveIfError( drmError );
         }
 
-    aProp.SetTObjectValueL<TBool>( KMPXMediaDrmProtected, prot );
-    aProp.SetTObjectValueL<TUint16>( KMPXMediaMTPDrmStatus, (TUint16)prot );
+    iMedia->SetTObjectValueL<TBool>( KMPXMediaDrmProtected, prot );
+    iMedia->SetTObjectValueL<TUint16>( KMPXMediaMTPDrmStatus, (TUint16)prot );
     
     iDrmMediaUtility->Close();
     
@@ -603,9 +516,9 @@
     // File Size --- The following needs MMF support
     //
     TInt size( 0 );
-    if( aFileErr == KErrNone )
+    if( iFileOpenError == KErrNone )
         {
-        const TDesC& mimeType = aProp.ValueText( KMPXMediaGeneralMimeType );
+        const TDesC& mimeType = iMedia->ValueText( KMPXMediaGeneralMimeType );
         MPX_DEBUG2("CMPXMetadataExtractor::SetExtMediaPropertiesL, mimeType = %S", &mimeType);   
         
         // Verify if WMA, skip getting info from MMF
@@ -617,25 +530,25 @@
         else
             {
             MPX_DEBUG1("CMPXMetadataExtractor::SetExtMediaPropertiesL, get MMF controller");   
-            aFileHandle.Size( size );
-            aProp.SetTObjectValueL<TInt>( KMPXMediaGeneralSize, size );
+            iFile.Size( size );
+            iMedia->SetTObjectValueL<TInt>( KMPXMediaGeneralSize, size );
 
             // Duration, bitrate, samplerate, etc
             //
-            if( !aMetadataOnly )
+            if( !iMetadataOnly )
             {
                 TRAPD(err2, iFileInfoUtil->OpenFileL(
-                          aFileHandle, 
-                          aProp.ValueText(KMPXMediaGeneralMimeType)));
+                          iFile, 
+                          iMedia->ValueText(KMPXMediaGeneralMimeType)));
                 MPX_DEBUG2("CMPXMetadataExtractor::SetExtMediaPropertiesL, file info util error %i", err2);
                 if( KErrNone == err2 )
                     {
-                    aProp.SetTObjectValueL<TUint>( KMPXMediaAudioBitrate,
+                    iMedia->SetTObjectValueL<TUint>( KMPXMediaAudioBitrate,
                                                    iFileInfoUtil->BitRate() );
-                    aProp.SetTObjectValueL<TUint>( KMPXMediaAudioSamplerate,
+                    iMedia->SetTObjectValueL<TUint>( KMPXMediaAudioSamplerate,
                                                    iFileInfoUtil->SampleRate() );
                     TInt64 duration = (TInt64) iFileInfoUtil->Duration().Int64() / 1000; // ms
-                    aProp.SetTObjectValueL<TInt32>( KMPXMediaGeneralDuration,
+                    iMedia->SetTObjectValueL<TInt32>( KMPXMediaGeneralDuration,
                                                     duration );
 
                     MPX_DEBUG2("CMPXMetadataExtractor::SetExtMediaPropertiesL -- duration %i", duration);
@@ -645,16 +558,14 @@
                 }
             }
         }
-    else if( aFileErr == KErrNotFound || aFileErr == KErrPathNotFound )
+    else if( iFileOpenError == KErrNotFound || iFileOpenError == KErrPathNotFound )
         {
         dbFlags |= KMPXMediaGeneralFlagsIsInvalid;
         }
     // Finally set the db flag
     //
-    aProp.SetTObjectValueL( KMPXMediaGeneralFlags,
+    iMedia->SetTObjectValueL( KMPXMediaGeneralFlags,
                             dbFlags );
-    
-    MPX_DEBUG1("CMPXMetadataExtractor::SetExtMediaPropertiesL --->");
     }
 
 // ---------------------------------------------------------------------------
@@ -664,6 +575,7 @@
 TInt CMPXMetadataExtractor::SupportedContainerTypeL( const TDesC& aFile,
                                                      TInt aIndex )
     {
+    MPX_FUNC("CMPXMetadataExtractor::SupportedContainerTypeL()");
     TInt index(KErrNotFound);
 
     TDataType dataType;
@@ -697,13 +609,20 @@
 // Callback but not used here
 // ---------------------------------------------------------------------------
 void CMPXMetadataExtractor::ThumbnailReady( TInt /*aError*/, 
-        MThumbnailData& /*aThumbnail*/, TThumbnailRequestId /*aId*/ )
+        MThumbnailData& /*aThumbnail*/, TThumbnailRequestId aId )
     {
     MPX_FUNC("CMPXMetadataExtractor::ThumbnailReady()");
-    MPX_DEBUG2("CMPXMetadataExtractor::ThumbnailReady(): iOutstandingThumbnailRequest %d",
-        iOutstandingThumbnailRequest);
-    iOutstandingThumbnailRequest--;
-    if ( iOutstandingThumbnailRequest < KMPXMaxThumbnailRequest )
+    
+    // Remove thumbnail id from array.
+    TInt index = iArrayTNRequestId.Find( aId );
+    if ( index >= 0 )
+        {
+        iArrayTNRequestId.Remove( index );
+        }
+    MPX_DEBUG2("CMPXMetadataExtractor::ThumbnailReady(): Outstanding Thumbnail Request = %d",
+            iArrayTNRequestId.Count());
+
+    if ( iArrayTNRequestId.Count() < KMPXMaxThumbnailRequest )
         {
         StopWaitLoop();
         }
@@ -762,7 +681,8 @@
 EXPORT_C TInt CMPXMetadataExtractor::ExtractAlbumArtL( CMPXMedia* aMedia )
     {
     MPX_FUNC("CMPXMetadataExtractor::ExtractAlbumArtL()");
-    TInt err = KErrNone; 
+    TInt err = KErrNone;
+    iCancelled = EFalse;
     
     if ( !aMedia->IsSupported(KMPXMediaGeneralUri) )
         {
@@ -778,25 +698,18 @@
     if (ext.CompareF(KNonEmbeddedArtExt)== 0)
         {
 		#ifdef RD_MPX_TNM_INTEGRATION
-
         //check if can send TN request, If thumbnail creation is ongoing, wait til it is done
         CheckBeforeSendRequest();
-
         CThumbnailObjectSource* source = CThumbnailObjectSource::NewLC(
            path, KImageFileType  );
-          
-       
-
-        iTNManager->CreateThumbnails( *source );
-        
-        iOutstandingThumbnailRequest++;
+        TThumbnailRequestId tnId = iTNManager->CreateThumbnails( *source );
+        iArrayTNRequestId.Append( tnId );
         CleanupStack::PopAndDestroy( source );
-
-        #endif
+        #endif // RD_MPX_TNM_INTEGRATION
         }
     else
         {
-#endif
+#endif // ABSTRACTAUDIOALBUM_INCLUDED
     // create wanted fields array
     RArray<TMetaDataFieldId> wantedFields;
     CleanupClosePushL( wantedFields );
@@ -820,54 +733,16 @@
     
     if ( !err )
         {
-        TRAP( err, GetMediaAlbumArtL( *aMedia, path ));
+        //check if can send TN request, If thumbnail creation is ongoing, wait til it is done
+        CheckBeforeSendRequest();
+        TRAP( err, AddMediaAlbumArtL( *aMedia, path ));
         }
 
     // Reset the utility
     iMetadataUtility->ResetL();
 #ifdef ABSTRACTAUDIOALBUM_INCLUDED
       }
-#endif
-    return err;
-    }
-
-// ----------------------------------------------------------------------------
-// Set album art.
-// ----------------------------------------------------------------------------
-TInt CMPXMetadataExtractor::GetMediaAlbumArtL( CMPXMedia& aMedia, 
-                                               const TDesC& aFile )
-    {
-    MPX_FUNC("CMPXMetadataExtractor::GetMediaAlbumArtL()");
-    TInt err = KErrNone;
-    // get metadata container.
-    const CMetaDataFieldContainer& metaCont = iMetadataUtility->MetaDataFieldsL();
-
-    TPtrC8 data8 = metaCont.Field8( EMetaDataJpeg );
-    
-    if ( data8.Length() )
-        {
-        MPX_DEBUG1("CMPXMetadataExtractor::GetMediaAlbumArtL(): Album art exist.");
-
-#ifdef RD_MPX_TNM_INTEGRATION
-        HBufC8* value8; 
-        TRAPD( err, value8 = data8.AllocL() );
-        if ( KErrNone != err )
-            {
-            MPX_DEBUG2("CMPXMetadataExtractor::GetMediaAlbumArtL - error jpeg = %i", err);           
-            User::Leave( err );  
-            }              
-        CleanupStack::PushL( value8 );
-        AddMediaAlbumArtL( aMedia, aFile, *value8 );
-        CleanupStack::Pop( value8 );
-#else // RD_MPX_TNM_INTEGRATION
-        aMedia.SetTextValueL( KMPXMediaMusicAlbumArtFileName, aFile );
-#endif // RD_MPX_TNM_INTEGRATION          
-        }
-    else
-        {
-        err = KErrNotFound;
-        }
-    
+#endif // ABSTRACTAUDIOALBUM_INCLUDED
     return err;
     }
 
@@ -875,40 +750,53 @@
 // Add album art to media object.
 // ----------------------------------------------------------------------------
 void CMPXMetadataExtractor::AddMediaAlbumArtL( CMPXMedia& aMedia, 
-                                               const TDesC& aFile,
-                                               TDesC8& aValue )
+                                               const TDesC& aFile )
     {
     MPX_FUNC("CMPXMetadataExtractor::AddMediaAlbumArtL()");
-#ifdef RD_MPX_TNM_INTEGRATION
-    
-    //check if can send TN request, If thumbnail creation is ongoing, wait til it is done
-    CheckBeforeSendRequest();
-
-    aMedia.SetTextValueL( KMPXMediaMusicAlbumArtFileName, aFile );
     
-    TBuf<256> mimeType;
-    mimeType.Copy( KImageFileType );
-    CThumbnailObjectSource* source = CThumbnailObjectSource::NewLC(
-        &aValue, mimeType, aFile );
-    iTNManager->CreateThumbnails( *source );
-    CleanupStack::PopAndDestroy( source );
-    aMedia.SetTextValueL( KMPXMediaMusicOriginalAlbumArtFileName, aFile );
-    iOutstandingThumbnailRequest++;
+    // get metadata container.
+    const CMetaDataFieldContainer& metaCont = iMetadataUtility->MetaDataFieldsL();
+    TPtrC8 data8 = metaCont.Field8( EMetaDataJpeg );
+   
+    if ( data8.Length() )
+        {
+        MPX_DEBUG1("CMPXMetadataExtractor::GetMediaAlbumArtL(): Album art exist.");
+#ifdef RD_MPX_TNM_INTEGRATION
+        HBufC8* value8 = NULL; 
+        TRAPD( err, value8 = data8.AllocL() );
+        if ( KErrNone != err )
+            {
+            MPX_DEBUG2("CMPXMetadataExtractor::GetMediaAlbumArtL - error jpeg = %i", err);
+            return;
+            }              
+        CleanupStack::PushL( value8 );
     
+        TBuf<256> mimeType;
+        mimeType.Copy( KImageFileType );
+        CThumbnailObjectSource* source = CThumbnailObjectSource::NewL(
+                value8, mimeType, aFile );
+        TThumbnailRequestId tnId = iTNManager->CreateThumbnails( *source );
+        iArrayTNRequestId.Append( tnId ); // add thumbnail id to array
+        CleanupStack::Pop( value8 );
+        aMedia.SetTextValueL( KMPXMediaMusicOriginalAlbumArtFileName, aFile );
 #endif // RD_MPX_TNM_INTEGRATION          
+        aMedia.SetTextValueL( KMPXMediaMusicAlbumArtFileName, aFile );
+        }
     }
 
+// ----------------------------------------------------------------------------
+// Check if can send request to TNM or not.
+// ----------------------------------------------------------------------------
 void CMPXMetadataExtractor::CheckBeforeSendRequest()
      {
      MPX_FUNC("CMPXMetadataExtractor::CheckBeforeSendRequest()");
 #ifdef RD_MPX_TNM_INTEGRATION
-    MPX_DEBUG2("CMPXMetadataExtractor::CheckBeforeSendRequest(): iOutstandingThumbnailRequest %d",
-        iOutstandingThumbnailRequest);
+    MPX_DEBUG2("CMPXMetadataExtractor::CheckBeforeSendRequest(): Outstanding Thumbnail Request = %d",
+            iArrayTNRequestId.Count());
 	// If thumbnail creation is ongoing, wait til it is done
-    if ( iOutstandingThumbnailRequest >= KMPXMaxThumbnailRequest )
+    if ( iArrayTNRequestId.Count() >= KMPXMaxThumbnailRequest )
         {
         MPX_DEBUG1("CMPXMetadataExtractor::CheckBeforeSendRequest(): Thumbnail creation ongoing!");
-        iTNMBlockCount++;
         // Cancel timer.
         CancelTimeoutTimer();
         // Start timer in case there is no callback from ThumbNail Manager.
@@ -925,3 +813,292 @@
         }
 #endif // RD_MPX_TNM_INTEGRATION
      }
+
+// ----------------------------------------------------------------------------
+// Cancel request. This will empty the task array and stop the wait loop. This
+//                 will cause the CreateMediaL() to finish more quickly.
+// ----------------------------------------------------------------------------
+EXPORT_C void CMPXMetadataExtractor::CancelRequest()
+    {
+    MPX_FUNC("CMPXMetadataExtractor::CancelRequest()");
+    iCancelled = ETrue;
+    // Cancel all tasks
+    iArrayTasks.Reset();
+    // Cancel all thumbnail request
+    CancelAllThumbnailRequests();
+    StopWaitLoop();
+    }
+
+// ----------------------------------------------------------------------------
+// Cancel all outstanding thumbnail requests.
+// ----------------------------------------------------------------------------
+void CMPXMetadataExtractor::CancelAllThumbnailRequests()
+    {
+    MPX_FUNC("CMPXMetadataExtractor::CancelAllThumbnailRequests()");
+#ifdef RD_MPX_TNM_INTEGRATION
+    // TODO: remove comments when TNM make CancelRequest asynchronous.
+    /*TInt count = iArrayTNRequestId.Count();
+    for ( TInt i=0; i<count; i++ )
+        {
+        iTNManager->CancelRequest( iArrayTNRequestId[i] );
+        }
+    */
+    iArrayTNRequestId.Reset();
+#endif // RD_MPX_TNM_INTEGRATION
+    }
+
+// ----------------------------------------------------------------------------
+// Create media and set default data and mimetype.
+// ----------------------------------------------------------------------------
+void CMPXMetadataExtractor::DoCreateMediaL()
+    {
+    MPX_FUNC("CMPXMetadataExtractor::DoCreateMediaL()");
+    RArray<TInt> contentIDs;
+    contentIDs.AppendL( KMPXMediaIdGeneral );
+    contentIDs.AppendL( KMPXMediaIdAudio );
+    contentIDs.AppendL( KMPXMediaIdMusic );
+    contentIDs.AppendL( KMPXMediaIdDrm );
+    contentIDs.AppendL( KMPXMediaIdMTP );
+    iMedia = CMPXMedia::NewL( contentIDs.Array() );
+    contentIDs.Close();
+
+    // CMPXMedia default types
+    iMedia->SetTObjectValueL<TMPXGeneralType>( KMPXMediaGeneralType,
+                                              EMPXItem );
+    iMedia->SetTObjectValueL<TMPXGeneralCategory>( KMPXMediaGeneralCategory,
+                                                  EMPXSong );
+
+    TParsePtrC parse( iFileName );
+    // Title, default is file name
+    iMedia->SetTextValueL( KMPXMediaGeneralTitle,
+                          parse.Name() );
+    // Default album track
+    iMedia->SetTextValueL( KMPXMediaMusicAlbumTrack,
+                          KNullDesC );
+
+    // Set the Mime Type and collection UID
+    //
+    if( !iMetadataOnly )
+        {
+        TInt index(KErrNotFound);
+        TInt count( iSupportedTypes.Count() );
+        for (TInt i=0; i <count; ++i)
+            {
+            TInt index2(KErrNotFound);
+            const CDesCArray& exts = iSupportedTypes[i]->Extensions();
+            const TDesC& ext = parse.Ext();
+            if (!exts.FindIsq(ext, index2))
+                { // found
+                index = i;
+                break;
+                }
+            }
+        if( KErrNotFound != index )
+            {
+            MPX_DEBUG1("CMPXMetadataExtractor::DoCreateMediaL apparc <---" );
+            TInt mimeIndex = SupportedContainerTypeL( iFileName, index );
+            User::LeaveIfError( mimeIndex );
+            MPX_DEBUG1("CMPXMetadataExtractor::DoCreateMediaL apparc --->" );
+
+            iMedia->SetTextValueL( KMPXMediaGeneralMimeType,
+                                  iSupportedTypes[index]->Mimetypes()[mimeIndex] );
+
+            iMedia->SetTObjectValueL( KMPXMediaGeneralCollectionId,
+                                     iSupportedTypes[index]->Uid() );
+            }
+        else
+            {
+            User::Leave(KErrNotSupported);
+            }
+        }
+    else // other case use apparc to fetch and set mimetype
+        {
+        TDataType dataType;
+        TUid dummyUid(KNullUid);
+        iAppArc.AppForDocument(iFileName, dummyUid, dataType);
+        iMedia->SetTextValueL( KMPXMediaGeneralMimeType,dataType.Des() );
+        }
+        
+    // Initially set default tags.
+    SetDefaultL( *iMedia );
+    }
+
+// ----------------------------------------------------------------------------
+// Execute task at index 0.
+// ----------------------------------------------------------------------------
+void CMPXMetadataExtractor::ExecuteTaskL()
+    {
+    MPX_FUNC("CMPXMetadataExtractor::ExecuteTasksL()");
+
+    if ( iArrayTasks.Count() )
+        {
+        switch ( iArrayTasks[0] )
+            {
+            case ETaskCreateMedia:
+                DoCreateMediaL();
+                break;
+            case ETaskAddMetadata:
+                SetMediaPropertiesL();
+                break;
+            case ETaskAddExtMetadata:
+                SetExtMediaPropertiesL();
+                break;
+            case ETaskAddAlbumArt:
+                AddMediaAlbumArtL( *iMedia, iFileName );
+                break;
+            case ETaskCheckBeforeSend:
+                CheckBeforeSendRequest();
+                break;
+            default:
+                MPX_ASSERT(0); // Should never get here
+            }
+        }
+    }
+
+// ---------------------------------------------------------------------------
+// Constructs a media properties object : asynchronous funcion
+// ---------------------------------------------------------------------------
+//
+EXPORT_C void CMPXMetadataExtractor::CreateMediaAsyncL( const TDesC& aFile,
+                                                        MMPXMetadataExtractorObserver* aObs,
+                                                        TBool aMetadataOnly )
+    {
+    MPX_FUNC("CMPXMetadataExtractor::CreateMediaAsyncL()");
+    // check if we are still processing a request.
+    if ( iArrayTasks.Count() )
+        {
+        MPX_DEBUG1("CMPXMetadataExtractor::CreateMediaAsyncL Request ongoing. Abort!" );
+        User::Leave( KErrAbort );
+        }
+    
+    iCancelled = EFalse;
+    iFileOpenError = KErrNone;
+    iFileName = aFile;
+    iObs = aObs;
+    iMetadataOnly = aMetadataOnly;
+    
+    // populate the task array
+    AddTasksL();
+    
+    // Start task timer to execute task
+    if ( iArrayTasks.Count() )
+        {
+        if ( iTaskTimer->IsActive() )
+            {
+            iTaskTimer->Cancel();
+            }   
+        iTaskTimer->Start( 0, 0, TCallBack(TaskTimerCallback, this ));
+        }
+    }
+
+// ---------------------------------------------------------------------------
+// Opens the file
+// ---------------------------------------------------------------------------
+//
+TInt CMPXMetadataExtractor::OpenFile()
+    {
+    MPX_FUNC("CMPXMetadataExtractor::OpenFile()");
+    
+    // Open the file
+    iFile.Close();
+    TInt error = iFile.Open( iFs, iFileName, EFileRead | EFileShareReadersOrWriters );
+    MPX_DEBUG2("CMPXMetadataExtractor::OpenFile open error = %d", error );
+    return error;
+    }
+
+// ---------------------------------------------------------------------------
+// Populat task array
+// ---------------------------------------------------------------------------
+//
+void CMPXMetadataExtractor::AddTasksL()
+    {
+    MPX_FUNC("CMPXMetadataExtractor::AddTasks()");
+    iFileOpenError = OpenFile();
+    
+    // Do not change the order of the task below.
+    iArrayTasks.Reset();
+    if ( iFileOpenError == KErrNone )
+        {
+        iArrayTasks.AppendL(ETaskCreateMedia);
+        iArrayTasks.AppendL(ETaskAddMetadata);
+        iArrayTasks.AppendL(ETaskCheckBeforeSend);
+        iArrayTasks.AppendL(ETaskAddAlbumArt);
+        iArrayTasks.AppendL(ETaskAddExtMetadata);
+        }
+    else
+        {
+        iArrayTasks.AppendL(ETaskCreateMedia);
+        iArrayTasks.AppendL(ETaskAddExtMetadata);
+        }
+    }
+
+// ----------------------------------------------------------------------------
+// Callback for timer.
+// ----------------------------------------------------------------------------
+TInt CMPXMetadataExtractor::TaskTimerCallback(TAny* aPtr)
+    {
+    MPX_FUNC("CMPXMetadataExtractor::TaskTimerCallback()");
+
+    CMPXMetadataExtractor* ptr =
+        static_cast<CMPXMetadataExtractor*>(aPtr);
+
+    ptr->HandleTaskTimerExpired();
+    return KErrNone;
+    }
+
+// ----------------------------------------------------------------------------
+// Handle task timer expired
+// ----------------------------------------------------------------------------
+void CMPXMetadataExtractor::HandleTaskTimerExpired()
+    {
+    MPX_FUNC("CMPXMetadataExtractor::HandleTaskTimerExpired()");
+    
+    iTaskTimer->Cancel();
+    // execute task at index 0
+    TRAPD( error, ExecuteTaskL() );
+    if ( error || iCancelled )
+        {
+        // cleanup
+        if ( iMedia != NULL )
+            {
+            delete iMedia;
+            iMedia = NULL;
+            }
+        iArrayTasks.Reset();
+        }
+    
+    // Remove task at index 0.
+    if ( iArrayTasks.Count() )
+        {
+        iArrayTasks.Remove( 0 );
+        }
+    
+    // check if we have any more task to run
+    if ( iArrayTasks.Count() )
+        {
+        // start task timer
+        iTaskTimer->Start( 0, 0, TCallBack(TaskTimerCallback, this ));
+        }
+    else
+        {
+        // done
+        if ( iObs && !iCancelled )
+            {
+            iObs->HandleCreateMediaComplete( iMedia, error );
+            }
+        
+        CleanUp();
+        }
+    }
+
+// ----------------------------------------------------------------------------
+// Callback for timer.
+// ----------------------------------------------------------------------------
+void CMPXMetadataExtractor::CleanUp()
+    {
+    MPX_FUNC("CMPXMetadataExtractor::CleanUp()");
+    // Reset the utility
+    TRAP_IGNORE( iMetadataUtility->ResetL() );
+    iFile.Close();
+    }
+
--- a/mmappcomponents/harvester/server/group/mpxharvester.mmp	Fri Apr 23 13:55:04 2010 +0100
+++ b/mmappcomponents/harvester/server/group/mpxharvester.mmp	Wed Apr 28 22:20:05 2010 +0100
@@ -60,7 +60,5 @@
 LIBRARY                 mpxplaylistengine.lib
 LIBRARY                 mpxplaybackutility.lib
 LIBRARY                 usbman.lib
-#ifdef RD_MULTIPLE_DRIVE
 LIBRARY                 PlatformEnv.lib
-#endif //RD_MULTIPLE_DRIVE
 LIBRARY                 disknotifyhandler.lib
--- a/mmappcomponents/harvester/server/src/mpxfsformatmonitor.cpp	Fri Apr 23 13:55:04 2010 +0100
+++ b/mmappcomponents/harvester/server/src/mpxfsformatmonitor.cpp	Wed Apr 28 22:20:05 2010 +0100
@@ -18,17 +18,11 @@
 
 #include <e32base.h>
 #include <f32file.h>
-#ifdef RD_MULTIPLE_DRIVE
 #include <driveinfo.h>
-#endif //RD_MULTIPLE_DRIVE
 #include <mpxlog.h>
 #include "mpxfsformatmonitor.h"
 
-#ifdef RD_MULTIPLE_DRIVE
-    static const TInt KDriveCount = 2;
-#else
-    static const TInt KDriveCount = 1;
-#endif
+static const TInt KDriveCount = 2;
 
 // ======== MEMBER FUNCTIONS ========
 
--- a/mmappcomponents/harvester/server/src/mpxharvesterengine.cpp	Fri Apr 23 13:55:04 2010 +0100
+++ b/mmappcomponents/harvester/server/src/mpxharvesterengine.cpp	Wed Apr 28 22:20:05 2010 +0100
@@ -17,9 +17,7 @@
 
 
 #include <e32std.h>
-#ifdef RD_MULTIPLE_DRIVE
 #include <driveinfo.h>
-#endif //RD_MULTIPLE_DRIVE
 #include <mpxlog.h>
 #include <mpxmedia.h>
 #include <mpxcollectionutility.h>
@@ -97,11 +95,9 @@
 
     // MMC Removal monitor for Removable Drive
     TInt removableDrive( EDriveE );
-#ifdef RD_MULTIPLE_DRIVE
     User::LeaveIfError( DriveInfo::GetDefaultDrive(
         DriveInfo::EDefaultRemovableMassStorage,
         removableDrive ) );
-#endif // RD_MULTIPLE_DRIVE
     iMediaRemovalMonitor = CMPXMediaRemovalMonitor::NewL(
         removableDrive, iFsSession, *this );
 
@@ -441,6 +437,26 @@
                                               TInt aData )
     {
     MPX_DEBUG2("CMPXHarvesterEngine::HandleSystemEventL %i <---", aEvent);
+    
+    if( !iTempCollectionUtil )
+        {
+        iTempCollectionUtil = MMPXCollectionUtility::NewL( NULL, KMcModeDefault );
+        }
+        
+    // Must close collections ASAP in case drives may dismount soon       
+    TRAP_IGNORE( 
+        if (aEvent == EUSBMassStorageStartEvent)
+            {
+            DoStopPlaybackL();
+            iTempCollectionUtil->Collection().CommandL ( EMcCloseCollection, -1 ); 
+            iFileHandler->HandleSystemEventL ( EDiskDismountEvent, -1 );
+            }
+        else if ( aEvent == EDiskDismountEvent )
+            {
+            DoStopPlaybackL();
+            iTempCollectionUtil->Collection().CommandL ( EMcCloseCollection, aData );
+            }
+        );
 
     // The engine is a delegator, it sends the events to
     // different classes to do the actual work
@@ -454,11 +470,14 @@
         case EDiskDismountEvent:
             {
             notify=EFalse;
-            TRAP_IGNORE( DoStopPlaybackL() );
             break;
             }
+        case EUSBMassStorageStartEvent:
+            {
+            iDiskOpActive = ETrue;
+            }
+            break;
         case EFormatStartEvent:
-        case EUSBMassStorageStartEvent:   // deliberate fall through
         case EUSBMTPStartEvent:           // deliberate fall through
         case EDiskInsertedEvent:          // deliberate fall through
         case EDiskRemovedEvent:           // deliberate fall through
@@ -471,10 +490,6 @@
 
     // Send a message to the collection server about the event
     //
-    if( !iTempCollectionUtil )
-        {
-        iTempCollectionUtil = MMPXCollectionUtility::NewL( NULL, KMcModeDefault );
-        }
     if( notify )
         {
         TRAP_IGNORE(
@@ -482,13 +497,6 @@
                                                           aData )
              );
         }
-	else if ( aEvent == EDiskDismountEvent ) 
-	    {
-        TRAP_IGNORE
-		    ( 
-            iTempCollectionUtil->Collection().CommandL ( EMcCloseCollection, aData ) 
-            );
-		}
 
     // Avoid Message queue already exist problem
     //
--- a/mmappcomponents/harvester/server/src/mpxusbeventhandler.cpp	Fri Apr 23 13:55:04 2010 +0100
+++ b/mmappcomponents/harvester/server/src/mpxusbeventhandler.cpp	Wed Apr 28 22:20:05 2010 +0100
@@ -19,9 +19,7 @@
 #include <e32base.h>
 #include <f32file.h>
 #include <e32property.h>
-#ifdef RD_MULTIPLE_DRIVE
 #include <driveinfo.h>
-#endif //RD_MULTIPLE_DRIVE
 #include <mpxpskeywatcher.h>
 #include <coreapplicationuisdomainpskeys.h>
 #include <UsbWatcherInternalPSKeys.h>
@@ -151,11 +149,9 @@
     
     // Use the default MMC drive
     TInt removableDrive( EDriveE );
-#ifdef RD_MULTIPLE_DRIVE
     User::LeaveIfError( DriveInfo::GetDefaultDrive(
         DriveInfo::EDefaultRemovableMassStorage,
         removableDrive ) );
-#endif // RD_MULTIPLE_DRIVE
 
     // Handle the Key event
     TInt value;
@@ -176,9 +172,7 @@
             iObserver.HandleSystemEventL( EUSBMTPEndEvent, removableDrive );
             }
         MPX_DEBUG1("CMPXUsbEventHandler::DoHandlePSEvent - USB Start");
-#ifdef RD_MULTIPLE_DRIVE
         removableDrive = -1;
-#endif // RD_MULTIPLE_DRIVE
 
         // Notify the state change (may happen more than once)
         iObserver.HandleSystemEventL( EUSBMassStorageStartEvent, removableDrive );
--- a/mmappcomponents/mmmtpdataprovider/inc/cmmmtpdpmetadataaccesswrapper.h	Fri Apr 23 13:55:04 2010 +0100
+++ b/mmappcomponents/mmmtpdataprovider/inc/cmmmtpdpmetadataaccesswrapper.h	Wed Apr 28 22:20:05 2010 +0100
@@ -75,7 +75,7 @@
     * @param aFullFileName, full file name of file
     * @return void
     */
-    void AddObjectL( const CMTPObjectMetaData& aObject );
+    IMPORT_C void AddObjectL( const CMTPObjectMetaData& aObject );
 
     /**
     * Set abstract media to DB
@@ -215,7 +215,7 @@
 
     void ConstructL();
 
-    TMPXGeneralCategory ContainerCategory( const TDesC& aFullFileName );
+    TMPXGeneralCategory ContainerCategoryL( const TDesC& aFullFileName );
 
     /**
     * Remove all dummy file of which format is "pla", and leave the "m3u"
@@ -225,11 +225,12 @@
 private:
     CMmMtpDpMetadataMpxAccess* iMmMtpDpMetadataMpxAccess;
     CMmMtpDpMetadataVideoAccess* iMmMtpDpMetadataVideoAccess;
-    TBool iOpenSession;
 
     MMTPDataProviderFramework& iFramework;
     RFs& iFs;    // should not remove this member data!!!
 
+    TInt iOpenCount;	// introduce to fix CollectionHelper Flush problem
+
     CDesCArray* iAbstractMediaArray;
 
     };
--- a/mmappcomponents/mmmtpdataprovider/inc/cmmmtpdpmetadatampxaccess.h	Fri Apr 23 13:55:04 2010 +0100
+++ b/mmappcomponents/mmmtpdataprovider/inc/cmmmtpdpmetadatampxaccess.h	Wed Apr 28 22:20:05 2010 +0100
@@ -56,6 +56,16 @@
 
 public:
     /**
+     * OpenSession, introduce to fix CollectionHelper Flush problem
+     */
+    void OpenSession();
+
+    /**
+     * CloseSession, introduce to fix CollectionHelper Flush problem
+     */
+    void CloseSession();
+
+    /**
      * Get all abstract medias from MPX database in the assigned store
      * @param aStoreRoot, specify in which drive abstract medias are stored
      * @param aAbstractMedias, return result array
--- a/mmappcomponents/mmmtpdataprovider/inc/mmmtpdpfiledefs.h	Fri Apr 23 13:55:04 2010 +0100
+++ b/mmappcomponents/mmmtpdataprovider/inc/mmmtpdpfiledefs.h	Wed Apr 28 22:20:05 2010 +0100
@@ -59,9 +59,7 @@
 
 //ODF container
 _LIT(KFormatExtensionODFAudio3GPP, "0xB984:ODF:audio/3gpp");
-_LIT(KFormatExtensionODFAudioMP4, "0xB982:ODF:audio/mp4");
 _LIT(KFormatExtensionODFVideo3GPP, "0xB984:ODF:video/3gpp");
-_LIT(KFormatExtensionODFVideoMP4, "0xB982:ODF:video/mp4");
 
 _LIT(KFormatExtensionM4A, "0xB982:m4a");
 _LIT(KFormatExtensionO4A, "0xB984:o4a");
@@ -100,7 +98,7 @@
     EMTPSubFormatCodeUnknown,
     EMTPSubFormatCodeAudio,
     EMTPSubFormatCodeVideo,
-    EMTPSubFormatCodeUndefine
+    EMTPSubFormatCodeUndefined
     };
 
 #endif // MMMTPDPFILEDEFS_H
--- a/mmappcomponents/mmmtpdataprovider/mmmtpdpplugins/mediamtpdataprovider/inc/cmediamtpdataprovider.h	Fri Apr 23 13:55:04 2010 +0100
+++ b/mmappcomponents/mmmtpdataprovider/mmmtpdpplugins/mediamtpdataprovider/inc/cmediamtpdataprovider.h	Wed Apr 28 22:20:05 2010 +0100
@@ -113,6 +113,12 @@
     */
     void RenameObjectL( const TMTPNotificationParamsHandle& aObject );
 
+    /**
+    * Notify the data provider that the object has been added
+    * @param aObjectHandle    the added object handle
+    */
+    void ObjectAddedL( TUint32 aObjectHandle );
+
     void StartObjectEnumerationL( TUint32 aStorageId );
 
     void StartStorageEnumerationL();
--- a/mmappcomponents/mmmtpdataprovider/mmmtpdpplugins/mediamtpdataprovider/src/cmediamtpdataprovider.cpp	Fri Apr 23 13:55:04 2010 +0100
+++ b/mmappcomponents/mmmtpdataprovider/mmmtpdpplugins/mediamtpdataprovider/src/cmediamtpdataprovider.cpp	Wed Apr 28 22:20:05 2010 +0100
@@ -179,9 +179,11 @@
             break;
 
         case EMTPStorageAdded:
+            PRINT( _L( "MM MTP <> CMediaMtpDataProvider::ProcessNotificationL EMTPStorageAdded event recvd" ) );
             break;
 
         case EMTPStorageRemoved:
+            PRINT( _L( "MM MTP <> CMediaMtpDataProvider::ProcessNotificationL EMTPStorageRemoved event recvd" ) );
             break;
 
         case EMTPRenameObject:
@@ -189,6 +191,11 @@
             RenameObjectL( *reinterpret_cast<const TMTPNotificationParamsHandle*> ( aParams ) );
             break;
 
+        case EMTPObjectAdded:
+            PRINT( _L( "MM MTP <> CMediaMtpDataProvider::ProcessNotificationL EMTPObjectAdded event recvd" ) );
+            ObjectAddedL(*reinterpret_cast<const TUint32*>(aParams));
+            break;
+
         default:
             PRINT( _L( "MM MTP <> CMediaMtpDataProvider::ProcessNotificationL default" ) );
             // Ignore all other notifications.
@@ -271,6 +278,8 @@
 
     // introduce to cleanup DBs at each close session
     iMediaEnumerator->SessionClosedL();
+    CMmMtpDpAccessSingleton::CloseSessionL();
+
     PRINT( _L( "MM MTP <= CMediaMtpDataProvider::SessionClosedL" ) );
     }
 
@@ -305,6 +314,27 @@
     }
 
 // -----------------------------------------------------------------------------
+// CMediaMtpDataProvider::ObjectAddedL
+// Process the added object
+// -----------------------------------------------------------------------------
+//
+void CMediaMtpDataProvider::ObjectAddedL( TUint32 aObjectHandle )
+    {
+    PRINT1( _L( "MM MTP => CMediaMtpDataProvider::ObjectAddedL aHandle=0x%x" ), aObjectHandle );
+
+    CMTPObjectMetaData* object(CMTPObjectMetaData::NewLC());
+    Framework().ObjectMgr().ObjectL( aObjectHandle, *object );
+
+    //Since the object's processor is not route to media dp, its format code should be reset
+    TUint formatCode = MmMtpDpUtility::FormatFromFilename( object->DesC( CMTPObjectMetaData::ESuid ) );
+    object->SetUint( CMTPObjectMetaData::EFormatCode, formatCode );
+    GetWrapperL().AddObjectL( *object );
+    PRINT2( _L( "MM MTP => CMediaMtpDataProvider::ObjectAddedL formatCode=0x%x Suid=%S" ), formatCode, &(object->DesC( CMTPObjectMetaData::ESuid ) ) );
+    CleanupStack::PopAndDestroy( object );
+    PRINT( _L( "MM MTP <= CMediaMtpDataProvider::ObjectAddedL" ) );
+    }
+
+// -----------------------------------------------------------------------------
 // CMediaMtpDataProvider::StartObjectEnumerationL
 // Start object enumeration
 // -----------------------------------------------------------------------------
@@ -435,9 +465,7 @@
         #endif
         //ODF container
         aStrings.AppendL(KFormatExtensionODFAudio3GPP);
-        aStrings.AppendL(KFormatExtensionODFAudioMP4);
         aStrings.AppendL(KFormatExtensionODFVideo3GPP);
-        aStrings.AppendL(KFormatExtensionODFVideoMP4);
 
         aStrings.AppendL(KFormatExtensionO4A);
         aStrings.AppendL(KFormatExtensionO4V);
--- a/mmappcomponents/mmmtpdataprovider/mmmtpdprequestprocessor/bwins/mmmtpdprequestprocessoru.def	Fri Apr 23 13:55:04 2010 +0100
+++ b/mmappcomponents/mmmtpdataprovider/mmmtpdprequestprocessor/bwins/mmmtpdprequestprocessoru.def	Wed Apr 28 22:20:05 2010 +0100
@@ -64,26 +64,26 @@
 	?DoCancel@CDeleteObject@@MAEXXZ @ 63 NONAME ; void CDeleteObject::DoCancel(void)
 	??1CGetObject@@UAE@XZ @ 64 NONAME ; CGetObject::~CGetObject(void)
 	?NewL@CGetInterdependentPropDesc@@SAPAVMMmRequestProcessor@@AAVMMTPDataProviderFramework@@AAVMMTPConnection@@AAVMMmMtpDpConfig@@@Z @ 65 NONAME ; class MMmRequestProcessor * CGetInterdependentPropDesc::NewL(class MMTPDataProviderFramework &, class MMTPConnection &, class MMmMtpDpConfig &)
-	?DoHandleResponsePhaseL@CSetObjectReferences@@EAEHXZ @ 66 NONAME ; int CSetObjectReferences::DoHandleResponsePhaseL(void)
-	?GetAccessWrapperL@CMmMtpDpAccessSingleton@@SAAAVCMmMtpDpMetadataAccessWrapper@@XZ @ 67 NONAME ; class CMmMtpDpMetadataAccessWrapper & CMmMtpDpAccessSingleton::GetAccessWrapperL(void)
-	??1CGetObjectPropsSupported@@UAE@XZ @ 68 NONAME ; CGetObjectPropsSupported::~CGetObjectPropsSupported(void)
-	?CheckRequestL@CGetObjectPropList@@MAE?AW4TMTPResponseCode@@XZ @ 69 NONAME ; enum TMTPResponseCode CGetObjectPropList::CheckRequestL(void)
-	?HasDataphase@CRequestProcessor@@MBEHXZ @ 70 NONAME ; int CRequestProcessor::HasDataphase(void) const
-	?NewL@CGetObjectPropsSupported@@SAPAVMMmRequestProcessor@@AAVMMTPDataProviderFramework@@AAVMMTPConnection@@AAVMMmMtpDpConfig@@@Z @ 71 NONAME ; class MMmRequestProcessor * CGetObjectPropsSupported::NewL(class MMTPDataProviderFramework &, class MMTPConnection &, class MMmMtpDpConfig &)
-	?Connection@CRequestProcessor@@MBEAAVMMTPConnection@@XZ @ 72 NONAME ; class MMTPConnection & CRequestProcessor::Connection(void) const
-	?ConstructL@CGetFormatCapabilities@@AAEXXZ @ 73 NONAME ; void CGetFormatCapabilities::ConstructL(void)
-	??1CPropertySettingUtility@@UAE@XZ @ 74 NONAME ; CPropertySettingUtility::~CPropertySettingUtility(void)
-	??1CGetPartialObject@@UAE@XZ @ 75 NONAME ; CGetPartialObject::~CGetPartialObject(void)
-	?NewL@CGetObjectInfo@@SAPAVMMmRequestProcessor@@AAVMMTPDataProviderFramework@@AAVMMTPConnection@@AAVMMmMtpDpConfig@@@Z @ 76 NONAME ; class MMmRequestProcessor * CGetObjectInfo::NewL(class MMTPDataProviderFramework &, class MMTPConnection &, class MMmMtpDpConfig &)
-	?RunError@CSetObjectPropList@@MAEHH@Z @ 77 NONAME ; int CSetObjectPropList::RunError(int)
-	?CheckRequestL@CGetInterdependentPropDesc@@MAE?AW4TMTPResponseCode@@XZ @ 78 NONAME ; enum TMTPResponseCode CGetInterdependentPropDesc::CheckRequestL(void)
-	?Match@CRequestUnknown@@MBEHABVTMTPTypeRequest@@AAVMMTPConnection@@@Z @ 79 NONAME ; int CRequestUnknown::Match(class TMTPTypeRequest const &, class MMTPConnection &) const
-	?ServiceL@CMoveObject@@MAEXXZ @ 80 NONAME ; void CMoveObject::ServiceL(void)
-	?CreateDummyFile@CMmMtpDpMetadataAccessWrapper@@QAEXABVTDesC16@@@Z @ 81 NONAME ; void CMmMtpDpMetadataAccessWrapper::CreateDummyFile(class TDesC16 const &)
-	?CheckRequestL@CGetObjectPropDesc@@MAE?AW4TMTPResponseCode@@XZ @ 82 NONAME ; enum TMTPResponseCode CGetObjectPropDesc::CheckRequestL(void)
-	?DoHandleRToIPhaseL@CRequestProcessor@@MAEHXZ @ 83 NONAME ; int CRequestProcessor::DoHandleRToIPhaseL(void)
-	?ServiceMetaDataToWrapperL@CSetObjectPropValue@@IAE?AW4TMTPResponseCode@@GAAVMMTPType@@ABVCMTPObjectMetaData@@@Z @ 84 NONAME ; enum TMTPResponseCode CSetObjectPropValue::ServiceMetaDataToWrapperL(unsigned short, class MMTPType &, class CMTPObjectMetaData const &)
-	?NewCommonObjectPropertyL@CDescriptionUtility@@QAEPAVCMTPTypeObjectPropDesc@@G@Z @ 85 NONAME ; class CMTPTypeObjectPropDesc * CDescriptionUtility::NewCommonObjectPropertyL(unsigned short)
+	?AddObjectL@CMmMtpDpMetadataAccessWrapper@@QAEXABVCMTPObjectMetaData@@@Z @ 66 NONAME ; void CMmMtpDpMetadataAccessWrapper::AddObjectL(class CMTPObjectMetaData const &)
+	?DoHandleResponsePhaseL@CSetObjectReferences@@EAEHXZ @ 67 NONAME ; int CSetObjectReferences::DoHandleResponsePhaseL(void)
+	?GetAccessWrapperL@CMmMtpDpAccessSingleton@@SAAAVCMmMtpDpMetadataAccessWrapper@@XZ @ 68 NONAME ; class CMmMtpDpMetadataAccessWrapper & CMmMtpDpAccessSingleton::GetAccessWrapperL(void)
+	??1CGetObjectPropsSupported@@UAE@XZ @ 69 NONAME ; CGetObjectPropsSupported::~CGetObjectPropsSupported(void)
+	?CheckRequestL@CGetObjectPropList@@MAE?AW4TMTPResponseCode@@XZ @ 70 NONAME ; enum TMTPResponseCode CGetObjectPropList::CheckRequestL(void)
+	?HasDataphase@CRequestProcessor@@MBEHXZ @ 71 NONAME ; int CRequestProcessor::HasDataphase(void) const
+	?NewL@CGetObjectPropsSupported@@SAPAVMMmRequestProcessor@@AAVMMTPDataProviderFramework@@AAVMMTPConnection@@AAVMMmMtpDpConfig@@@Z @ 72 NONAME ; class MMmRequestProcessor * CGetObjectPropsSupported::NewL(class MMTPDataProviderFramework &, class MMTPConnection &, class MMmMtpDpConfig &)
+	?Connection@CRequestProcessor@@MBEAAVMMTPConnection@@XZ @ 73 NONAME ; class MMTPConnection & CRequestProcessor::Connection(void) const
+	?ConstructL@CGetFormatCapabilities@@AAEXXZ @ 74 NONAME ; void CGetFormatCapabilities::ConstructL(void)
+	??1CPropertySettingUtility@@UAE@XZ @ 75 NONAME ; CPropertySettingUtility::~CPropertySettingUtility(void)
+	??1CGetPartialObject@@UAE@XZ @ 76 NONAME ; CGetPartialObject::~CGetPartialObject(void)
+	?NewL@CGetObjectInfo@@SAPAVMMmRequestProcessor@@AAVMMTPDataProviderFramework@@AAVMMTPConnection@@AAVMMmMtpDpConfig@@@Z @ 77 NONAME ; class MMmRequestProcessor * CGetObjectInfo::NewL(class MMTPDataProviderFramework &, class MMTPConnection &, class MMmMtpDpConfig &)
+	?RunError@CSetObjectPropList@@MAEHH@Z @ 78 NONAME ; int CSetObjectPropList::RunError(int)
+	?CheckRequestL@CGetInterdependentPropDesc@@MAE?AW4TMTPResponseCode@@XZ @ 79 NONAME ; enum TMTPResponseCode CGetInterdependentPropDesc::CheckRequestL(void)
+	?Match@CRequestUnknown@@MBEHABVTMTPTypeRequest@@AAVMMTPConnection@@@Z @ 80 NONAME ; int CRequestUnknown::Match(class TMTPTypeRequest const &, class MMTPConnection &) const
+	?ServiceL@CMoveObject@@MAEXXZ @ 81 NONAME ; void CMoveObject::ServiceL(void)
+	?CreateDummyFile@CMmMtpDpMetadataAccessWrapper@@QAEXABVTDesC16@@@Z @ 82 NONAME ; void CMmMtpDpMetadataAccessWrapper::CreateDummyFile(class TDesC16 const &)
+	?CheckRequestL@CGetObjectPropDesc@@MAE?AW4TMTPResponseCode@@XZ @ 83 NONAME ; enum TMTPResponseCode CGetObjectPropDesc::CheckRequestL(void)
+	?DoHandleRToIPhaseL@CRequestProcessor@@MAEHXZ @ 84 NONAME ; int CRequestProcessor::DoHandleRToIPhaseL(void)
+	?ServiceMetaDataToWrapperL@CSetObjectPropValue@@IAE?AW4TMTPResponseCode@@GAAVMMTPType@@ABVCMTPObjectMetaData@@@Z @ 85 NONAME ; enum TMTPResponseCode CSetObjectPropValue::ServiceMetaDataToWrapperL(unsigned short, class MMTPType &, class CMTPObjectMetaData const &)
 	?FormatFromFilename@MmMtpDpUtility@@SA?AW4TMTPFormatCode@@ABVTDesC16@@@Z @ 86 NONAME ; enum TMTPFormatCode MmMtpDpUtility::FormatFromFilename(class TDesC16 const &)
 	?CheckRequestL@CSetObjectPropValue@@MAE?AW4TMTPResponseCode@@XZ @ 87 NONAME ; enum TMTPResponseCode CSetObjectPropValue::CheckRequestL(void)
 	??0CPropertySettingUtility@@IAE@XZ @ 88 NONAME ; CPropertySettingUtility::CPropertySettingUtility(void)
--- a/mmappcomponents/mmmtpdataprovider/mmmtpdprequestprocessor/eabi/mmmtpdprequestprocessoru.def	Fri Apr 23 13:55:04 2010 +0100
+++ b/mmappcomponents/mmmtpdataprovider/mmmtpdprequestprocessor/eabi/mmmtpdprequestprocessoru.def	Wed Apr 28 22:20:05 2010 +0100
@@ -115,73 +115,73 @@
 	_ZN18CSetObjectPropListD0Ev @ 114 NONAME
 	_ZN18CSetObjectPropListD1Ev @ 115 NONAME
 	_ZN18CSetObjectPropListD2Ev @ 116 NONAME
-	_ZN19CDescriptionUtility24NewCommonObjectPropertyLEt @ 117 NONAME
-	_ZN19CDescriptionUtility24NewRangeFormDescriptionLEtmmmi @ 118 NONAME
-	_ZN19CDescriptionUtilityC2Ev @ 119 NONAME
-	_ZN19CDescriptionUtilityD0Ev @ 120 NONAME
-	_ZN19CDescriptionUtilityD1Ev @ 121 NONAME
-	_ZN19CDescriptionUtilityD2Ev @ 122 NONAME
-	_ZN19CGetObjectPropValue13CheckRequestLEv @ 123 NONAME
-	_ZN19CGetObjectPropValue27ServiceMetaDataFromWrapperLEtR8MMTPTypeRK18CMTPObjectMetaData @ 124 NONAME
-	_ZN19CGetObjectPropValue8ServiceLEv @ 125 NONAME
-	_ZN19CGetObjectPropValueC2ER25MMTPDataProviderFrameworkR14MMTPConnectionR14MMmMtpDpConfig @ 126 NONAME
-	_ZN19CGetObjectPropValueD0Ev @ 127 NONAME
-	_ZN19CGetObjectPropValueD1Ev @ 128 NONAME
-	_ZN19CGetObjectPropValueD2Ev @ 129 NONAME
-	_ZN19CSetObjectPropValue13CheckRequestLEv @ 130 NONAME
-	_ZN19CSetObjectPropValue22DoHandleResponsePhaseLEv @ 131 NONAME
-	_ZN19CSetObjectPropValue25ServiceMetaDataToWrapperLEtR8MMTPTypeRK18CMTPObjectMetaData @ 132 NONAME
-	_ZN19CSetObjectPropValue8ServiceLEv @ 133 NONAME
-	_ZN19CSetObjectPropValueC2ER25MMTPDataProviderFrameworkR14MMTPConnectionR14MMmMtpDpConfig @ 134 NONAME
-	_ZN19CSetObjectPropValueD0Ev @ 135 NONAME
-	_ZN19CSetObjectPropValueD1Ev @ 136 NONAME
-	_ZN19CSetObjectPropValueD2Ev @ 137 NONAME
-	_ZN20CGetObjectReferences4NewLER25MMTPDataProviderFrameworkR14MMTPConnectionR14MMmMtpDpConfig @ 138 NONAME
-	_ZN20CGetObjectReferencesD0Ev @ 139 NONAME
-	_ZN20CGetObjectReferencesD1Ev @ 140 NONAME
-	_ZN20CGetObjectReferencesD2Ev @ 141 NONAME
-	_ZN20CSetObjectReferences22DoHandleResponsePhaseLEv @ 142 NONAME
-	_ZN20CSetObjectReferences22DoSetObjectReferencesLERK18CMTPObjectMetaData @ 143 NONAME
-	_ZN20CSetObjectReferences4NewLER25MMTPDataProviderFrameworkR14MMTPConnectionR14MMmMtpDpConfig @ 144 NONAME
-	_ZN20CSetObjectReferences8ServiceLEv @ 145 NONAME
-	_ZN20CSetObjectReferencesC1ER25MMTPDataProviderFrameworkR14MMTPConnectionR14MMmMtpDpConfig @ 146 NONAME
-	_ZN20CSetObjectReferencesC2ER25MMTPDataProviderFrameworkR14MMTPConnectionR14MMmMtpDpConfig @ 147 NONAME
-	_ZN20CSetObjectReferencesD0Ev @ 148 NONAME
-	_ZN20CSetObjectReferencesD1Ev @ 149 NONAME
-	_ZN20CSetObjectReferencesD2Ev @ 150 NONAME
-	_ZN22CGetFormatCapabilities10ConstructLEv @ 151 NONAME
-	_ZN22CGetFormatCapabilities13CheckRequestLEv @ 152 NONAME
-	_ZN22CGetFormatCapabilities4NewLER25MMTPDataProviderFrameworkR14MMTPConnectionR14MMmMtpDpConfig @ 153 NONAME
-	_ZN22CGetFormatCapabilities8ServiceLEv @ 154 NONAME
-	_ZN22CGetFormatCapabilitiesC1ER25MMTPDataProviderFrameworkR14MMTPConnectionR14MMmMtpDpConfig @ 155 NONAME
-	_ZN22CGetFormatCapabilitiesC2ER25MMTPDataProviderFrameworkR14MMTPConnectionR14MMmMtpDpConfig @ 156 NONAME
-	_ZN22CGetFormatCapabilitiesD0Ev @ 157 NONAME
-	_ZN22CGetFormatCapabilitiesD1Ev @ 158 NONAME
-	_ZN22CGetFormatCapabilitiesD2Ev @ 159 NONAME
-	_ZN23CMmMtpDpAccessSingleton12OpenSessionLEv @ 160 NONAME
-	_ZN23CMmMtpDpAccessSingleton13CloseSessionLEv @ 161 NONAME
-	_ZN23CMmMtpDpAccessSingleton17GetAccessWrapperLEv @ 162 NONAME
-	_ZN23CMmMtpDpAccessSingleton7CreateLER25MMTPDataProviderFramework @ 163 NONAME
-	_ZN23CMmMtpDpAccessSingleton7ReleaseEv @ 164 NONAME
-	_ZN23CPropertySettingUtility20SetMetaDataToWrapperER14MMmMtpDpConfigtR8MMTPTypeRK18CMTPObjectMetaData @ 165 NONAME
-	_ZN23CPropertySettingUtilityC2Ev @ 166 NONAME
-	_ZN23CPropertySettingUtilityD0Ev @ 167 NONAME
-	_ZN23CPropertySettingUtilityD1Ev @ 168 NONAME
-	_ZN23CPropertySettingUtilityD2Ev @ 169 NONAME
-	_ZN24CGetObjectPropsSupported4NewLER25MMTPDataProviderFrameworkR14MMTPConnectionR14MMmMtpDpConfig @ 170 NONAME
-	_ZN24CGetObjectPropsSupported8ServiceLEv @ 171 NONAME
-	_ZN24CGetObjectPropsSupportedD0Ev @ 172 NONAME
-	_ZN24CGetObjectPropsSupportedD1Ev @ 173 NONAME
-	_ZN24CGetObjectPropsSupportedD2Ev @ 174 NONAME
-	_ZN26CGetInterdependentPropDesc10ConstructLEv @ 175 NONAME
-	_ZN26CGetInterdependentPropDesc13CheckRequestLEv @ 176 NONAME
-	_ZN26CGetInterdependentPropDesc4NewLER25MMTPDataProviderFrameworkR14MMTPConnectionR14MMmMtpDpConfig @ 177 NONAME
-	_ZN26CGetInterdependentPropDesc8ServiceLEv @ 178 NONAME
-	_ZN26CGetInterdependentPropDescC1ER25MMTPDataProviderFrameworkR14MMTPConnectionR14MMmMtpDpConfig @ 179 NONAME
-	_ZN26CGetInterdependentPropDescC2ER25MMTPDataProviderFrameworkR14MMTPConnectionR14MMmMtpDpConfig @ 180 NONAME
-	_ZN26CGetInterdependentPropDescD0Ev @ 181 NONAME
-	_ZN26CGetInterdependentPropDescD1Ev @ 182 NONAME
-	_ZN26CGetInterdependentPropDescD2Ev @ 183 NONAME
+	_ZN19CDescriptionUtility24NewRangeFormDescriptionLEtmmmi @ 117 NONAME
+	_ZN19CDescriptionUtilityC2Ev @ 118 NONAME
+	_ZN19CDescriptionUtilityD0Ev @ 119 NONAME
+	_ZN19CDescriptionUtilityD1Ev @ 120 NONAME
+	_ZN19CDescriptionUtilityD2Ev @ 121 NONAME
+	_ZN19CGetObjectPropValue13CheckRequestLEv @ 122 NONAME
+	_ZN19CGetObjectPropValue27ServiceMetaDataFromWrapperLEtR8MMTPTypeRK18CMTPObjectMetaData @ 123 NONAME
+	_ZN19CGetObjectPropValue8ServiceLEv @ 124 NONAME
+	_ZN19CGetObjectPropValueC2ER25MMTPDataProviderFrameworkR14MMTPConnectionR14MMmMtpDpConfig @ 125 NONAME
+	_ZN19CGetObjectPropValueD0Ev @ 126 NONAME
+	_ZN19CGetObjectPropValueD1Ev @ 127 NONAME
+	_ZN19CGetObjectPropValueD2Ev @ 128 NONAME
+	_ZN19CSetObjectPropValue13CheckRequestLEv @ 129 NONAME
+	_ZN19CSetObjectPropValue22DoHandleResponsePhaseLEv @ 130 NONAME
+	_ZN19CSetObjectPropValue25ServiceMetaDataToWrapperLEtR8MMTPTypeRK18CMTPObjectMetaData @ 131 NONAME
+	_ZN19CSetObjectPropValue8ServiceLEv @ 132 NONAME
+	_ZN19CSetObjectPropValueC2ER25MMTPDataProviderFrameworkR14MMTPConnectionR14MMmMtpDpConfig @ 133 NONAME
+	_ZN19CSetObjectPropValueD0Ev @ 134 NONAME
+	_ZN19CSetObjectPropValueD1Ev @ 135 NONAME
+	_ZN19CSetObjectPropValueD2Ev @ 136 NONAME
+	_ZN20CGetObjectReferences4NewLER25MMTPDataProviderFrameworkR14MMTPConnectionR14MMmMtpDpConfig @ 137 NONAME
+	_ZN20CGetObjectReferencesD0Ev @ 138 NONAME
+	_ZN20CGetObjectReferencesD1Ev @ 139 NONAME
+	_ZN20CGetObjectReferencesD2Ev @ 140 NONAME
+	_ZN20CSetObjectReferences22DoHandleResponsePhaseLEv @ 141 NONAME
+	_ZN20CSetObjectReferences22DoSetObjectReferencesLERK18CMTPObjectMetaData @ 142 NONAME
+	_ZN20CSetObjectReferences4NewLER25MMTPDataProviderFrameworkR14MMTPConnectionR14MMmMtpDpConfig @ 143 NONAME
+	_ZN20CSetObjectReferences8ServiceLEv @ 144 NONAME
+	_ZN20CSetObjectReferencesC1ER25MMTPDataProviderFrameworkR14MMTPConnectionR14MMmMtpDpConfig @ 145 NONAME
+	_ZN20CSetObjectReferencesC2ER25MMTPDataProviderFrameworkR14MMTPConnectionR14MMmMtpDpConfig @ 146 NONAME
+	_ZN20CSetObjectReferencesD0Ev @ 147 NONAME
+	_ZN20CSetObjectReferencesD1Ev @ 148 NONAME
+	_ZN20CSetObjectReferencesD2Ev @ 149 NONAME
+	_ZN22CGetFormatCapabilities10ConstructLEv @ 150 NONAME
+	_ZN22CGetFormatCapabilities13CheckRequestLEv @ 151 NONAME
+	_ZN22CGetFormatCapabilities4NewLER25MMTPDataProviderFrameworkR14MMTPConnectionR14MMmMtpDpConfig @ 152 NONAME
+	_ZN22CGetFormatCapabilities8ServiceLEv @ 153 NONAME
+	_ZN22CGetFormatCapabilitiesC1ER25MMTPDataProviderFrameworkR14MMTPConnectionR14MMmMtpDpConfig @ 154 NONAME
+	_ZN22CGetFormatCapabilitiesC2ER25MMTPDataProviderFrameworkR14MMTPConnectionR14MMmMtpDpConfig @ 155 NONAME
+	_ZN22CGetFormatCapabilitiesD0Ev @ 156 NONAME
+	_ZN22CGetFormatCapabilitiesD1Ev @ 157 NONAME
+	_ZN22CGetFormatCapabilitiesD2Ev @ 158 NONAME
+	_ZN23CMmMtpDpAccessSingleton12OpenSessionLEv @ 159 NONAME
+	_ZN23CMmMtpDpAccessSingleton13CloseSessionLEv @ 160 NONAME
+	_ZN23CMmMtpDpAccessSingleton17GetAccessWrapperLEv @ 161 NONAME
+	_ZN23CMmMtpDpAccessSingleton7CreateLER25MMTPDataProviderFramework @ 162 NONAME
+	_ZN23CMmMtpDpAccessSingleton7ReleaseEv @ 163 NONAME
+	_ZN23CPropertySettingUtility20SetMetaDataToWrapperER14MMmMtpDpConfigtR8MMTPTypeRK18CMTPObjectMetaData @ 164 NONAME
+	_ZN23CPropertySettingUtilityC2Ev @ 165 NONAME
+	_ZN23CPropertySettingUtilityD0Ev @ 166 NONAME
+	_ZN23CPropertySettingUtilityD1Ev @ 167 NONAME
+	_ZN23CPropertySettingUtilityD2Ev @ 168 NONAME
+	_ZN24CGetObjectPropsSupported4NewLER25MMTPDataProviderFrameworkR14MMTPConnectionR14MMmMtpDpConfig @ 169 NONAME
+	_ZN24CGetObjectPropsSupported8ServiceLEv @ 170 NONAME
+	_ZN24CGetObjectPropsSupportedD0Ev @ 171 NONAME
+	_ZN24CGetObjectPropsSupportedD1Ev @ 172 NONAME
+	_ZN24CGetObjectPropsSupportedD2Ev @ 173 NONAME
+	_ZN26CGetInterdependentPropDesc10ConstructLEv @ 174 NONAME
+	_ZN26CGetInterdependentPropDesc13CheckRequestLEv @ 175 NONAME
+	_ZN26CGetInterdependentPropDesc4NewLER25MMTPDataProviderFrameworkR14MMTPConnectionR14MMmMtpDpConfig @ 176 NONAME
+	_ZN26CGetInterdependentPropDesc8ServiceLEv @ 177 NONAME
+	_ZN26CGetInterdependentPropDescC1ER25MMTPDataProviderFrameworkR14MMTPConnectionR14MMmMtpDpConfig @ 178 NONAME
+	_ZN26CGetInterdependentPropDescC2ER25MMTPDataProviderFrameworkR14MMTPConnectionR14MMmMtpDpConfig @ 179 NONAME
+	_ZN26CGetInterdependentPropDescD0Ev @ 180 NONAME
+	_ZN26CGetInterdependentPropDescD1Ev @ 181 NONAME
+	_ZN26CGetInterdependentPropDescD2Ev @ 182 NONAME
+	_ZN29CMmMtpDpMetadataAccessWrapper10AddObjectLERK18CMTPObjectMetaData @ 183 NONAME
 	_ZN29CMmMtpDpMetadataAccessWrapper13AddDummyFileLERK7TDesC16 @ 184 NONAME
 	_ZN29CMmMtpDpMetadataAccessWrapper13DeleteObjectLERK18CMTPObjectMetaData @ 185 NONAME
 	_ZN29CMmMtpDpMetadataAccessWrapper13RenameObjectLERK18CMTPObjectMetaDataRK7TDesC16 @ 186 NONAME
--- a/mmappcomponents/mmmtpdataprovider/mmmtpdprequestprocessor/src/cdescriptionutility.cpp	Fri Apr 23 13:55:04 2010 +0100
+++ b/mmappcomponents/mmmtpdataprovider/mmmtpdprequestprocessor/src/cdescriptionutility.cpp	Wed Apr 28 22:20:05 2010 +0100
@@ -39,7 +39,7 @@
     // Do nothing
     }
 
-EXPORT_C CMTPTypeObjectPropDesc* CDescriptionUtility::NewCommonObjectPropertyL( TUint16 aPropCode )
+CMTPTypeObjectPropDesc* CDescriptionUtility::NewCommonObjectPropertyL( TUint16 aPropCode )
     {
     CMTPTypeObjectPropDesc* propertyDesc = NULL;
 
--- a/mmappcomponents/mmmtpdataprovider/mmmtpdprequestprocessor/src/csendobject.cpp	Fri Apr 23 13:55:04 2010 +0100
+++ b/mmappcomponents/mmmtpdataprovider/mmmtpdprequestprocessor/src/csendobject.cpp	Wed Apr 28 22:20:05 2010 +0100
@@ -1108,8 +1108,18 @@
 
     if ( result && ( iObjectFormat != MmMtpDpUtility::FormatFromFilename( iFullPath ) ) )
         {
-        PRINT2( _L( "MM MTP <> %S does not match 0x%x" ), &iFullPath, iObjectFormat );
-        result = EFalse;
+        TParsePtrC file( aFileName );
+        if ( ( iObjectFormat == EMTPFormatCode3GPContainer ) && (file.Ext().CompareF( KTxtExtensionODF ) == 0))
+            {
+            PRINT( _L( "MM MTP <> might happen if function is called before physical file arrives" ) );
+            // might happen if function is called before physical file arrives
+            // do nothing
+            }
+        else
+            {
+            PRINT2( _L( "MM MTP <> %S does not match 0x%x" ), &iFullPath, iObjectFormat );
+            result = EFalse;
+            }
         }
 
     PRINT1( _L( "MM MTP <= CSendObject::GetFullPathNameL result = %d" ), result );
--- a/mmappcomponents/mmmtpdataprovider/mmmtpdprequestprocessor/src/csetobjectreferences.cpp	Fri Apr 23 13:55:04 2010 +0100
+++ b/mmappcomponents/mmmtpdataprovider/mmmtpdprequestprocessor/src/csetobjectreferences.cpp	Wed Apr 28 22:20:05 2010 +0100
@@ -154,7 +154,7 @@
         {
         MMTPReferenceMgr& referenceMgr = iFramework.ReferenceMgr();
         TUint32 objectHandle = Request().Uint32( TMTPTypeRequest::ERequestParameter1 );
-        PRINT1( _L( "MM MTP <>CSetObjectReferences::DoHandleResponsePhaseL objectHandle = 0x%x" ), objectHandle );
+        PRINT1( _L( "MM MTP <> CSetObjectReferences::DoHandleResponsePhaseL objectHandle = 0x%x" ), objectHandle );
         referenceMgr.SetReferencesL( TMTPTypeUint32( objectHandle ),
             *iReferences );
 
--- a/mmappcomponents/mmmtpdataprovider/src/cmmmtpdpmetadataaccesswrapper.cpp	Fri Apr 23 13:55:04 2010 +0100
+++ b/mmappcomponents/mmmtpdataprovider/src/cmmmtpdpmetadataaccesswrapper.cpp	Wed Apr 28 22:20:05 2010 +0100
@@ -46,7 +46,8 @@
 
 CMmMtpDpMetadataAccessWrapper::CMmMtpDpMetadataAccessWrapper( MMTPDataProviderFramework& aFramework ) :
     iFramework( aFramework ),
-    iFs( aFramework.Fs() )
+    iFs( aFramework.Fs() ),
+    iOpenCount( 0 )
     {
     // Do nothing
     }
@@ -350,7 +351,7 @@
 //
 void CMmMtpDpMetadataAccessWrapper::OpenSessionL()
     {
-    iOpenSession = ETrue;
+    iOpenCount++;
     }
 
 // -----------------------------------------------------------------------------
@@ -360,15 +361,22 @@
 //
 void CMmMtpDpMetadataAccessWrapper::CloseSessionL()
     {
-    if ( iOpenSession )
+    PRINT1( _L( "MM MTP <> CMmMtpDpMetadataAccessWrapper::CloseSessionL count = %d" ), iOpenCount );
+
+    if ( iOpenCount >= 1 )
         {
-        PRINT( _L( "MM MTP <> CMmMtpDpMetadataAccessWrapper::CloseSessionL close" ) );
-        iMmMtpDpMetadataVideoAccess->CloseSessionL();
-        iOpenSession = EFalse;
+        iOpenCount--;
+
+        if ( iOpenCount == 0 )
+            {
+            PRINT( _L( "MM MTP <> CMmMtpDpMetadataAccessWrapper::CloseSessionL close" ) );
+            iMmMtpDpMetadataMpxAccess->CloseSession();
+            iMmMtpDpMetadataVideoAccess->CloseSessionL();
+            }
         }
     else
         {
-        PRINT( _L( "MM MTP <> CMmMtpDpMetadataAccessWrapper::CloseSessionL alreay close" ) );
+        PRINT( _L( "MM MTP <> CMmMtpDpMetadataAccessWrapper::CloseSessionL already close" ) );
         }
     }
 
@@ -390,13 +398,13 @@
             TUint aSubFormatCode = aObject.Uint( CMTPObjectMetaData::EFormatSubCode );
             if ( aSubFormatCode == EMTPSubFormatCodeUnknown )
                 {
-                category = ContainerCategory( aObject.DesC( CMTPObjectMetaData::ESuid ) );
+                TRAP_IGNORE( category = ContainerCategoryL( aObject.DesC( CMTPObjectMetaData::ESuid ) ) );
                 if ( category == EMPXSong )
                     aSubFormatCode = EMTPSubFormatCodeAudio;
                 else if ( category == EMPXVideo )
                     aSubFormatCode = EMTPSubFormatCodeVideo;
                 else
-                    aSubFormatCode = EMTPSubFormatCodeUndefine;
+                    aSubFormatCode = EMTPSubFormatCodeUndefined;
                 const_cast<CMTPObjectMetaData&>(aObject).SetUint( CMTPObjectMetaData::EFormatSubCode, aSubFormatCode );
                 // If object doesn't exist, do nothing
                 TRAP_IGNORE( iFramework.ObjectMgr().ModifyObjectL( aObject ) );
@@ -405,7 +413,7 @@
                 category = EMPXSong;
             else if ( aSubFormatCode == EMTPSubFormatCodeVideo )
                 category = EMPXVideo;
-            else if( aSubFormatCode == EMTPSubFormatCodeUndefine )
+            else if( aSubFormatCode == EMTPSubFormatCodeUndefined )
                 category = EMPXOther;
             }
             break;
@@ -445,9 +453,9 @@
     return category;
     }
 
-TMPXGeneralCategory CMmMtpDpMetadataAccessWrapper::ContainerCategory( const TDesC& aFullFileName )
+TMPXGeneralCategory CMmMtpDpMetadataAccessWrapper::ContainerCategoryL( const TDesC& aFullFileName )
     {
-    PRINT1( _L( "MM MTP => CMmMtpDpMetadataAccessWrapper::ContainerCategory aFullFileName = %S" ), &aFullFileName );
+    PRINT1( _L( "MM MTP => CMmMtpDpMetadataAccessWrapper::ContainerCategoryL aFullFileName = %S" ), &aFullFileName );
 
     TMPXGeneralCategory category = EMPXNoCategory;
     TParsePtrC pathParser( aFullFileName );
@@ -455,17 +463,27 @@
 
     if ( ext.Length() <= 0 )
         category = EMPXOther;
+    else if ( ext.CompareF( KTxtExtensionO4A ) == 0
+        || ext.CompareF( KTxtExtensionM4A ) == 0 )
+        category = EMPXSong;
+    else if ( ext.CompareF( KTxtExtensionO4V ) == 0 )
+        category = EMPXVideo;
+    else
+        {
+        HBufC8* mimetype = NULL;
 
-    if ( ext.CompareF( KTxtExtensionMP4 ) == 0
-        || ext.CompareF( KTxtExtension3GP ) == 0
-        || ext.CompareF( KTxtExtension3G2 ) == 0
-        || ext.CompareF( KTxtExtensionODF ) == 0
-        || ext.CompareF( KTxtExtensionASF ) == 0 )
-        {
-        HBufC8* mimetype = MmMtpDpUtility::ContainerMimeType( aFullFileName );
+        if ( ext.CompareF( KTxtExtensionMP4 ) == 0
+            || ext.CompareF( KTxtExtension3GP ) == 0
+            || ext.CompareF( KTxtExtension3G2 ) == 0 )
+            mimetype = MmMtpDpUtility::Mp4MimeTypeL( aFullFileName );
+        else if ( ext.CompareF( KTxtExtensionODF ) == 0 )
+            mimetype = MmMtpDpUtility::OdfMimeTypeL( aFullFileName );
+        else if ( ext.CompareF( KTxtExtensionASF ) == 0 )
+            mimetype = MmMtpDpUtility::AsfMimeTypeL( aFullFileName );
         if ( mimetype != NULL )
             {
-            TMmMtpSubFormatCode subFormatCode = MmMtpDpUtility::SubFormatCodeFromMime( *mimetype );
+            TMmMtpSubFormatCode subFormatCode =
+                MmMtpDpUtility::SubFormatCodeFromMime( *mimetype );
 
             if ( subFormatCode == EMTPSubFormatCodeVideo )
                 category = EMPXVideo;
@@ -475,12 +493,8 @@
                 category = EMPXOther;
             }
         }
-    else if ( ext.CompareF( KTxtExtensionO4V ) == 0 )
-        category = EMPXVideo;
-    else
-        category = EMPXOther;
 
-    PRINT1( _L( "MM MTP <= CMmMtpDpMetadataAccessWrapper::ContainerCategory, category = %d" ), category );
+    PRINT1( _L( "MM MTP <= CMmMtpDpMetadataAccessWrapper::ContainerCategoryL, category = %d" ), category );
     return category;
     }
 
@@ -518,7 +532,7 @@
 // Add object (music, video, playlist and abstract media) info to DB
 // -----------------------------------------------------------------------------
 //
-void CMmMtpDpMetadataAccessWrapper::AddObjectL( const CMTPObjectMetaData& aObject )
+EXPORT_C void CMmMtpDpMetadataAccessWrapper::AddObjectL( const CMTPObjectMetaData& aObject )
     {
     PRINT( _L( "MM MTP => CMmMtpDpMetadataAccessWrapper::AddObjectL" ) );
     TMPXGeneralCategory category = Category( aObject );
@@ -531,7 +545,7 @@
         }
     else if ( category == EMPXPlaylist || category == EMPXAbstractAlbum )
         {
-        PRINT( _L( "MM MTP => CMmMtpDpMetadataAccessWrapper::AddObjectL AddPlaylist" ) );
+        PRINT( _L( "MM MTP => CMmMtpDpMetadataAccessWrapper::AddObjectL AddPlaylist/AbstractAlbum" ) );
         iMmMtpDpMetadataMpxAccess->AddAbstractMediaL( fullFileName,
             category );
         }
--- a/mmappcomponents/mmmtpdataprovider/src/cmmmtpdpmetadatampxaccess.cpp	Fri Apr 23 13:55:04 2010 +0100
+++ b/mmappcomponents/mmmtpdataprovider/src/cmmmtpdpmetadatampxaccess.cpp	Wed Apr 28 22:20:05 2010 +0100
@@ -105,7 +105,7 @@
 //
 CMmMtpDpMetadataMpxAccess::~CMmMtpDpMetadataMpxAccess()
     {
-    if ( iCollectionHelper )
+    if ( iCollectionHelper != NULL )
         {
         iCollectionHelper->Close();
         iCollectionHelper = NULL;
@@ -118,6 +118,36 @@
     }
 
 // ---------------------------------------------------------------------------
+// CMmMtpDpMetadataMpxAccess::OpenSession
+// This is introduced to fix CollectionHelper Flush problem
+// ---------------------------------------------------------------------------
+//
+void CMmMtpDpMetadataMpxAccess::OpenSession()
+    {
+    // do nothing
+    }
+
+// ---------------------------------------------------------------------------
+// CMmMtpDpMetadataMpxAccess::CloseSession
+// This is introduced to fix CollectionHelper Flush problem
+// ---------------------------------------------------------------------------
+//
+void CMmMtpDpMetadataMpxAccess::CloseSession()
+    {
+    PRINT( _L( "MM MTP => CMmMtpDpMetadataMpxAccess::CloseSession" ) );
+
+    // flush cache
+    if ( iCollectionHelper != NULL )
+        {
+        PRINT( _L( "MM MTP <> Delete & Close CollectionHelper" ) );
+        iCollectionHelper->Close();
+        iCollectionHelper = NULL;
+        }
+
+    PRINT( _L( "MM MTP <= CMmMtpDpMetadataMpxAccess::CloseSession" ) );
+    }
+
+// ---------------------------------------------------------------------------
 // CMmMtpDpMetadataMpxAccess::GetObjectMetadataValueL
 // Gets a piece of metadata from the collection
 // ---------------------------------------------------------------------------
@@ -644,6 +674,7 @@
     TParsePtrC parse( aFullFileName );
     media->SetTextValueL( KMPXMediaGeneralUri, aFullFileName );
     media->SetTextValueL( KMPXMediaGeneralDrive, parse.Drive() );
+    media->SetTObjectValueL( KMPXMediaGeneralModified, EFalse );
 
     PERFLOGSTART( KSetMetadataValue );
     SetMetadataValueL( aPropCode, aNewData, *media );
@@ -1018,10 +1049,7 @@
     CleanupClosePushL( abstractMediaAttributes ); // + abstractMediaAttributes
     abstractMediaAttributes.AppendL( KMPXMediaGeneralId );
     abstractMediaAttributes.AppendL( KMPXMediaGeneralTitle );
-    if ( aCategory == EMPXPlaylist )    // rollback until Rename is supported on MPX DB
-        {
-        abstractMediaAttributes.AppendL( KMPXMediaGeneralUri );
-        }
+    abstractMediaAttributes.AppendL( KMPXMediaGeneralUri );
 
     PERFLOGSTART( KMpxCollectionFindAllLBeforeAdd );
     CMPXMedia* foundMedia = CollectionHelperL()->FindAllL( *searchMedia,
@@ -1067,10 +1095,7 @@
 
         TParsePtrC parse( aFullFileName );
         media->SetTextValueL( KMPXMediaGeneralDrive, parse.Drive() );
-        if ( aCategory == EMPXPlaylist )    // rollback until Rename is supported on MPX DB
-            {
-            media->SetTextValueL( KMPXMediaGeneralTitle, parse.Name() );
-            }
+        media->SetTextValueL( KMPXMediaGeneralTitle, parse.Name() );
         media->SetTObjectValueL<TBool>( KMPXMediaGeneralSynchronized, ETrue );
         media->SetCObjectValueL( KMPXMediaArrayContents, abstractMediaArray );
         media->SetTObjectValueL( KMPXMediaArrayCount, abstractMediaArray->Count() );
@@ -1132,7 +1157,8 @@
         // TODO: need to confirm that should set drive letter or storage root path.
         TParsePtrC parse( aRefFileArray[j] );
         media->SetTextValueL( KMPXMediaGeneralDrive, parse.Drive() );
-
+        media->SetTObjectValueL( KMPXMediaGeneralModified, EFalse );
+  
         // Add media into array contents
         abstractMediaArray->AppendL( media );
 
@@ -1313,10 +1339,8 @@
     CleanupClosePushL( abstractMediaAttributes ); // + abstractMediaAttributes
     abstractMediaAttributes.AppendL( KMPXMediaGeneralId );
     abstractMediaAttributes.AppendL( KMPXMediaGeneralTitle );
-    if ( aCategory == EMPXPlaylist )    // rollback until Rename is supported on MPX DB
-        {
-        abstractMediaAttributes.AppendL( KMPXMediaGeneralUri );
-        }
+
+    abstractMediaAttributes.AppendL( KMPXMediaGeneralUri );
 
     PERFLOGSTART( KMpxCollectionGetAbstractMedia );
     CMPXMedia* foundMedia = CollectionHelperL()->FindAllL( *searchMedia,
@@ -1447,7 +1471,7 @@
     {
     PRINT( _L( "MM MTP => CMmMtpDpMetadataMpxAccess::GetAbstractMediaNameL" ) );
     HBufC* name = NULL;
-    if ( aCategory == EMPXPlaylist )    // rollback until Rename is supported on MPX DB
+    if ( aCategory == EMPXPlaylist || aCategory == EMPXAbstractAlbum )
         {
         if( !aAbstractMedia->IsSupported( KMPXMediaGeneralUri ) )
             {
@@ -1455,14 +1479,6 @@
             }
         name = aAbstractMedia->ValueText( KMPXMediaGeneralUri ).AllocL();
         }
-    else if ( aCategory == EMPXAbstractAlbum )
-        {
-        if ( !aAbstractMedia->IsSupported( KMPXMediaGeneralTitle ) )
-            {
-            User::Leave( KErrNotSupported );
-            }
-        name = aAbstractMedia->ValueText( KMPXMediaGeneralTitle ).AllocL();
-        }
     else
         {
         User::Leave( KErrNotSupported );
--- a/mmappcomponents/mmmtpdataprovider/src/mmmtpdputility.cpp	Fri Apr 23 13:55:04 2010 +0100
+++ b/mmappcomponents/mmmtpdataprovider/src/mmmtpdputility.cpp	Wed Apr 28 22:20:05 2010 +0100
@@ -100,7 +100,7 @@
 #endif // __WINDOWS_MEDIA
             else if ( file.Ext().CompareF( KTxtExtensionODF ) == 0 )
                 {
-                HBufC8* mime = MmMtpDpUtility::ContainerMimeType( file.FullName() );
+                HBufC8* mime = MmMtpDpUtility::OdfMimeTypeL( file.FullName() );
                 if ( mime != NULL )
                     {
                     // 3GP
@@ -409,54 +409,6 @@
     }
 
 // -----------------------------------------------------------------------------
-// MetadataAccessWrapper::ContainerMimeType
-// Get mime type from file
-// -----------------------------------------------------------------------------
-//
-HBufC8* MmMtpDpUtility::ContainerMimeType( const TDesC& aFullPath )
-    {
-    PRINT( _L( "MM MTP => MmMtpDpUtility::ContainerMimeType" ) );
-
-    // parse the file path
-    TParsePtrC pathParser( aFullPath );
-
-    // get the extension of file
-    TPtrC ext( pathParser.Ext() );
-    if ( ext.Length() <= 0 )
-        {
-        PRINT( _L( "MM MTP <> MmMtpDpUtility::ContainerMimeType file ext len == 0" ) );
-        return NULL;
-        }
-
-    HBufC8* mimebuf = NULL;
-    TInt err = KErrNone;
-
-    // MP4/3GP
-    if ( ext.CompareF( KTxtExtensionMP4 ) == 0
-        || ext.CompareF( KTxtExtension3GP ) == 0
-        || ext.CompareF( KTxtExtension3G2 ) == 0 )
-        {
-        TRAP( err, mimebuf = Mp4MimeTypeL( aFullPath ) );
-        PRINT1( _L("MM MTP <> MmMtpDpUtility::ContainerMimeType, Mp4MimeTypeL err = %d"), err );
-        }
-    else if ( ext.CompareF( KTxtExtensionODF ) == 0 )
-        {
-        TRAP( err, mimebuf = OdfMimeTypeL( aFullPath ) );
-        PRINT1( _L("MM MTP <> MmMtpDpUtility::ContainerMimeType, OdfMimeTypeL err = %d"), err );
-        }
-#ifdef __WINDOWS_MEDIA
-    else if ( ext.CompareF( KTxtExtensionASF ) == 0 )
-        {
-        TRAP( err, mimebuf = AsfMimeTypeL( aFullPath ) );
-        PRINT1( _L("MM MTP <> MmMtpDpUtility::ContainerMimeType, AsfMimeTypeL err = %d"), err );
-        }
-#endif
-
-    PRINT( _L( "MM MTP <= MmMtpDpUtility::ContainerMimeType" ) );
-    return mimebuf;
-    }
-
-// -----------------------------------------------------------------------------
 // MetadataAccessWrapper::Mp4MimeTypeL
 // Get mime type from mp4 file
 // -----------------------------------------------------------------------------
@@ -519,7 +471,7 @@
             // is video file
             else if ( mp4err == MP4_OK )
                 {
-                if ( file.Ext().CompareF( KTxtExtension3GP ) == 0 
+                if ( file.Ext().CompareF( KTxtExtension3GP ) == 0
                     || file.Ext().CompareF( KTxtExtension3G2 ) == 0 )
                     {
                     mimebuf = KMimeTypeVideo3gpp().Alloc();
@@ -562,44 +514,35 @@
     PRINT( _L( "MM MTP => MmMtpDpUtility::OdfMimeTypeL" ) );
     HBufC8* mimebuf = NULL;
 
-    TParsePtrC file( aFullPath );
+    CContent* content = CContent::NewL( aFullPath );
+    CleanupStack::PushL( content ); // + content
 
-    if ( file.Ext().CompareF( KTxtExtensionODF ) == 0 )
-        {
-        CContent* content = CContent::NewL( aFullPath );
-        CleanupStack::PushL( content ); // + content
-
-        HBufC* buffer = HBufC::NewL( KMimeTypeMaxLength );
-        CleanupStack::PushL( buffer ); // + buffer
+    HBufC* buffer = HBufC::NewL( KMimeTypeMaxLength );
+    CleanupStack::PushL( buffer ); // + buffer
 
-        TPtr data = buffer->Des();
-        TInt err = content->GetStringAttribute( EMimeType, data );
-
-        if ( err == KErrNone )
-            {
-            mimebuf = HBufC8::New( buffer->Length() );
+    TPtr data = buffer->Des();
+    TInt err = content->GetStringAttribute( EMimeType, data );
 
-            if (mimebuf == NULL)
-                {
-                User::LeaveIfError( KErrNotFound );
-                }
+    if ( err == KErrNone )
+        {
+        mimebuf = HBufC8::New( buffer->Length() );
 
-            mimebuf->Des().Copy( *buffer );
+        if ( mimebuf == NULL )
+            {
+            User::LeaveIfError( KErrNotFound );
             }
 
-        // leave if NULL
-        if ( mimebuf == NULL )
-            {
-            User::Leave( KErrNotFound );
-            }
+        mimebuf->Des().Copy( *buffer );
+        }
 
-        CleanupStack::PopAndDestroy( buffer ); // - buffer
-        CleanupStack::PopAndDestroy( content ); // - content
+    // leave if NULL
+    if ( mimebuf == NULL )
+        {
+        User::Leave( KErrNotFound );
         }
-    else
-        {
-        User::Leave( KErrNotSupported );
-        }
+
+    CleanupStack::PopAndDestroy( buffer ); // - buffer
+    CleanupStack::PopAndDestroy( content ); // - content
 
     PRINT( _L( "MM MTP <= MmMtpDpUtility::OdfMimeTypeL" ) );
     return mimebuf;
@@ -617,62 +560,52 @@
     HBufC8* mimebuf = NULL;
 
 #ifdef __WINDOWS_MEDIA
-    TParsePtrC file( aFullPath );
-
-    if ( file.Ext().CompareF( KTxtExtensionASF ) == 0 )
-        {
-        CHXMetaDataUtility *hxUtility = CHXMetaDataUtility::NewL();
-        CleanupStack::PushL( hxUtility );
-
-        hxUtility->OpenFileL( aFullPath );
-        PRINT( _L( "MM MTP <> MmMtpDpUtility::AsfMimeTypeL OpenFileL" ) );
+    CHXMetaDataUtility *hxUtility = CHXMetaDataUtility::NewL();
+    CleanupStack::PushL( hxUtility );
 
-        HXMetaDataKeys::EHXMetaDataId id;
-        TUint count = 0;
-        TBool isAudio = EFalse;
-        hxUtility->GetMetaDataCount( count );
-        for ( TUint i = 0; i < count; i++ )
-            {
-            HBufC* buf = NULL;
-            hxUtility->GetMetaDataAt( i, id, buf );
-
-            if ( id == HXMetaDataKeys::EHXMimeType )
-                {
-                TPtr des = buf->Des();
+    hxUtility->OpenFileL( aFullPath );
+    PRINT( _L( "MM MTP <> MmMtpDpUtility::AsfMimeTypeL OpenFileL" ) );
 
-                if ( des.Find( KHxMimeTypeWma() ) != KErrNotFound )
-                    {
-                    isAudio = ETrue;
-                    }
-                else if ( des.Find( KHxMimeTypeWmv() ) != KErrNotFound )
-                    {
-                    PRINT( _L( "MM MTP <> MmMtpDpUtility::AsfMimeTypeL, video" ) );
-                    mimebuf = KMimeTypeVideoWm().Alloc();
-                    break;
-                    }
+    HXMetaDataKeys::EHXMetaDataId id;
+    TUint count = 0;
+    TBool isAudio = EFalse;
+    hxUtility->GetMetaDataCount( count );
+    for ( TUint i = 0; i < count; i++ )
+        {
+        HBufC* buf = NULL;
+        hxUtility->GetMetaDataAt( i, id, buf );
+
+        if ( id == HXMetaDataKeys::EHXMimeType )
+            {
+            TPtr des = buf->Des();
+
+            if ( des.Find( KHxMimeTypeWma() ) != KErrNotFound )
+                {
+                isAudio = ETrue;
                 }
-            else if ( i == count - 1 )
+            else if ( des.Find( KHxMimeTypeWmv() ) != KErrNotFound )
                 {
-                if ( isAudio )
-                    {
-                    PRINT( _L( "MM MTP <> MmMtpDpUtility::AsfMimeTypeL, audio" ) );
-                    mimebuf = KMimeTypeAudioWm().Alloc();
-                    }
-                else
-                    {
-                    User::Leave( KErrNotFound );
-                    }
+                PRINT( _L( "MM MTP <> MmMtpDpUtility::AsfMimeTypeL, video" ) );
+                mimebuf = KMimeTypeVideoWm().Alloc();
+                break;
                 }
             }
-
-        hxUtility->ResetL();
-        CleanupStack::PopAndDestroy( hxUtility );
-        }
-    else
-        {
-        User::Leave( KErrNotSupported );
+        else if ( i == count - 1 )
+            {
+            if ( isAudio )
+                {
+                PRINT( _L( "MM MTP <> MmMtpDpUtility::AsfMimeTypeL, audio" ) );
+                mimebuf = KMimeTypeAudioWm().Alloc();
+                }
+            else
+                {
+                User::Leave( KErrNotFound );
+                }
+            }
         }
 
+    hxUtility->ResetL();
+    CleanupStack::PopAndDestroy( hxUtility );
 #else
     User::Leave( KErrNotSupported );
 #endif
@@ -713,7 +646,7 @@
     else
         {
         PRINT( _L( "MM MTP <= MmMtpDpUtility::SubFormatCodeFromMime format not supported" ) );
-        subFormatCode = EMTPSubFormatCodeUndefine;
+        subFormatCode = EMTPSubFormatCodeUndefined;
         }
 
     PRINT1( _L( "MM MTP <= MmMtpDpUtility::SubFormatCodeFromMime SubFormatCode = %d" ), subFormatCode );
--- a/mmappfw_plat/harvester_metadata_extractor_api/group/bld.inf	Fri Apr 23 13:55:04 2010 +0100
+++ b/mmappfw_plat/harvester_metadata_extractor_api/group/bld.inf	Wed Apr 28 22:20:05 2010 +0100
@@ -25,3 +25,4 @@
 PRJ_EXPORTS          
           
 ../inc/mpxmetadataextractor.h                    MW_LAYER_PLATFORM_EXPORT_PATH(mpxmetadataextractor.h)                            
+../inc/mpxmetadataextractorobserver.h            MW_LAYER_PLATFORM_EXPORT_PATH(mpxmetadataextractorobserver.h)                            
--- a/mmappfw_plat/harvester_metadata_extractor_api/inc/mpxmetadataextractor.h	Fri Apr 23 13:55:04 2010 +0100
+++ b/mmappfw_plat/harvester_metadata_extractor_api/inc/mpxmetadataextractor.h	Wed Apr 28 22:20:05 2010 +0100
@@ -24,6 +24,7 @@
 class CMetaDataUtility;
 class CMPXFileInfoUtility;
 class CMPXDrmMediaUtility;
+class MMPXMetadataExtractorObserver;
 #include <thumbnailmanager.h>
 #include <thumbnailmanagerobserver.h>
 
@@ -33,7 +34,7 @@
  *  @lib mpxfilehandler.lib
  */
 class CMPXMetadataExtractor : public CBase,
-                            public MThumbnailManagerObserver
+                              public MThumbnailManagerObserver
     {
     
 public:
@@ -72,6 +73,27 @@
      */
     IMPORT_C TInt ExtractAlbumArtL( CMPXMedia* aMedia );
     
+    /*
+    * Create a media object for a file. This is a asynchronous function.
+    * This function will leave with KErrAbort if still processing last request.
+    * Callback function is HandleCreateMediaComplete()
+    * @since 9.2
+    * @param aFile a fullpath to the file.
+    * @param aObs Metadata Extractor Observer
+    * @param aMetadataOnly extract metadata only or not. Default EFalse
+    */
+    IMPORT_C void CreateMediaAsyncL( const TDesC& aFile,
+                                     MMPXMetadataExtractorObserver* aObs,
+                                     TBool aMetadataOnly = EFalse );
+
+    /**
+     * Cancel request.  This will empty the task array and stop the wait loop. This
+     *                  will cause the CreateMediaL() to finish more quickly. Also,
+     *                  all outstanding thumbnail requests are cancelled.
+     * @since 9.2
+     */
+    IMPORT_C void CancelRequest();
+    
 private: // New Functions:
     
     /**
@@ -84,26 +106,14 @@
     /**
     * Function to go through the metadata entries.
     * @since 3.2.3
-    * @param aProp Media Properties to update.
-    * @param aFile File name
     */
-    void SetMediaPropertiesL( CMPXMedia& aProp, 
-                              const TDesC& aFile );
+    void SetMediaPropertiesL();
     
     /**
     * Sets other media properties not found from metadata util.
     * @since 3.2.3
-    * @param aProp Media Properties to update.
-    * @param aFile file name.
-    * @param aMetadataOnly extract metadata only or not Default EFalse.
-    * @param aFileHandle file handle to the file. 
-    * @param aFileErr file handle error if file could not be opened
     */
-    void SetExtMediaPropertiesL( CMPXMedia& aProp, 
-                                 const TDesC& aFile,
-                                 TBool aMetadataOnly,
-                                 RFile& aFileHandle,
-                                 TInt aFileErr  );   
+    void SetExtMediaPropertiesL();   
                                 
     /**
     * Checks to see if a container type is supported.
@@ -151,22 +161,12 @@
     static TInt TimeoutTimerCallback(TAny* aPtr);
 
     /**
-     * Get album art metadata.
-     * @since 5.0
-     * @param aMedia
-     * @return error ID 
-     */
-    TInt GetMediaAlbumArtL( CMPXMedia& aMedia,
-                            const TDesC& aFile );
-    
-    /**
      * Add album art to media object.
      * @since 5.0
      * @param aMedia
      */
     void AddMediaAlbumArtL( CMPXMedia& aMedia,
-                            const TDesC& aFile,
-                            TDesC8& aValue);
+                            const TDesC& aFile );
     
     /**
      * Check if can send request to TNM or not.
@@ -175,6 +175,62 @@
      */                     
     void CheckBeforeSendRequest();
     
+    /**
+     * Cancel all outstanding thumbnail requests
+     * @since 9.2
+     * 
+     */                     
+    void CancelAllThumbnailRequests();
+    
+    /**
+     * Create media and set default data.
+     * @since 9.2
+     * 
+     */                     
+    void DoCreateMediaL();
+    
+    /**
+     * Execute task at index 0.
+     * @since 9.2
+     * 
+     */                     
+    void ExecuteTaskL();
+    
+    /**
+     * Cancel task timer. 
+     */
+    void CancelTaskTimer();
+    
+    /**
+    * Callback when the task timer expires.
+    */
+    static TInt TaskTimerCallback(TAny* aPtr);
+
+    /**
+     * Populate task array
+     * @since 9.2
+     */
+    void AddTasksL();
+    
+    /**
+     * Opens the file
+     * @since 9.2
+     * @return system error
+     */
+    TInt OpenFile();
+    
+    /**
+     * Handle task timer expired
+     * @since 9.2 
+     */
+    void HandleTaskTimerExpired();
+    
+    /**
+     * Clean up
+     * @since 9.2 
+     */
+    void CleanUp();
+    
 private:
 
     /**
@@ -190,6 +246,15 @@
     void ConstructL();
 
 private: // data
+    enum EMetadataExtractorTasks
+        {
+        ETaskCreateMedia,
+        ETaskAddMetadata,
+        ETaskAddExtMetadata,
+        ETaskAddAlbumArt,
+        ETaskCheckBeforeSend
+        };
+    
     CMetaDataUtility*    iMetadataUtility;  // extract metadata from file
     CMPXDrmMediaUtility* iDrmMediaUtility;  // extra drm data from file
     CMPXFileInfoUtility* iFileInfoUtil;     // extract duration/bitrate etc from file
@@ -200,8 +265,16 @@
     CThumbnailManager*    iTNManager;
     CActiveSchedulerWait* iTNSyncWait;  // wait loop use to sync thumbnail
     CPeriodic*            iTimer; // backup timer to stop wait loop
-    TInt                  iOutstandingThumbnailRequest;
-    TInt                  iTNMBlockCount;
+    RArray<TThumbnailRequestId>     iArrayTNRequestId;
+    RArray<EMetadataExtractorTasks> iArrayTasks;
+    TBool                           iCancelled;
+    CPeriodic*                      iTaskTimer; // timer for task execution
+    MMPXMetadataExtractorObserver*  iObs; // metadata extractor obserer
+    TFileName                       iFileName;
+    RFile                           iFile;
+    CMPXMedia*                      iMedia;  // ownership transferred
+    TBool                           iMetadataOnly;
+    TInt                            iFileOpenError;
     };
 
 #endif // CMPXMETADATAEXTRACTOR_H
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mmappfw_plat/harvester_metadata_extractor_api/inc/mpxmetadataextractorobserver.h	Wed Apr 28 22:20:05 2010 +0100
@@ -0,0 +1,43 @@
+/*
+* Copyright (c) 2006 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:  Observer class for metadata extractor
+*
+*/
+
+
+#ifndef MMPXMETADATAEXTRACTOROBSERVER_H
+#define MMPXMETADATAEXTRACTOROBSERVER_H
+
+class CMPXMediaArray;
+
+/**
+ *  Metadata Extractor observer
+ *
+ *  @lib mpxfilehandler.lib
+ *  @since S60 v9.2
+ */
+class MMPXMetadataExtractorObserver
+    {
+
+public:
+
+    /**
+    * Callback when the CreateMediaL() is completed.
+    * @param aMedia media with metadata populated. Ownership transferred.
+    * @param aError error
+    */
+    virtual void HandleCreateMediaComplete( CMPXMedia* aMedia, TInt aError ) = 0;
+    };
+
+#endif // MMPXMETADATAEXTRACTOROBSERVER_H
--- a/mpx/collectionframework/collectionengine/src/mpxcollectionengine.cpp	Fri Apr 23 13:55:04 2010 +0100
+++ b/mpx/collectionframework/collectionengine/src/mpxcollectionengine.cpp	Wed Apr 28 22:20:05 2010 +0100
@@ -194,6 +194,9 @@
     TInt command = KErrNotSupported;
     TInt data = 0;
     TBool clearCache ( EFalse );
+    TBool notify( ETrue );
+    TInt count = iContexts.Count();
+    CMPXCollectionClientContext* context( NULL );
     switch( aMsg )
         {
         case EMcMsgFormatStart:
@@ -207,8 +210,14 @@
             clearCache = ETrue;
             break;
             }
+        case EMcMsgDiskInserted:        	
+            for( TInt i=0; i<count; ++i )
+                {
+                context = iContexts[i];
+                context->NotifyL( aMsg, aData );
+                }
+            notify = EFalse;
         case EMcMsgFormatEnd:
-        case EMcMsgDiskInserted:
         case EMcMsgUSBMassStorageEnd:
             {
             command = EMcReOpenCollection;
@@ -281,15 +290,15 @@
         rfs.Close();
     	}
     
-    TInt count = iContexts.Count();
-    for( TInt i=0; i<count; ++i )
-        {
-        CMPXCollectionClientContext* context;
-        context = iContexts[i];
-        context->NotifyL( aMsg, aData );
-        }
+    if ( notify )
+    	{
+		for( TInt i=0; i<count; ++i )
+			{
+			context = iContexts[i];
+			context->NotifyL( aMsg, aData );
+			}
+    	}
     }
-
 void CMPXCollectionEngine::Command( TMPXCollectionCommand aCmd, TInt aData )
     {
     TArray<CMPXCollectionPlugin*> plugins = iPluginHandler->LoadedPlugins();
--- a/mpx/playbackframework/playbackengine/src/mpxplaybackengine.cpp	Fri Apr 23 13:55:04 2010 +0100
+++ b/mpx/playbackframework/playbackengine/src/mpxplaybackengine.cpp	Wed Apr 28 22:20:05 2010 +0100
@@ -1478,6 +1478,23 @@
             {
             iProperties[EPbPropertyPosition] = 0;
             }
+	
+	//check whether plugin is KMPXPlaybackPluginVersion2, if not, set saved position
+    CDesCArray* interfaces = iPluginHandler->SupportedInterfacesL( iPluginUid );
+    TBool version2InterfaceSupported = EFalse;
+    if ( interfaces->MdcaCount() )
+        {
+        TInt pos(0);            
+        version2InterfaceSupported = !interfaces->FindIsq( KMPXPlaybackPluginVersion2, pos );
+        }
+    delete interfaces;
+    
+    if ( !version2InterfaceSupported )
+        {
+        // Set position to restore saved position.
+        TRAP_IGNORE( // uPnP leaves if set position in stop state
+                PluginL()->SetL( EPbPropertyPosition, iProperties[EPbPropertyPosition] ));
+        }
 
     iAutoResumeHandler->HandleOpenFileComplete();
     
@@ -2620,7 +2637,7 @@
     MPX_DEBUG1("==>CMPXPlaybackEngine::DoStopL()");
     Suspend();
     if (iState == EPbStatePaused || iState == EPbStatePlaying ||
-        iState == EPbStateInitialising)
+        iState == EPbStateInitialising || iState == EPbStateBuffering)
         {
         if (aSavePlaybackInfo && (iState == EPbStatePaused || iState == EPbStatePlaying ))
             {
--- a/mpx/playbackframework/playbackserver/src/mpxplaybackserver.cpp	Fri Apr 23 13:55:04 2010 +0100
+++ b/mpx/playbackframework/playbackserver/src/mpxplaybackserver.cpp	Wed Apr 28 22:20:05 2010 +0100
@@ -196,8 +196,16 @@
             if (cl->ClientCount()==0)
                 {
                 MPX_DEBUG1("CMPXPlaybackServer::RemoveClient delete a player");
+                CMPXPlaybackEngine* enginePtr = p; 
                 delete p;
-                iPlayers.Remove(i);
+				//Due to callbacks in PlaybackServer we have to remove engine from the iPlayers array after deleting.
+                //enginePtr is a invalid pointer as p is already deleted
+    		    //Find the index of deleted engine using its address
+				TInt engineIndex = iPlayers.Find(enginePtr);
+                if ( engineIndex != KErrNotFound )
+                    {
+                    iPlayers.Remove(engineIndex);
+                    }
                 }
             break;
             }