imagehandlingutilities/thumbnailmanager/thumbagdaemon/src/thumbagprocessor.cpp
branchRCL_3
changeset 37 f759b6186ab5
parent 28 ff2fb7658ff7
child 38 2b4b06654caa
--- a/imagehandlingutilities/thumbnailmanager/thumbagdaemon/src/thumbagprocessor.cpp	Mon Jun 21 16:00:46 2010 +0300
+++ b/imagehandlingutilities/thumbnailmanager/thumbagdaemon/src/thumbagprocessor.cpp	Thu Jul 15 18:59:26 2010 +0300
@@ -50,7 +50,8 @@
 // CThumbAGProcessor::CThumbAGProcessor()
 // ---------------------------------------------------------------------------
 //
-CThumbAGProcessor::CThumbAGProcessor(): CActive( CActive::EPriorityStandard )
+CThumbAGProcessor::CThumbAGProcessor(): CActive( CActive::EPriorityStandard ), iMMCHarvestingItemsLeftTemp(0), 
+        iPHHarvestingItemsLeftTemp(0)
     {
     TN_DEBUG1( "CThumbAGProcessor::CThumbAGProcessor() - begin" );
     
@@ -82,10 +83,11 @@
     // set auto create values from cenrep
     CheckAutoCreateValuesL();
     
-    iPeriodicTimer = CPeriodic::NewL(CActive::EPriorityIdle);
+    iPeriodicTimer = CPeriodic::NewL(CActive::EPriorityStandard);
+    
+    iMountTimer = CPeriodic::NewL(CActive::EPriorityUserInput);
     
     SetForceRun( EFalse );    
-    iActive = EFalse;
     
     iFormatObserver = CTMFormatObserver::NewL( *this );
        
@@ -96,7 +98,7 @@
     
     iActivityManager = CTMActivityManager::NewL( this, KBackgroundGenerationIdle);
 
-    UpdatePSValues(ETrue);
+    UpdatePSValues(ETrue, ETrue);
     
     RProperty::Define(KTAGDPSNotification, KMPXHarvesting, RProperty::EInt);
     
@@ -118,6 +120,20 @@
     
     Cancel();
     
+    if (iTMSession)
+        {
+        iTMSession->RemoveRequestObserver();
+        delete iTMSession;
+        iTMSession = NULL;
+        }
+    
+    if(iMountTimer)
+        {
+        iMountTimer->Cancel();
+        delete iMountTimer;
+        iMountTimer = NULL;
+        }
+    
     if(iPeriodicTimer)
         {
         iPeriodicTimer->Cancel();
@@ -177,21 +193,17 @@
         iCollectionUtility->Close();
         iCollectionUtility = NULL;
         }
-
-    iAddQueue.Close();
-    iModifyQueue.Close();
-    iRemoveQueue.ResetAndDestroy();
+    
+    for(TInt i=0;i<iGenerationQueue.Count();i++)
+        {
+        delete iGenerationQueue[i].iUri;
+        iGenerationQueue[i].iUri = NULL;
+        }
+    
+    iGenerationQueue.Reset();
+    iGenerationQueue.Close();
+    
     iQueryQueue.Close();
-    iPlaceholderQueue.Close();
-	  
-    i2ndRoundGenerateQueue.Close();
-    
-    if (iTMSession)
-        {
-        iTMSession->RemoveRequestObserver();
-        delete iTMSession;
-        iTMSession = NULL;
-        }
     
     TN_DEBUG1( "CThumbAGProcessor::~CThumbAGProcessor() - end" );
     }
@@ -204,7 +216,7 @@
     {
     TN_DEBUG1( "CThumbAGProcessor::Shutdown()" );
     iShutdown = ETrue;
-    UpdatePSValues();
+    UpdatePSValues(EFalse, EFalse);
     }
 
 // -----------------------------------------------------------------------------
@@ -244,13 +256,19 @@
                     }
                
                 // ignore if fails
-                iPlaceholderQueue.InsertInOrder(object->Id(), Compare);               
+                TThumbnailGenerationItem item;
+                item.iItemId = object->Id();
+                item.iPlaceholder = ETrue;
+                
+                SetGenerationItemType( item, object->Def().Id());
+                
+                AppendProcessingQueue( item );
                 }  
             }
         else if(&aQuery == iQueryAllItems)
             {
             TN_DEBUG2( "CThumbAGProcessor::HandleQueryNewResults - QueryAllItems, %d new", aNewItemCount);
-    
+            
             for(TInt i = aFirstNewItemIndex; i < iQueryAllItems->Count(); i++)
                 {    
                 const CMdEObject* object = &iQueryAllItems->Result(i);
@@ -259,13 +277,17 @@
                     {
                     continue;
                     }
-               
-                if (iAddQueue.FindInOrder(object->Id(), Compare) == KErrNotFound && 
-                    iModifyQueue.FindInOrder(object->Id(), Compare) == KErrNotFound )
-                    {
-                    // ignore if fails
-                    iAddQueue.InsertInOrder(object->Id(), Compare);
-                    }
+
+                TThumbnailGenerationItem item;
+                item.iItemId = object->Id();
+                
+                SetGenerationItemType(item, object->Def().Id());
+                
+                TInt itemIndex = iGenerationQueue.FindInOrder(item, Compare);
+                
+                item.iPlaceholder = object->Placeholder(); 
+                
+                AppendProcessingQueue( item );
                 }
             }    
         }
@@ -292,8 +314,6 @@
         {
         TN_DEBUG1( "CThumbAGProcessor::HandleQueryCompleted - iQueryPlaceholders completed");
         
-        iPlaceholderQueue.Reset();
-        
         //free query
         delete iQueryPlaceholders;
         iQueryPlaceholders = NULL;
@@ -331,60 +351,123 @@
             {
             iProcessingCount = iQuery->Count();
 			
-            if(iProcessingCount != iQueryQueue.Count())
+            if(iProcessingCount != iQueryQueue.Count() )
                 {
                 TN_DEBUG1( "CThumbAGProcessor::HandleQueryCompleted() some result items missing");
                 
                 RArray<TItemId> queryQueueDelta;
                 
-                TInt itemIndex(KErrNotFound);
-                
-                //search delta items which were queried, but not found
-                 for(TInt queryItem =0; queryItem < iQueryQueue.Count();queryItem++)
-                     {
-                     TBool found(EFalse);
-                     for(TInt queryResult = 0; queryResult < iQuery->Count(); queryResult++)
-                        {    
-                        const CMdEObject* object = &iQuery->Result(queryResult);
-                        
-                        if( iQueryQueue[queryItem] == object->Id())
+                    //search delta items which were queried, but not found
+                     for(TInt queryItem =0; queryItem < iQueryQueue.Count();queryItem++)
+                         {
+                         TBool found(EFalse);
+                         for(TInt queryResult = 0; queryResult < iQuery->Count(); queryResult++)
+                            {    
+                            const CMdEObject* object = &iQuery->Result(queryResult);
+                            
+                            if( iQueryQueue[queryItem] == object->Id())
+                                {
+                                found = ETrue;
+                                break;
+                                }
+                            }
+                             
+                         if(!found)
+                             {
+                             TN_DEBUG2( "CThumbAGProcessor::HandleQueryCompleted() %d missing from query results", iQueryQueue[queryItem] );
+                             
+                             // ignore if fails
+                             queryQueueDelta.InsertInOrder(iQueryQueue[queryItem], CompareId);
+                             }
+                         }
+                     
+                     TN_DEBUG2( "CThumbAGProcessor::HandleQueryCompleted() missing items found %d", queryQueueDelta.Count()); 
+                     //cleanup from previous queue it item is not found from MDS
+                     while(queryQueueDelta.Count())
+                         {
+                         TThumbnailGenerationItem item;
+                         item.iItemId = queryQueueDelta[0];
+                         TInt itemIndex = iQueryQueue.FindInOrder(item.iItemId, CompareId);
+                         
+                         if(itemIndex >= 0)
+                             {
+                             TN_DEBUG2( "CThumbAGProcessor::HandleQueryCompleted() remove %d from iQueryQueue", queryQueueDelta[0]);
+                             iQueryQueue.Remove( itemIndex );
+                             
+                             //remove from procesing queue
+                             itemIndex = iGenerationQueue.FindInOrder(item, Compare);
+                             
+                             if(itemIndex >= 0)
+                                 {
+                                 
+                                 if( iUnknown )
+                                     {
+                                     TN_DEBUG2( "CThumbAGProcessor::HandleQueryCompleted() mark %d as EGenerationItemTypeNotFound in iGenerationQueue", queryQueueDelta[0]);
+                                     //mark to be removed, cleanup is done below
+                                     iGenerationQueue[itemIndex].iItemType = EGenerationItemTypeNotFound;
+                                     }
+                                 else
+                                     {
+                                     TN_DEBUG2( "CThumbAGProcessor::HandleQueryCompleted() remove %d from iGenerationQueue", queryQueueDelta[0]);
+                                     iGenerationQueue.Remove( itemIndex );
+                                     }
+                                 }
+                             }
+                         queryQueueDelta.Remove(0);
+                         }
+                     queryQueueDelta.Close();
+                    }
+
+                if(iUnknown)
+                    {
+                    for(TInt i = 0; i < iQuery->Count(); i++)
+                      {    
+                      const CMdEObject* object = &iQuery->Result(i);
+                     
+                      if(!object)
+                          {
+                          continue;
+                          }
+
+                          TThumbnailGenerationItem tempItem;
+                          tempItem.iItemId = object->Id();
+                          TInt itemIndex = iGenerationQueue.FindInOrder(tempItem, Compare);
+                                           
+                        if(itemIndex >= 0)
                             {
-                            found = ETrue;
-                            break;
+                            TThumbnailGenerationItem& item = iGenerationQueue[itemIndex]; 
+                            
+                            if(iGenerationQueue[itemIndex].iItemType == EGenerationItemTypeNotFound)
+                                {
+                                TN_DEBUG2( "CThumbAGProcessor::HandleQueryCompleted() remove EGenerationItemTypeNotFound %d item from iGenerationQueue", item.iItemId);
+                                iGenerationQueue.Remove(itemIndex);
+                                continue;
+                                }
+                            
+                                SetGenerationItemType(item, object->Def().Id());
+                                    
+                                if(item.iItemType == EGenerationItemTypeUnknown )
+                                  {
+                                  TN_DEBUG2( "CThumbAGProcessor::HandleQueryCompleted() remove unknown item %d", item.iItemId);
+                                  iGenerationQueue.Remove(itemIndex);
+                                  continue;
+                                  }
+                              
+                              item.iPlaceholder = object->Placeholder(); 
+                                      
                             }
                         }
-                         
-                     if(!found)
-                         {
-                         TN_DEBUG2( "CThumbAGProcessor::HandleQueryCompleted() missing from results item %d", iQueryQueue[queryItem] );
-                         
-                         // ignore if fails
-                         queryQueueDelta.InsertInOrder(iQueryQueue[queryItem], Compare);
-                         }
-                     }
-                 
-                 TN_DEBUG2( "CThumbAGProcessor::HandleQueryCompleted() missing items total count %d", queryQueueDelta.Count()); 
-                 //cleanup from previous queue it item is not found from MDS
-                 while(queryQueueDelta.Count())
-                     {
-                     itemIndex = iLastQueue->FindInOrder(queryQueueDelta[0], Compare);
-                     
-                     if(itemIndex >= 0)
-                         {
-                         TN_DEBUG2( "CThumbAGProcessor::HandleQueryCompleted() remove items %d", iQueryQueue[0]);
-                         iLastQueue->Remove( itemIndex );
-                         }
-                     queryQueueDelta.Remove(0);
-                     }
-                 queryQueueDelta.Close();
-                }
+                
+                        iQueryQueue.Reset();
+                        iProcessingCount = 0;
+                        iUnknown = EFalse;
+                    }
             
             // no results, reset query
-            if( !iProcessingCount)
+            if( !iProcessingCount )
                 {
                 delete iQuery;
                 iQuery = NULL;
-                iProcessingCount = 0;
                 iModify = EFalse;
                 }
             }
@@ -416,7 +499,7 @@
     }
 
 // -----------------------------------------------------------------------------
-// CThumbAGProcessor::ThumbnailReady()
+// CThumbAGProcessor::ThumbnailReady()d
 // -----------------------------------------------------------------------------
 //
 void CThumbAGProcessor::ThumbnailReady( TInt aError, MThumbnailData& /*aThumbnail*/,
@@ -426,12 +509,6 @@
     
     iActiveCount--;
     
-    if(iActiveCount <= 0)
-        {
-        iActiveCount = 0;
-        iActive = EFalse;
-        }
-    
     // TNM server died, delete session
     if( aError == KErrServerTerminated )
         {
@@ -469,12 +546,6 @@
     
         iActiveCount--;
         
-        if(iActiveCount <= 0)
-            {
-            iActiveCount = 0;
-            iActive = EFalse;
-            }
-    
         ActivateAO();
         }
     }
@@ -483,7 +554,7 @@
 // CThumbAGProcessor::SetMdESession()
 // ---------------------------------------------------------------------------
 //
-void CThumbAGProcessor::SetMdESession( CMdESession* aMdESession )
+void CThumbAGProcessor::SetMdESessionL( CMdESession* aMdESession )
     {
     TN_DEBUG1( "CThumbAGProcessor::SetMdESession() - begin" );
     
@@ -495,14 +566,22 @@
     if (err != KErrNone)
         {
         TN_DEBUG2( "CThumbAGProcessor::SetMdESession() GetDefaultNamespaceDefL() err = %d", err );
+        __ASSERT_DEBUG((iDefNamespace), User::Panic(_L("CThumbAGProcessor::SetMdESession() !iDefNamespace "), KErrBadHandle));
         }
-    
-    __ASSERT_DEBUG((iDefNamespace), User::Panic(_L("CThumbAGProcessor::SetMdESession() !iDefNamespace "), KErrBadHandle));
-       
-    //do async init
-    iInit = ETrue;
-    
-	ActivateAO();
+    else
+        {
+        iImageObjectDef = &iDefNamespace->GetObjectDefL( MdeConstants::Image::KImageObject );
+        __ASSERT_DEBUG((iImageObjectDef), User::Panic(_L("CThumbAGProcessor::SetMdESession() !iDefNamespace "), KErrBadHandle));
+        iVideoObjectDef = &iDefNamespace->GetObjectDefL( MdeConstants::Video::KVideoObject );
+        __ASSERT_DEBUG((iVideoObjectDef), User::Panic(_L("CThumbAGProcessor::SetMdESession() !iVideoObjectDef "), KErrBadHandle));
+        iAudioObjectDef = &iDefNamespace->GetObjectDefL( MdeConstants::Audio::KAudioObject );
+        __ASSERT_DEBUG((iAudioObjectDef), User::Panic(_L("CThumbAGProcessor::SetMdESession() !iAudioObjectDef "), KErrBadHandle));
+        
+        //do async init
+        iInit = ETrue;
+
+        ActivateAO();
+        }
     }
 
 // ---------------------------------------------------------------------------
@@ -510,11 +589,13 @@
 // ---------------------------------------------------------------------------
 //
 void CThumbAGProcessor::AddToQueueL( TObserverNotificationType aType, 
+                                    TThumbnailGenerationItemType aItemType,
                                     const RArray<TItemId>& aIDArray, 
                                     const RPointerArray<HBufC>& aObjectUriArray,
                                     TBool /*aPresent*/ )
     {
     TN_DEBUG1( "CThumbAGProcessor::AddToQueueL() - begin" );
+    
 
     // update queues
     if (aType == ENotifyAdd)
@@ -523,12 +604,18 @@
         
         for (int i=0; i<aIDArray.Count(); i++)
             {
-            // do not to append to Add queue if exist already in Add or 2nd Add queue (just processed)     
-            if (iAddQueue.FindInOrder(aIDArray[i], Compare) == KErrNotFound && 
-                i2ndRoundGenerateQueue.FindInOrder(aIDArray[i], Compare) == KErrNotFound)
+            TThumbnailGenerationItem item;
+            item.iItemId = aIDArray[i];      
+            item.iItemType = aItemType;
+            
+            SetGenerationItemAction(item, aItemType);
+            
+            if(iPHHarvesting)
                 {
-                User::LeaveIfError(iAddQueue.InsertInOrder(aIDArray[i], Compare));    
+                item.iPlaceholder = ETrue;
                 }
+
+            AppendProcessingQueue( item );
             }
         }
     else if (aType == ENotifyModify)
@@ -540,19 +627,24 @@
             TN_DEBUG1( "CThumbAGProcessor::AddToQueueL() - PH  harvesting active, treat like add" );
             for (int i=0; i<aIDArray.Count(); i++)
                 {
-                TInt itemIndex = iPlaceholderQueue.FindInOrder(aIDArray[i], Compare);
+                TThumbnailGenerationItem item;
+                item.iItemId = aIDArray[i];
+                item.iItemType = aItemType;
+                
+                TInt itemIndex = iGenerationQueue.FindInOrder(item, Compare);
                                 
                 if (itemIndex >= 0)
                     {
-                    TN_DEBUG1( "CThumbAGProcessor::AddToQueueL() - remove from placeholder queue");
-                    iPlaceholderQueue.Remove( itemIndex );
+                    TN_DEBUG1( "CThumbAGProcessor::AddToQueueL() - set as non-placeholder");
+                    iGenerationQueue[itemIndex].iPlaceholder = EFalse;
                     }
-                
-                if(iAddQueue.FindInOrder(aIDArray[i], Compare) == KErrNotFound && 
-                   i2ndRoundGenerateQueue.FindInOrder(aIDArray[i], Compare) == KErrNotFound)
+                else
                     {
-                    TN_DEBUG1( "CThumbAGProcessor::AddToQueueL() - append to add queue");
-                    User::LeaveIfError(iAddQueue.InsertInOrder(aIDArray[i], Compare));
+                    TN_DEBUG1( "CThumbAGProcessor::AddToQueueL() - append");
+
+                     item.iPlaceholder = EFalse;
+                     SetGenerationItemAction( item, aItemType );
+                     AppendProcessingQueue( item );
                     }
                 }
             }
@@ -564,75 +656,91 @@
             
             for (int i=0; i<aIDArray.Count(); i++)
                 {
-                itemIndex = iPlaceholderQueue.FindInOrder(aIDArray[i], Compare);
+                TThumbnailGenerationItem item;
+                item.iItemId = aIDArray[i];
+                item.iItemType = aItemType;
+                
+                itemIndex = iGenerationQueue.FindInOrder(item, Compare);
                 
                 if (itemIndex >= 0)
                     {
-                    TN_DEBUG1( "CThumbAGProcessor::AddToQueueL() - placeholder modify, remove from placeholder queue");
-                    iPlaceholderQueue.Remove( itemIndex );
+                    if( iGenerationQueue[itemIndex].iPlaceholder )
+                        {
+                        TN_DEBUG1( "CThumbAGProcessor::AddToQueueL() - placeholder modify");
+                        iGenerationQueue[itemIndex].iPlaceholder = EFalse;
+                        }
+                    else
+                        {
+                        TN_DEBUG1( "CThumbAGProcessor::AddToQueueL() - real modify");
+                        iGenerationQueue[itemIndex].iItemAction = EGenerationItemActionModify;
+                        SetForceRun( ETrue );
+                        }
                     }
                 else
                     {
-                    TN_DEBUG1( "CThumbAGProcessor::AddToQueueL() - real modify");
-                    itemIndex = iAddQueue.FindInOrder(aIDArray[i], Compare);
-                                    
-                    if (itemIndex >= 0)
-                        {
-                        TN_DEBUG1( "CThumbAGProcessor::AddToQueueL() - remove from add queue");
-                        iAddQueue.Remove( itemIndex );
-                        }
-					else
-						{						
-						itemIndex = i2ndRoundGenerateQueue.FindInOrder(aIDArray[i], Compare);
-                                    
-	                    if (itemIndex >= 0)
-	                        {
-	                        TN_DEBUG1( "CThumbAGProcessor::AddToQueueL() - remove from 2nd round add queue");
-	                        i2ndRoundGenerateQueue.Remove( itemIndex );
-	                        }
-					}
-                    
-                    TN_DEBUG1( "CThumbAGProcessor::AddToQueueL() - append to modify queue");
-                    User::LeaveIfError(iModifyQueue.InsertInOrder(aIDArray[i], Compare));
-                    
-                    SetForceRun( ETrue );
-                    } 
+                    TN_DEBUG1( "CThumbAGProcessor::AddToQueueL() - append");
+                    SetGenerationItemAction( item, aItemType);
+                    item.iPlaceholder = EFalse;
+                    AppendProcessingQueue( item );
+                    }
                 }
             }
         }
-        else if (aType == ENotifyRemove)
+        else if (aType == ENotifyRemove && aItemType == EGenerationItemTypeAny)
             {
             TN_DEBUG1( "CThumbAGProcessor::AddToQueueL() - ENotifyRemove, remove IDs from all queues");
             
             for (int i=0; i<aIDArray.Count(); i++)
                 {
-                // can be removed from Add queue
-                TInt itemIndex = iAddQueue.FindInOrder(aIDArray[i], Compare);
-                if(itemIndex >= 0)
-                    {
-                    iAddQueue.Remove(itemIndex);
-                    }
-    
-                // ..and Modify Queue
-                itemIndex = iModifyQueue.FindInOrder(aIDArray[i], Compare);
+                TThumbnailGenerationItem item;
+                item.iItemId = aIDArray[i];
+                item.iItemType = aItemType;
+
+                TInt itemIndex = iGenerationQueue.FindInOrder(item, Compare);
+                
                 if(itemIndex >= 0)
                     {
-                    iModifyQueue.Remove(itemIndex);
+                    iGenerationQueue[itemIndex].iItemAction = EGenerationItemActionDelete;
+                    delete iGenerationQueue[itemIndex].iUri;
+                    iGenerationQueue[itemIndex].iUri = NULL;
+                    
+                    if( aObjectUriArray[i])
+                        {
+                        iGenerationQueue[itemIndex].iUri = aObjectUriArray[i]->AllocL();
+                        }
+                    else
+                        {
+                        //invalid URI remove from processing queue
+                        iGenerationQueue.Remove(itemIndex);
+                        }
                     }
-                }
-            
-            TN_DEBUG1( "CThumbAGProcessor::AddToQueueL() - ENotifyRemove append URIs to remove queue");
-            for (int i=0; i<aObjectUriArray.Count(); i++)
-                {
-                HBufC* temp = aObjectUriArray[i]->AllocL();
-                iRemoveQueue.Append( temp );
-                TN_DEBUG2( "CThumbAGProcessor::AddToQueueL() - %S", temp); 
+                else
+                    {
+                    TN_DEBUG1( "CThumbAGProcessor::AddToQueueL() - append");
+                    item.iItemAction = EGenerationItemActionDelete;
+                    delete item.iUri;
+                    item.iUri = NULL;
+                    
+                    if( aObjectUriArray[i])
+                        {
+                        item.iUri = aObjectUriArray[i]->AllocL();
+                        CleanupStack::PushL( item.iUri );
+                        User::LeaveIfError( iGenerationQueue.InsertInOrder(item, Compare) );
+                        CleanupStack::Pop();
+                        }
+                    
+                    //owned by item
+                    item.iUri = NULL;
+                    }
+                
+                TN_DEBUG2( "CThumbAGProcessor::AddToQueueL() - %S", aObjectUriArray[i]); 
                 }
             }
 #ifdef _DEBUG
         else
             {
 	        TN_DEBUG1( "CThumbAGProcessor::AddToQueueL() -  should not come here" );
+	        __ASSERT_DEBUG((EFalse), User::Panic(_L("CThumbAGProcessor::AddToQueueL()"), KErrArgument));
 	        User::Leave( KErrArgument );
             }
 #endif
@@ -662,8 +770,8 @@
     TInt64 modifiedVal = 0;
     
     CMdEProperty* orientation = NULL;
-    CMdEObjectDef& imageObjectDef = iDefNamespace->GetObjectDefL( MdeConstants::Image::KImageObject );       
-    TInt orientErr = aObject->Property( imageObjectDef.GetPropertyDefL( MdeConstants::Image::KOrientationProperty ), orientation, 0 );
+       
+    TInt orientErr = aObject->Property( iImageObjectDef->GetPropertyDefL( MdeConstants::Image::KOrientationProperty ), orientation, 0 );
     
     if (orientErr == KErrNone)
         {
@@ -688,6 +796,20 @@
             //generate both if needed
             TN_DEBUG1( "CThumbAGProcessor::CreateThumbnailsL() EOptimizeForQuality ");
             iTMSession->SetQualityPreferenceL( CThumbnailManager::EOptimizeForQuality );
+            
+            TN_DEBUG2( "CThumbAGProcessor::CreateThumbnailsL() - 2nd round add remove from queue", aObject->Id() );
+                        
+            TThumbnailGenerationItem item;
+            item.iItemId = aObject->Id();
+            TInt itemIndex = iGenerationQueue.FindInOrder(item, Compare);
+            
+            if(itemIndex >=0 )
+                {
+                if(iGenerationQueue[itemIndex].iItemAction == EGenerationItemAction2ndAdd)
+                    {
+                    iGenerationQueue.Remove(itemIndex);
+                    }
+                }
             }
 		// 1st roung generation
         else
@@ -696,35 +818,29 @@
             TN_DEBUG1( "CThumbAGProcessor::CreateThumbnailsL() EOptimizeForQualityWithPreview");
             iTMSession->SetQualityPreferenceL( CThumbnailManager::EOptimizeForQualityWithPreview );
             
-            CMdEObjectDef& videoObjectDef = iDefNamespace->GetObjectDefL( MdeConstants::Video::KVideoObject );
+            // add item to 2nd round queue 
+            TN_DEBUG2( "CThumbAGProcessor::CreateThumbnailsL() - 1st round add/modify, append to 2nd round queue", aObject->Id() );
             
-            // add item to 2nd round queue 
-            if(iLastQueue == &iAddQueue || iLastQueue == &iModifyQueue)
-                {
-                TN_DEBUG2( "CThumbAGProcessor::CreateThumbnailsL() - 1st round add/modify, append to 2nd round queue", aObject->Id() );
-                if(i2ndRoundGenerateQueue.FindInOrder(aObject->Id(), Compare) == KErrNotFound)
-                    {
-                    // ignore if fails
-                    i2ndRoundGenerateQueue.InsertInOrder(aObject->Id(), Compare);
-                    }
-                }
+            TThumbnailGenerationItem item;
+            item.iItemId = aObject->Id();
+            TInt itemIndex = iGenerationQueue.FindInOrder(item, Compare);
             
-            /*CMdEProperty* inDefaultFolder = NULL;
-            TBool inDefaultFolderVal(ETrue);
-            TInt inDefaultFolderErr = aObject->Property( baseObjDef.GetPropertyDefL( MdeConstants::Object::KInDefaultFolder ), inDefaultFolder, 0 );
-            
-            if(inDefaultFolder &&  inDefaultFolderErr >= 0 )
+            if(itemIndex >=0 )
                 {
-                inDefaultFolderVal = inDefaultFolder->BoolValueL();
-                }*/
-            
-		   // Symbian^3 specific
-           if( !(( imageObjectDef.Id() == aObject->Def().Id() || videoObjectDef.Id() == aObject->Def().Id()) 
-                   /*&& inDefaultFolderVal*/ ) )
-                {
-                TN_DEBUG1( "CThumbAGProcessor::CreateThumbnailsL() 1st round; not image or video in default folder, skip");
-                ActivateAO();
-                return;
+                if(iGenerationQueue[itemIndex].iItemAction == EGenerationItemActionModify)
+                    {
+                    iGenerationQueue.Remove(itemIndex);
+                    }
+                //change 1st round item for 2nd round processing
+                //2nd round item can be deleted
+                else if(iGenerationQueue[itemIndex].iItemAction == EGenerationItemActionAdd)
+                    {
+                    iGenerationQueue[itemIndex].iItemAction = EGenerationItemAction2ndAdd;
+                    }
+                else
+                    {
+                    iGenerationQueue.Remove(itemIndex);
+                    }
                 }
             }
 
@@ -736,13 +852,11 @@
             TN_DEBUG2( "CThumbAGProcessor::CreateThumbnailsL, iTMSession error == %d", err );
             
             iSessionDied = ETrue;
-            iActive = EFalse;
             ActivateAO();
             } 
         else
             {
             iActiveCount++;
-            iActive = ETrue;
             }
         }
     else
@@ -757,7 +871,7 @@
 // CThumbAGProcessor::QueryL()
 // ---------------------------------------------------------------------------
 //
-void CThumbAGProcessor::QueryL( RArray<TItemId>& aIDArray )
+void CThumbAGProcessor::QueryL(/*RArray<TItemId>& aIDArray*/TThumbnailGenerationItemAction aAction  )
     {
     TN_DEBUG1( "CThumbAGProcessor::QueryL() - begin" );
     
@@ -772,7 +886,6 @@
 	//reset query queue
     iQueryQueue.Reset();
 	//set reference to current pprocessing queue
-    iLastQueue = &aIDArray;
     
     iQueryReady = EFalse;
 
@@ -784,18 +897,64 @@
         }
     
     //move ID from source queue to Query queue
-    TInt maxCount = aIDArray.Count();
+    TInt maxCount = iGenerationQueue.Count();
         
-    TN_DEBUG3( "CThumbAGProcessor::QueryL() - fill begin aIDArray == %d, iQueryQueue == %d", aIDArray.Count(), iQueryQueue.Count() );
+    TN_DEBUG3( "CThumbAGProcessor::QueryL() - fill begin iGenerationQueue == %d, iQueryQueue == %d", iGenerationQueue.Count(), iQueryQueue.Count() );
+    
     
-    for(TInt i=0; i < KMaxQueryItems && i < maxCount; i++)
+    TInt itemCount(0);
+    for(TInt i=0; itemCount < KMaxQueryItems && i < maxCount; i++)
         {
-        TN_DEBUG2( "CThumbAGProcessor::QueryL() - fill %d", aIDArray[0] );
-        iQueryQueue.InsertInOrder(aIDArray[0], Compare);
-        aIDArray.Remove(0);
+        TInt itemIndex(KErrNotFound);
+        switch(aAction)
+            {
+            //1st round items
+            case EGenerationItemActionAdd:
+                if(iGenerationQueue[i].iItemAction == aAction )
+                    {
+                    itemIndex = i;
+                    }
+                break;
+            case EGenerationItemActionModify:
+                if( iGenerationQueue[i].iItemAction == aAction )
+                    {
+                    itemIndex = i;
+                    }
+                break;
+            case EGenerationItemAction2ndAdd:
+                if( iGenerationQueue[i].iItemAction == aAction )
+                    {
+                    itemIndex = i;
+                    }
+                break;
+            //unknown stuff
+            case EGenerationItemActionResolveType:
+                if( iGenerationQueue[i].iItemType == EGenerationItemTypeUnknown )
+                    {
+                    itemIndex = i;
+                    }
+                break;
+            default:
+                break;
+            };
+        
+        if( itemIndex >= 0 )
+            {
+            TN_DEBUG2( "CThumbAGProcessor::QueryL() - fill %d", iGenerationQueue[itemIndex].iItemId );        
+            iQueryQueue.InsertInOrder(iGenerationQueue[itemIndex].iItemId, CompareId);
+            itemCount++;
+            }
         }
     
-    TN_DEBUG3( "CThumbAGProcessor::QueryL() - fill end aIDArray == %d, iQueryQueue == %d", aIDArray.Count(), iQueryQueue.Count() );
+    if(!itemCount)
+        {
+        TN_DEBUG1( "CThumbAGProcessor::QueryL() - empty query, cancel?!");
+        iQueryActive = EFalse;
+        __ASSERT_DEBUG((iMdESession), User::Panic(_L("CThumbAGProcessor::QueryL() empty! "), KErrNotFound));
+        return;
+        }
+    
+    TN_DEBUG3( "CThumbAGProcessor::QueryL() - fill end iGenerationQueue == %d, iQueryQueue == %d", iGenerationQueue.Count(), iQueryQueue.Count() );
     
     CMdEObjectDef& objDef = iDefNamespace->GetObjectDefL( MdeConstants::Object::KBaseObject );
     iQuery = iMdESession->NewObjectQueryL( *iDefNamespace, objDef, this );
@@ -810,7 +969,7 @@
     CleanupStack::Pop( &iQueryQueue );
     
     // add object type conditions 
-    if (!iModify)
+    if (!(iModify || iUnknown))
         {
         CMdELogicCondition& objDefCondition = rootCondition.AddLogicConditionL( ELogicConditionOperatorOr );
         
@@ -842,7 +1001,7 @@
 // ---------------------------------------------------------------------------
 //
 
-void CThumbAGProcessor::QueryPlaceholdersL()
+void CThumbAGProcessor::QueryPlaceholdersL(TBool aPresent)
     {
     TN_DEBUG1( "CThumbAGProcessor::QueryPlaceholdersL" );
     
@@ -884,17 +1043,17 @@
     
     CMdEObjectCondition& imagePHObjectCondition = rootCondition.AddObjectConditionL(imageObjDef);
     imagePHObjectCondition.SetPlaceholderOnly( ETrue );
-    imagePHObjectCondition.SetNotPresent( ETrue );
+    imagePHObjectCondition.SetNotPresent( aPresent );
     
     CMdEObjectCondition& videoPHObjectCondition = rootCondition.AddObjectConditionL(videoObjDef);
     videoPHObjectCondition.SetPlaceholderOnly( ETrue );
-    videoPHObjectCondition.SetNotPresent( ETrue );
+    videoPHObjectCondition.SetNotPresent( aPresent );
     
     CMdEObjectCondition& audioPHObjectCondition = rootCondition.AddObjectConditionL(audioObjDef);
     audioPHObjectCondition.SetPlaceholderOnly( ETrue );
-    audioPHObjectCondition.SetNotPresent( ETrue );
+    audioPHObjectCondition.SetNotPresent( aPresent );
     
-    iQueryPlaceholders->FindL(KMaxTInt, KMaxQueryItems2);   
+    iQueryPlaceholders->FindL(KMaxTInt, KMaxQueryBatchSize);   
    
     TN_DEBUG1( "CThumbAGProcessor::QueryPlaceholdersL - end" );
     }
@@ -928,13 +1087,11 @@
         iInit = EFalse;
         iInit2 = ETrue;
 
-        iAddQueue.Reset();
-        iModifyQueue.Reset();
-        iRemoveQueue.ResetAndDestroy();
+        iGenerationQueue.Reset();
         iQueryQueue.Reset();
-        iPlaceholderQueue.Reset();
         
-        TRAP_IGNORE(QueryPlaceholdersL());
+		//query all not present placeholders
+        TRAP_IGNORE(QueryPlaceholdersL( ETrue ));
 		//query all items after PH query
         iDoQueryAllItems = ETrue;
         TN_DEBUG1( "CThumbAGProcessor::RunL() - Initialisation 1 done" );
@@ -954,13 +1111,20 @@
         err = iHarvesterClient.Connect();
         TN_DEBUG2( "CThumbAGProcessor::RunL() iHarvesterClient connect err = %d", err);
         
-        __ASSERT_DEBUG((err==KErrNone), User::Panic(_L("CThumbAGProcessor::RunL(), !iHarvesterClient "), err));
+        __ASSERT_DEBUG((err == KErrNone), User::Panic(_L("CThumbAGProcessor::RunL(), !iHarvesterClient "), err));
         
         if(  err == KErrNone )
             {
             TN_DEBUG1( "CThumbAGProcessor::RunL() add iHarvesterClient observer");
-            err = iHarvesterClient.AddHarvesterEventObserver( *this, EHEObserverTypeOverall | EHEObserverTypeMMC | EHEObserverTypePlaceholder, KMaxTInt );
+            err = iHarvesterClient.AddHarvesterEventObserver( *this, EHEObserverTypeOverall | EHEObserverTypeMMC | EHEObserverTypePlaceholder, 20 );
             TN_DEBUG2( "CThumbAGProcessor::RunL() iHarvesterClient observer err = %d", err);
+            
+            if( !err )
+                {
+                TN_DEBUG1( "CThumbAGProcessor::RunL() add iHarvesterClient observer failed");
+                // if we fail observer harvester, fake it
+                iHarvesterActivated = ETrue;
+                }
             __ASSERT_DEBUG((err==KErrNone), User::Panic(_L("CThumbAGProcessor::RunL(), !iHarvesterClient "), err));
             }
 #endif
@@ -984,7 +1148,6 @@
     if (!iTMSession)
         {
         TN_DEBUG1( "CThumbAGProcessor::RunL() - open TNM session");
-        iActive = EFalse;
         TRAPD( err, iTMSession = CThumbnailManager::NewL( *this ) );
 		
         if (err != KErrNone)
@@ -1001,19 +1164,11 @@
         }    
    
     // do not run if request is already issued to TNM server even if forced
-    if( iActive)
+    if(iActiveCount >= KMaxDaemonRequests)
         {
-        if(iActiveCount >= KMaxDaemonRequests)
-            {
-            TN_DEBUG1( "CThumbAGProcessor::RunL() - waiting for previous to complete, abort..." );
-            return;
-            }
+        TN_DEBUG1( "CThumbAGProcessor::RunL() - waiting for previous to complete, abort..." );
+        return;
         }
-    else
-        {
-        iActiveCount = 0;   
-        }
-    
     
     //force run can proceed from this point
 #ifdef _DEBUG
@@ -1062,7 +1217,9 @@
         {
         TInt err(KErrNone);
         //if force or non forced
-        if((iForceRun && iModify ) || (!iForceRun && !iModify ))
+		//if unknown items or mount timer is active, abort processing
+
+        if(((iForceRun && iModify ) || (!iForceRun && !iModify )) && !iUnknownItemCount && !iMountTimer->IsActive())
             {
             TN_DEBUG1( "CThumbAGProcessor::RunL() - iQueryReady START" );
             
@@ -1071,21 +1228,16 @@
             
             if ( object )
                 {
-                TInt itemIndex = iLastQueue->FindInOrder(object->Id(), Compare);
-                if(itemIndex >= 0)
-                    {
-                    iLastQueue->Remove(itemIndex);
-                    }
-				
                 //process one item at once
                 //remove item from queryQueue when request is issued 
-                itemIndex = iQueryQueue.FindInOrder(object->Id(), Compare);
+ 
+                TInt itemIndex = iQueryQueue.FindInOrder(object->Id(), CompareId);
                 if(itemIndex >= 0)
                     {
                     iQueryQueue.Remove(itemIndex);
                     }
             
-                TRAP( err, CreateThumbnailsL(object) );
+                TRAP( err, CreateThumbnailsL( object ) );
                 TN_DEBUG2( "CThumbAGProcessor::RunL(), CreateThumbnailsL error == %d", err );
                 __ASSERT_DEBUG((err==KErrNone), User::Panic(_L("CThumbAGProcessor::RunL(), CreateThumbnailsL() "), err));
                 }
@@ -1093,7 +1245,8 @@
         //force is coming, but executing non-forced query complete-> cancel old
         else
             {
-			//cancel query and move items back to original processing queue
+			//cancel query
+            TN_DEBUG1( "CThumbAGProcessor::RunL() - cancel processing query" );
             DeleteAndCancelQuery( ETrue );
 	        ActivateAO();
             return;  
@@ -1113,7 +1266,7 @@
     else if( iQueryActive )
         {
 		//state mismatch
-        if(iForceRun && !iModify)
+        if(iForceRun && !(iModify || iUnknown))
             {
 			//cancel query and move items back to original processing queue
             DeleteAndCancelQuery(ETrue);
@@ -1124,10 +1277,20 @@
             TN_DEBUG1( "CThumbAGProcessor::RunL() - waiting for query to complete, abort..." );
             }    
         }
+    else if ( iUnknownItemCount > 0 )
+        {
+        TN_DEBUG1( "void CThumbAGProcessor::RunL() unknown items in queue");
+        
+        i2ndRound = EFalse;
+        iModify = EFalse;
+        iUnknown = ETrue;
+        iQueryActive = ETrue;
 
+        QueryL( EGenerationItemActionResolveType );
+       }
     // no items in query queue, start new
     // select queue to process, priority by type
-    else if ( iModifyQueue.Count() > 0 )
+    else if ( iModifyItemCount > 0 )
         {
         TN_DEBUG1( "void CThumbAGProcessor::RunL() update thumbnails");
         
@@ -1136,54 +1299,77 @@
         // query for object info
         iQueryActive = ETrue;
         iModify = ETrue;
-        QueryL( iModifyQueue );
+        iUnknown = EFalse;
+        QueryL( EGenerationItemActionModify );
        }
-    else if ( iAddQueue.Count() > 0 )
+    else if ( iAddItemCount > 0 )
         {
         TN_DEBUG1( "void CThumbAGProcessor::RunL() update 1st round thumbnails");
         
         i2ndRound = EFalse;
-        
+        iUnknown = EFalse;
         // query for object info
         iQueryActive = ETrue;
         
-        QueryL( iAddQueue );     
+        QueryL( EGenerationItemActionAdd );     
         }
-    else if ( iRemoveQueue.Count() > 0 )
+    else if ( iDeleteItemCount > 0 )
         {
         TN_DEBUG1( "void CThumbAGProcessor::RunL() delete thumbnails");
-
         i2ndRound = EFalse;
-        
+        iUnknown = EFalse;
         // delete thumbs by URI
         __ASSERT_DEBUG((iTMSession), User::Panic(_L("CThumbAGProcessor::RunL() !iTMSession "), KErrBadHandle));
         if(iTMSession)
             {
-            HBufC* uri = iRemoveQueue[0];
-            TN_DEBUG2( "void CThumbAGProcessor::RunL() delete %S",  uri);
-            CThumbnailObjectSource* source = NULL;
-            TRAPD(err,  source = CThumbnailObjectSource::NewL( *uri, KNullDesC));
-               
-        	if(err == KErrNone)
-            	{
-                iTMSession->DeleteThumbnails( *source );
+            TInt itemIndex(KErrNotFound);
+                                
+            for(TInt i=0;i<iGenerationQueue.Count() || itemIndex == KErrNotFound;i++)
+                {
+                if(iGenerationQueue[i].iItemAction == EGenerationItemActionDelete)
+                    {
+                    itemIndex = i;
+                    }
                 }
-            iRemoveQueue.Remove( 0 );
-            delete source;
-            delete uri;
-            
-            iActiveCount++;
-            iActive = ETrue;
+        
+            if(itemIndex >= 0)
+                {
+                if(!iGenerationQueue[itemIndex].iUri)
+                    {
+                    //URI is invalid
+                    TN_DEBUG1( "void CThumbAGProcessor::RunL() unable to delete URI inbalid");
+                    iGenerationQueue.Remove( itemIndex );
+                    ActivateAO();
+                    return;
+                    }
+
+                TN_DEBUG2( "void CThumbAGProcessor::RunL() delete %S",  iGenerationQueue[itemIndex].iUri);
+                CThumbnailObjectSource* source = NULL;                
+                TRAPD(err,  source = CThumbnailObjectSource::NewL( *iGenerationQueue[itemIndex].iUri, KNullDesC));
+                   
+                if(err == KErrNone)
+                    {
+                    iTMSession->DeleteThumbnails( *source );
+                    }
+                delete source;
+                
+                delete iGenerationQueue[itemIndex].iUri;
+                iGenerationQueue[itemIndex].iUri = NULL;
+                iGenerationQueue.Remove( itemIndex );
+                
+                iActiveCount++;
+                }
             }
         }
-    else if( i2ndRoundGenerateQueue.Count() > 0)
+    else if( i2ndAddItemCount > 0)
         {
         TN_DEBUG1( "void CThumbAGProcessor::RunL() update 2nd round thumbnails");
             
         // query for object info
         iQueryActive = ETrue;
         i2ndRound = ETrue;
-        QueryL( i2ndRoundGenerateQueue );     
+        iUnknown = EFalse;
+        QueryL( EGenerationItemAction2ndAdd );     
         }
         
     TN_DEBUG1( "CThumbAGProcessor::RunL() - end" );
@@ -1212,18 +1398,22 @@
     //move remainig IDs in query queue back to original queue
     while(iQueryQueue.Count())
         {
-        if(aRestoreItems && iLastQueue)
+        if(!aRestoreItems )
             {
-            if(iLastQueue->FindInOrder(iQueryQueue[0], Compare) == KErrNotFound)
+            TThumbnailGenerationItem item;
+            item.iItemId = iQueryQueue[0];
+            TInt itemIndex = iGenerationQueue.FindInOrder(item, Compare);
+                
+            if(itemIndex >= 0)
                 {
-                //ignore if fails
-                iLastQueue->InsertInOrder(iQueryQueue[0], Compare);
+                delete iGenerationQueue[itemIndex].iUri;
+                iGenerationQueue[itemIndex].iUri = NULL;
+                iGenerationQueue.Remove(itemIndex);
                 }
             }
         iQueryQueue.Remove(0);
         }
-    iLastQueue = NULL;
-    
+
     TN_DEBUG1( "CThumbAGProcessor::DeleteAndCancelQuery() out" );
     }
 
@@ -1239,15 +1429,20 @@
 void CThumbAGProcessor::HarvestingUpdated( 
          HarvesterEventObserverType aHEObserverType, 
          HarvesterEventState aHarvesterEventState,
-         TInt /*aItemsLeft*/ )
+         TInt aItemsLeft )
     {
-    TN_DEBUG3( "CThumbAGProcessor::HarvestingUpdated -- start() aHEObserverType = %d, aHarvesterEventState = %d", aHEObserverType, aHarvesterEventState );
+    TN_DEBUG4( "CThumbAGProcessor::HarvestingUpdated -- start() aHEObserverType = %d, aHarvesterEventState = %d, aItemsLeft = %d", aHEObserverType, aHarvesterEventState, aItemsLeft );
     
-    if(iShutdown)
+	if(iShutdown)
         {
         return;
         }
 
+    if(!iHarvesterActivated)
+        {
+        iHarvesterActivated = ETrue;
+        }
+    
     #ifdef _DEBUG
     if( aHEObserverType == EHEObserverTypePlaceholder)
         {
@@ -1257,6 +1452,10 @@
         {
         TN_DEBUG1( "CThumbAGProcessor::HarvestingUpdated -- type EHEObserverTypeOverall");
         }
+    else if( aHEObserverType == EHEObserverTypeMMC)
+        {
+        TN_DEBUG1( "CThumbAGProcessor::HarvestingUpdated -- type EHEObserverTypeMMC");
+        }
     #endif
     
     //placeholder harvesting
@@ -1291,9 +1490,32 @@
             else
                 {
                 TN_DEBUG1( "CThumbAGProcessor::HarvestingUpdated -- MDS placeholder harvesting finished");
-                TRAP_IGNORE(QueryPlaceholdersL());
+                //query present placeholders
+                TRAP_IGNORE(QueryPlaceholdersL( EFalse ));
+                iDoQueryAllItems = EFalse;
+                iPHHarvestingItemsLeftTemp = 0;
                 }
             }
+        
+        //restart mount timout if PH item count is increasing durin MMC harvesting 
+        if(iMMCHarvesting && iPHHarvesting && aItemsLeft > iPHHarvestingItemsLeftTemp)
+          {
+          //if items count increasing, restart mount timeout 
+            TN_DEBUG1( "CThumbAGProcessor::HarvestingUpdated -- PH count increasing, restart mount timeout");
+            
+           if(iMountTimer->IsActive())
+              {
+              iMountTimer->Cancel();
+              }
+
+            iMountTimer->Start( KMountTimeout, KMountTimeout, TCallBack(MountTimerCallBack, this));
+          }
+          
+        //we are interestead of only PHs during MMC harvesting
+        if( iMMCHarvesting )
+            {
+            iPHHarvestingItemsLeftTemp = aItemsLeft;
+            }
         }
     //overall harvesting
     else if ( aHEObserverType == EHEObserverTypeOverall)
@@ -1322,7 +1544,7 @@
             
             if( iHarvesting )
                 {
-                TN_DEBUG1( "CThumbAGProcessor::HarvestingUpdated -- MDS harvesterin started");
+                TN_DEBUG1( "CThumbAGProcessor::HarvestingUpdated -- MDS harvesting started");
                 CancelTimeout();
                 }
             else
@@ -1330,6 +1552,11 @@
                 TN_DEBUG1( "CThumbAGProcessor::HarvestingUpdated -- MDS harvesting finished ");
                 // continue processing if needed
                 StartTimeout();
+                
+                if(iMountTimer->IsActive())
+                    {
+                    iMountTimer->Cancel();
+                    }
                 }
             }
         }
@@ -1361,17 +1588,34 @@
             if( iMMCHarvesting )
                 {
                 TN_DEBUG1( "CThumbAGProcessor::HarvestingUpdated -- MDS MMC harvesterin started");
-                if(iPreviousItemsLeft != KErrNotReady)
-                    {
-                    iPreviousItemsLeft = KErrNotReady;
-                    RProperty::Set(KTAGDPSNotification, KDaemonProcessing, iPreviousItemsLeft);
-                    }
+                UpdatePSValues(EFalse, ETrue);
+                iMMCHarvestingItemsLeftTemp = 0;
                 }
             else
                 {
+				//activate timeout if overall harvesting is not active
+                if(!iHarvesting)
+                    {
+                    StartTimeout();
+                    }
                 TN_DEBUG1( "CThumbAGProcessor::HarvestingUpdated -- MDS MMC harvesting finished ");
                 }
             }
+        
+        //restart mount timout if MMC item count is still increasing 
+        if(iMMCHarvesting && aItemsLeft > iMMCHarvestingItemsLeftTemp)
+            {
+              TN_DEBUG1( "CThumbAGProcessor::HarvestingUpdated -- MMC count increasing, restart mount timeout");
+              
+             if(iMountTimer->IsActive())
+                {
+                iMountTimer->Cancel();
+                }
+
+              iMountTimer->Start( KMountTimeout, KMountTimeout, TCallBack(MountTimerCallBack, this));
+            }
+        
+            iMMCHarvestingItemsLeftTemp = aItemsLeft;
         }
    
     TN_DEBUG4( "CThumbAGProcessor::HarvestingUpdated -- end() iHarvesting == %d, iPHHarvesting == %d iMMCHarvesting == %d ", iHarvesting, iPHHarvesting, iMMCHarvesting);
@@ -1399,6 +1643,7 @@
 //
 void CThumbAGProcessor::CancelTimeout()
     {
+    TN_DEBUG1( "CThumbAGProcessor::CancelTimeout()");
     if(iPeriodicTimer->IsActive())
         {
         iPeriodicTimer->Cancel();
@@ -1417,16 +1662,10 @@
     {
     TN_DEBUG2( "CThumbAGrocessor::RunError() %d", aError);
     
-    UpdatePSValues();
+    UpdatePSValues(EFalse, EFalse);
         
     iActiveCount--;
     
-    if(iActiveCount <= 0)
-        {
-        iActiveCount = 0;
-        iActive = EFalse;
-        }
-    
 	ActivateAO();
 	
     // nothing to do
@@ -1439,23 +1678,16 @@
 //
 void CThumbAGProcessor::ActivateAO()
     {
-#ifdef _DEBUG
-    TN_DEBUG6( "CThumbAGProcessor::ActivateAO() items in queue Add = %d, Mod = %d, Del = %d, Query = %d, iPlaceholder = %d", iAddQueue.Count(),  iModifyQueue.Count(), iRemoveQueue.Count(), iQueryQueue.Count(), iPlaceholderQueue.Count());
-    TN_DEBUG2( "CThumbAGProcessor::ActivateAO() items in queue 2nd Add = %d", i2ndRoundGenerateQueue.Count());
-    TN_DEBUG3( "CThumbAGProcessor::ActivateAO() iActive = %d, iActiveCount = %d", iActive, iActiveCount);
-    TN_DEBUG3( "CThumbAGProcessor::ActivateAO() iHarvesting == %d, iMPXHarvesting == %d", iHarvesting, iMPXHarvesting);
-    TN_DEBUG4( "CThumbAGProcessor::ActivateAO() iIdle = %d, timer = %d, iForceRun = %d", iIdle, iPeriodicTimer->IsActive(), iForceRun);
-    TN_DEBUG4( "CThumbAGProcessor::ActivateAO() iModify = %d, iQueryReady = %d, iProcessingCount = %d", iModify, iQueryReady, iProcessingCount);
-#endif
+    UpdateItemCounts();
     
     if(iFormatting)
         {
         TN_DEBUG1( "CThumbAGProcessor::ActivateAO() - FORMATTING - DAEMON ON PAUSE");
         return;
         }
-        
+    
     //check if forced run needs to continue
-    if (iModifyQueue.Count())
+    if ( iModifyItemCount || iUnknownItemCount > 0 )
         {
         SetForceRun( ETrue );
         }
@@ -1465,7 +1697,7 @@
         SetForceRun( EFalse );
         }
     
-    if( !IsActive() && !iShutdown && ((!iActive && !iQueryActive) || iForceRun ))
+    if( !IsActive() && !iShutdown && ((iActiveCount == 0 && !iQueryActive) || iForceRun ))
         {
         TN_DEBUG1( "CThumbAGProcessor::ActivateAO() - Activated");
         SetActive();
@@ -1473,7 +1705,7 @@
         User::RequestComplete( statusPtr, KErrNone );
         }
 
-    UpdatePSValues();
+    UpdatePSValues(EFalse, EFalse);
     }
 
 // ---------------------------------------------------------------------------
@@ -1562,60 +1794,33 @@
     {
     TN_DEBUG2( "CThumbAGProcessor::RemoveFromQueues() aRemoveFromDelete == %d - begin", aRemoveFromDelete );
     
-    TInt itemIndex = KErrNotFound;
+    TInt itemIndex(KErrNotFound);
     
     for (int i=0; i< aIDArray.Count(); i++)
         {
+        TThumbnailGenerationItem item;
+        item.iItemId = aIDArray[i];
         TN_DEBUG2( "CThumbAGProcessor::RemoveFromQueues() - %d", aIDArray[i]);
 
-        itemIndex = iPlaceholderQueue.FindInOrder(aIDArray[i], Compare);                        
-        if(itemIndex >= 0)
-            {
-            iPlaceholderQueue.Remove(itemIndex);
-            TN_DEBUG1( "CThumbAGProcessor::RemoveFromQueues() - iPlaceholderQueue" );
-            }
-                
-        itemIndex = iAddQueue.FindInOrder(aIDArray[i], Compare);       
+        itemIndex = iGenerationQueue.FindInOrder(item, Compare);                        
         if(itemIndex >= 0)
             {
-            iAddQueue.Remove(itemIndex);
-            TN_DEBUG1( "CThumbAGProcessor::RemoveFromQueues() - iAddQueue" );
-            }
-
-        itemIndex = i2ndRoundGenerateQueue.FindInOrder(aIDArray[i], Compare);               
-        if(itemIndex >= 0)
-            {
-            i2ndRoundGenerateQueue.Remove(itemIndex);
-            TN_DEBUG1( "CThumbAGProcessor::RemoveFromQueues() - i2ndRoundGenerateQueue" );
+            delete iGenerationQueue[itemIndex].iUri;
+            iGenerationQueue[itemIndex].iUri = NULL;
+            iGenerationQueue.Remove(itemIndex);
+            TN_DEBUG1( "CThumbAGProcessor::RemoveFromQueues() - iGenerationQueue" );
             }
-        
-        itemIndex = iModifyQueue.FindInOrder(aIDArray[i], Compare);       
-        if(itemIndex >= 0)
-            {
-            iModifyQueue.Remove(itemIndex);
-            TN_DEBUG1( "CThumbAGProcessor::RemoveFromQueues() - iModifyQueue" );
-			 
-            if( iModifyQueue.Count() == 0)
-			    {
-			    SetForceRun( EFalse );
-		        }
-            }
-            
-        itemIndex = iQueryQueue.FindInOrder(aIDArray[i], Compare);                    
+                
+        itemIndex = iQueryQueue.FindInOrder(aIDArray[i], CompareId);                    
         if(itemIndex >= 0)
             {
             iQueryQueue.Remove(itemIndex);
             TN_DEBUG1( "CThumbAGProcessor::RemoveFromQueues() - iQueryQueue" );
             }
-         
-        itemIndex = iPlaceholderQueue.FindInOrder(aIDArray[i], Compare); 
-        if(itemIndex >= 0)
-        	{
-            iPlaceholderQueue.Remove(itemIndex);
-            TN_DEBUG1( "CThumbAGProcessor::RemoveFromQueues() - iPlaceholderQueue" );
-            }
         }
     
+    ActivateAO();
+    
     TN_DEBUG1( "CThumbAGProcessor::RemoveFromQueues() - end" );
     }
 	
@@ -1674,13 +1879,13 @@
     CMdELogicCondition& rootCondition = iQueryAllItems->Conditions();
     rootCondition.SetOperator( ELogicConditionOperatorOr );
     
-    CMdEObjectCondition& imagePHObjectCondition = rootCondition.AddObjectConditionL(imageObjDef);
+    CMdEObjectCondition& imageObjectCondition = rootCondition.AddObjectConditionL(imageObjDef);
     
-    CMdEObjectCondition& videoPHObjectCondition = rootCondition.AddObjectConditionL(videoObjDef);
+    CMdEObjectCondition& videoObjectCondition = rootCondition.AddObjectConditionL(videoObjDef);
     
-    CMdEObjectCondition& audioPHObjectCondition = rootCondition.AddObjectConditionL(audioObjDef);
+    CMdEObjectCondition& audioObjectCondition = rootCondition.AddObjectConditionL(audioObjDef);
     
-    iQueryAllItems->FindL(KMaxTInt, KMaxQueryItems2);  
+    iQueryAllItems->FindL(KMaxTInt, KMaxQueryBatchSize);  
     
     TN_DEBUG1( "CThumbAGProcessor::QueryAllItemsL - end" );
     }
@@ -1795,8 +2000,7 @@
         {
         iIdle = ETrue; 
         
-        if(iAddQueue.Count() + iModifyQueue.Count() + iRemoveQueue.Count() + 
-           iQueryQueue.Count() + i2ndRoundGenerateQueue.Count() > 0 )
+        if(iGenerationQueue.Count() > 0 )
             {
             ActivateAO();
             }
@@ -1848,10 +2052,10 @@
 // Update KItemsleft PS value if changed
 // ---------------------------------------------------------------------------
 //
-void CThumbAGProcessor::UpdatePSValues(const TBool aDefine)
+void CThumbAGProcessor::UpdatePSValues(const TBool aDefine, const TBool aForce)
     {
-    TInt itemsLeft = iModifyQueue.Count() + iAddQueue.Count();
-    TBool daemonProcessing = EFalse;
+    TInt itemsLeft(KErrNotReady);
+    TBool daemonProcessing = ETrue;
     
     if(iShutdown)
         {
@@ -1859,51 +2063,83 @@
         RProperty::Set(KTAGDPSNotification, KItemsleft, 0 );
         return;
         }
-    
-    if(itemsLeft + i2ndRoundGenerateQueue.Count() + iRemoveQueue.Count() > 0 )
-        {
-        daemonProcessing = ETrue;
-        }
-    
-    //adjust items left to containing also items not yet processed but removed from queue under processing
-    if((iLastQueue == &iModifyQueue || iLastQueue == &iAddQueue) && !i2ndRound)
-        {
-        itemsLeft +=iQueryQueue.Count();
-        }
-    
-    //cancel 2nd round generarion when there is items in 1st round queues
-    if(itemsLeft && i2ndRound)
-        {
-        DeleteAndCancelQuery(ETrue);
-        i2ndRound = EFalse;
-        }
-        
-    TN_DEBUG2( "CThumbAGProcessor::UpdatePSValues() KItemsleft == %d", itemsLeft);
-    
+   
     if(aDefine)
         {
-        TN_DEBUG1( "CThumbAGProcessor::UpdatePSValues() define");
-        RProperty::Define(KTAGDPSNotification, KDaemonProcessing, RProperty::EInt);
-        RProperty::Set(KTAGDPSNotification, KDaemonProcessing, 0);
-        daemonProcessing = EFalse;
-        RProperty::Define(KTAGDPSNotification, KItemsleft, RProperty::EInt);
-        RProperty::Set(KTAGDPSNotification, KItemsleft, 0);
-        iPreviousItemsLeft = 0;
+        TInt ret = RProperty::Define(KTAGDPSNotification, KDaemonProcessing, RProperty::EInt);
+        
+        if( ret != KErrNone )
+            {
+            TN_DEBUG2( "CThumbAGProcessor::UpdatePSValues() define KDaemonProcessing ret = %d", ret);
+            }
+
+        ret = RProperty::Define(KTAGDPSNotification, KItemsleft, RProperty::EInt);
+        
+        if( ret != KErrNone )
+            {
+            TN_DEBUG2( "CThumbAGProcessor::UpdatePSValues() define KItemsleft ret = %d", ret);
+            }
         }
     
-    if( daemonProcessing != iPreviousDaemonProcessing)
-        {
-        TN_DEBUG2( "CThumbAGProcessor::UpdatePSValues() update KDaemonProcessing == %d", daemonProcessing);
-        iPreviousDaemonProcessing = daemonProcessing;
-        RProperty::Set(KTAGDPSNotification, KDaemonProcessing, daemonProcessing);
-        }
+        // set itemsleft = KErrNotReady (-18) and daemonProcessing = ETrue if
+        // - key is initalized
+        // - mount timer is pending
+        // - harvester observer is not yet activated
+        // - single unknown item exists in processing queue
+        // - forced
+       if( iMountTimer->IsActive() || aForce || aDefine  || iUnknownItemCount
+               || !iHarvesterActivated  )
+           {
+           daemonProcessing = ETrue;
+           itemsLeft = KErrNotReady;
+           }
+       else
+           {
+           itemsLeft = iAddItemCount + iModifyItemCount;
+           }
+       
+       TN_DEBUG2( "CThumbAGProcessor::UpdatePSValues() KItemsleft == %d", itemsLeft);
+           
+       //cancel 2nd round generarion when there is items in 1st round queues
+       if(iAddItemCount && i2ndRound)
+           {
+           DeleteAndCancelQuery(ETrue);
+           i2ndRound = EFalse;
+           }
     
-    if( itemsLeft != iPreviousItemsLeft)
-        {
-        TN_DEBUG2( "CThumbAGProcessor::UpdatePSValues() update KItemsleft == %d", itemsLeft);
-        iPreviousItemsLeft = itemsLeft;
-        RProperty::Set(KTAGDPSNotification, KItemsleft, itemsLeft );
-        }
+        if( iGenerationQueue.Count() )
+            {
+            daemonProcessing = ETrue;
+            }
+        else
+            {
+            daemonProcessing = EFalse;
+            }
+        
+        if( daemonProcessing != iPreviousDaemonProcessing)
+            {
+            TN_DEBUG2( "CThumbAGProcessor::UpdatePSValues() update KDaemonProcessing == %d", daemonProcessing);
+            iPreviousDaemonProcessing = daemonProcessing;
+            TInt ret = RProperty::Set(KTAGDPSNotification, KDaemonProcessing, daemonProcessing);
+            
+            if(ret != KErrNone )
+                {
+                TN_DEBUG3( "CThumbAGProcessor::UpdatePSValues() set KDaemonProcessing %d failed %d", daemonProcessing, ret);
+                }
+            }
+        
+        if( itemsLeft != iPreviousItemsLeft)
+            {
+            TN_DEBUG2( "CThumbAGProcessor::UpdatePSValues() update KItemsleft == %d", itemsLeft);
+            iPreviousItemsLeft = itemsLeft;
+            TInt ret = RProperty::Set(KTAGDPSNotification, KItemsleft, itemsLeft );
+            
+            if(ret != KErrNone )
+                {
+                TN_DEBUG3( "CThumbAGProcessor::UpdatePSValues() set KItemsleft %d failed %d", itemsLeft, ret);
+                }
+            }
+        
     }
 
 // ---------------------------------------------------------------------------
@@ -1911,10 +2147,208 @@
 // Comparison function for logaritmic use of queue arrays
 // ---------------------------------------------------------------------------
 //
-TInt CThumbAGProcessor::Compare(const TItemId& aLeft, const TItemId& aRight)
+
+TInt CThumbAGProcessor::Compare(const TThumbnailGenerationItem& aLeft, const TThumbnailGenerationItem& aRight)
+    {  
+    return (aLeft.iItemId - aRight.iItemId);
+    }
+
+TInt CThumbAGProcessor::CompareId(const TItemId& aLeft, const TItemId& aRight)
     {  
     return (aLeft - aRight);
     }
 
+void CThumbAGProcessor::UpdateItemCounts()
+    {
+    TN_DEBUG1( "CThumbAGProcessor::UpdateItemCounts()");
+    iModifyItemCount = 0;
+    iDeleteItemCount = 0;
+    iAddItemCount = 0;
+    iUnknownItemCount = 0;
+    i2ndAddItemCount = 0;
+    iPlaceholderItemCount=0;
+    iCameraItemCount =0;
+    iImageItemCount=0;
+    iVideoItemCount=0;
+    iAudioItemCount=0;
+    
+    for(TInt i=0; i < iGenerationQueue.Count(); i++)
+    {
+        TThumbnailGenerationItem& item = iGenerationQueue[i];
+    
+        if(item.iItemAction == EGenerationItemActionModify)
+            {
+            iModifyItemCount++;
+            }
+        
+        if(item.iItemAction == EGenerationItemActionDelete)
+            {
+            iDeleteItemCount++;
+            }
+        
+        if(item.iItemType == EGenerationItemTypeUnknown)
+            {
+            iUnknownItemCount++;
+            }
+        if(item.iItemAction == EGenerationItemAction2ndAdd)
+            {
+            i2ndAddItemCount++;
+            }
+        if(item.iPlaceholder)
+            {
+            iPlaceholderItemCount++;
+            }
+        if(item.iItemType == EGenerationItemTypeCamera)
+            {
+            iCameraItemCount++;
+            }
+        if(item.iItemAction == EGenerationItemActionAdd )
+            {
+            iAddItemCount++;
+            }
+        if(item.iItemType == EGenerationItemTypeAudio)
+            {
+            iAudioItemCount++;
+            }
+        if(item.iItemType == EGenerationItemTypeVideo)
+            {
+            iVideoItemCount++;
+            }
+        if(item.iItemType == EGenerationItemTypeImage)
+            {
+            iImageItemCount++;
+            }
+    }
+    
+    TN_DEBUG2( "CThumbAGProcessor::UpdateItemCounts() iActiveCount = %d", 
+            iActiveCount);
+    TN_DEBUG2( "CThumbAGProcessor::UpdateItemCounts() iPreviousItemsLeft = %d", 
+            iPreviousItemsLeft);
+    TN_DEBUG5( "CThumbAGProcessor::UpdateItemCounts() iHarvesting == %d, iMMCHarvesting == %d, iPHHarvesting == %d, iMPXHarvesting == %d", 
+            iHarvesting, iMMCHarvesting, iPHHarvesting, iMPXHarvesting);
+    TN_DEBUG5( "CThumbAGProcessor::UpdateItemCounts() iIdle = %d, iForegroundRun = %d, timer = %d, iForceRun = %d", 
+            iIdle, iForegroundRun, iPeriodicTimer->IsActive(), iForceRun);
+    TN_DEBUG4( "CThumbAGProcessor::UpdateItemCounts() iModify = %d, iQueryReady = %d, iProcessingCount = %d", 
+            iModify, iQueryReady, iProcessingCount);
+    TN_DEBUG2( "CThumbAGProcessor::UpdateItemCounts() iMountTimer = %d", iMountTimer->IsActive());
+    TN_DEBUG3( "CThumbAGProcessor::UpdateItemCounts() iGenerationQueue = %d, iQueryQueue = %d", 
+            iGenerationQueue.Count(), iQueryQueue.Count());
+    TN_DEBUG5( "CThumbAGProcessor::UpdateItemCounts() iAddItemCount=%d, i2ndAddItemCount=%d, iModifyItemCount=%d, iDeleteItemCount=%d",
+            iAddItemCount, i2ndAddItemCount, iModifyItemCount, iDeleteItemCount );
+    TN_DEBUG3( "CThumbAGProcessor::UpdateItemCounts() iUnknownItemCount=%d, iPlaceholderItemCount=%d",
+            iUnknownItemCount, iPlaceholderItemCount);
+    TN_DEBUG4( "CThumbAGProcessor::UpdateItemCounts() iAudioItemCount=%d, iVideoItemCount=%d, iImageItemCount=%d",
+            iAudioItemCount, iVideoItemCount, iImageItemCount);
+    TN_DEBUG2( "CThumbAGProcessor::UpdateItemCounts() iCameraItemCount=%d", iCameraItemCount);
+    
+    //compress queues when empty
+    if(!iGenerationQueue.Count())
+        {
+        iGenerationQueue.Compress();
+        }
+    
+    if(!iQueryQueue.Count())
+        {
+        iQueryQueue.Compress();
+        }
+    }
+
+
+// ---------------------------------------------------------------------------
+// CThumbAGProcessor::MountTimerCallBack()
+// ---------------------------------------------------------------------------
+//
+TInt CThumbAGProcessor::MountTimerCallBack(TAny* aAny)
+    {
+    TN_DEBUG1( "CThumbAGProcessor::MountTimerCallBack()");
+    CThumbAGProcessor* self = static_cast<CThumbAGProcessor*>( aAny );
+    
+    self->iMountTimer->Cancel();
+    
+    //activate timeout if overall or mmc harvestig is not active
+    if(!self->iHarvesting && !self->iMMCHarvesting )
+        {
+        self->ActivateAO();
+        }
+
+    return KErrNone; // Return value ignored by CPeriodic
+    }
+
+// ---------------------------------------------------------------------------
+// CThumbAGProcessor::SetGenerationItemAction()
+// ---------------------------------------------------------------------------
+//
+void CThumbAGProcessor::SetGenerationItemAction( TThumbnailGenerationItem& aGenerationItem, TThumbnailGenerationItemType aItemType )
+    {
+    switch( aItemType )
+        {
+        case EGenerationItemTypeAudio:
+            aGenerationItem.iItemAction = EGenerationItemAction2ndAdd;
+            break;
+        case EGenerationItemTypeCamera:
+            aGenerationItem.iItemAction = EGenerationItemAction2ndAdd;
+            aGenerationItem.iPlaceholder = ETrue;
+            break;
+        case EGenerationItemTypeImage:
+            aGenerationItem.iItemAction = EGenerationItemActionAdd;
+            break;
+        case EGenerationItemTypeVideo:
+            //S^3 EGenerationItemActionAdd
+            //S^4 EGenerationItemAction2ndAdd
+            aGenerationItem.iItemAction = EGenerationItemActionAdd;    
+            break;
+        default:
+            aGenerationItem.iItemAction = EGenerationItemActionResolveType;
+        }
+    }
+
+// ---------------------------------------------------------------------------
+// CThumbAGProcessor::SetGenerationItemType()
+// ---------------------------------------------------------------------------
+//
+void CThumbAGProcessor::SetGenerationItemType( TThumbnailGenerationItem& aGenerationItem, const TDefId aDefId )
+    {
+        if(aDefId == iImageObjectDef->Id())
+          {
+            aGenerationItem.iItemType = EGenerationItemTypeImage;
+          }
+      else if(aDefId == iAudioObjectDef->Id())
+          {
+          aGenerationItem.iItemType = EGenerationItemTypeAudio;
+          }
+      else if(aDefId == iVideoObjectDef->Id())
+          {
+          aGenerationItem.iItemType = EGenerationItemTypeVideo;
+          }
+      else
+          {
+          aGenerationItem.iItemType = EGenerationItemTypeUnknown;
+          }
+        
+        SetGenerationItemAction( aGenerationItem, aGenerationItem.iItemType );
+    }
+
+
+// -----------------------------------------------------------------------------
+// CThumbAGProcessor::AppendProcessingQueue()
+// -----------------------------------------------------------------------------
+//
+void CThumbAGProcessor::AppendProcessingQueue( TThumbnailGenerationItem& item )
+    {
+
+    TInt itemIndex = iGenerationQueue.FindInOrder( item, Compare );
+           
+    if(itemIndex >= 0)
+       {
+       iGenerationQueue[itemIndex].iPlaceholder = item.iPlaceholder;
+       iGenerationQueue[itemIndex].iItemType = item.iItemType;
+       iGenerationQueue[itemIndex].iItemAction = item.iItemAction;
+       }
+    else
+       {
+       iGenerationQueue.InsertInOrder(item, Compare);
+       }
+    }
+
 
 // End of file