diff --git a/io/io/inc/TFPBlock.h b/io/io/inc/TFPBlock.h
index 06df0cec93bb32565548a63c9ec44fcbc3e74f3a..ca40ef4ed0fc8bc077afebce6b151112a617bdef 100644
--- a/io/io/inc/TFPBlock.h
+++ b/io/io/inc/TFPBlock.h
@@ -51,6 +51,7 @@ public:
    char     *GetBuffer() const;
 
    void SetBuffer(char*);
+   void SetPos(Int_t, Long64_t);
    void ReallocBlock(Long64_t*, Int_t*, Int_t);
 
    ClassDef(TFPBlock, 0);  // File prefetch block
diff --git a/io/io/inc/TFile.h b/io/io/inc/TFile.h
index 78ea2cbabf019ded707ace22ff00d8be294027a5..16110b3b1283a81ff765a8938b859f56e20ed791 100644
--- a/io/io/inc/TFile.h
+++ b/io/io/inc/TFile.h
@@ -169,6 +169,7 @@ public:
    virtual void        FillBuffer(char *&buffer);
    virtual void        Flush();
    TArchiveFile       *GetArchive() const { return fArchive; }
+   Long64_t            GetArchiveOffset() const { return fArchiveOffset; }
    Int_t               GetBestBuffer() const;
    virtual Int_t       GetBytesToPrefetch() const;
    TFileCacheRead     *GetCacheRead() const;
diff --git a/io/io/inc/TFilePrefetch.h b/io/io/inc/TFilePrefetch.h
index 9a0c9a7f8230f04371d4a21d5c346a3f3790417c..f0da2770553711b689943f372b8ae1ca253e80d2 100644
--- a/io/io/inc/TFilePrefetch.h
+++ b/io/io/inc/TFilePrefetch.h
@@ -75,6 +75,7 @@ private:
    TThread    *fConsumer;          // consumer thread
    TMutex     *fMutexPendingList;  // mutex for the pending list
    TMutex     *fMutexReadList;     // mutex for the list of read blocks
+   TMutex     *fMutexSynch;        // mutex for synchronisation between working and main thread
    TCondition *fNewBlockAdded;     // condition used to signal the addition of a new pending block
    TCondition *fReadBlockAdded;    // condition usd to signal the addition of a new red block
    TSemaphore *fSem;               // semaphore used to kill the consumer thread
@@ -111,6 +112,9 @@ public:
    Bool_t    BinarySearchReadList(TFPBlock*, Long64_t, Int_t, Int_t*);
    Long64_t  GetWaitTime();
 
+   void      SetFile(TFile*);
+   TMutex*   GetMutexSynch() const { return fMutexSynch; };
+
    ClassDef(TFilePrefetch, 0);  // File block prefetcher
 };
 
diff --git a/io/io/src/TFPBlock.cxx b/io/io/src/TFPBlock.cxx
index 9523a58820ebaac687a8e207de4b7473d63500a1..e8672bf4deccda5daa52a682279ed198ab07dc2c 100644
--- a/io/io/src/TFPBlock.cxx
+++ b/io/io/src/TFPBlock.cxx
@@ -114,6 +114,16 @@ char* TFPBlock::GetBuffer() const
    return fBuffer;
 }
 
+
+//__________________________________________________________________
+void TFPBlock::SetPos(Int_t idx, Long64_t value)
+{
+   // Set pos value for index idx.
+
+   fPos[idx] = value;
+}
+
+
 //__________________________________________________________________
 void TFPBlock::SetBuffer(char* buf)
 {
diff --git a/io/io/src/TFile.cxx b/io/io/src/TFile.cxx
index 8ac82b8b83fe67c8916184c90ab3098be1c8ce6c..1e8133ef5620187e0bc7255d1703a68c5944b77b 100644
--- a/io/io/src/TFile.cxx
+++ b/io/io/src/TFile.cxx
@@ -494,7 +494,6 @@ TFile::TFile(const TFile &) : TDirectoryFile(), fInfoCache(0)
 TFile::~TFile()
 {
    // File destructor.
-
    Close();
 
    SafeDelete(fProcessIDs);
diff --git a/io/io/src/TFileCacheRead.cxx b/io/io/src/TFileCacheRead.cxx
index 36eb1bed3f1cab7a670f09de6c4602f34b8414b2..5b442f14be1d71d662d12bea43f9e0351e9677ee 100644
--- a/io/io/src/TFileCacheRead.cxx
+++ b/io/io/src/TFileCacheRead.cxx
@@ -172,6 +172,7 @@ TFileCacheRead::~TFileCacheRead()
 {
    // Destructor.
 
+   SafeDelete(fPrefetch);
    delete [] fSeek;
    delete [] fSeekIndex;
    delete [] fSeekSort;
@@ -189,7 +190,6 @@ TFileCacheRead::~TFileCacheRead()
    delete [] fBSeekSortLen;
    delete [] fBSeekPos;
    delete [] fBLen;
-   SafeDelete(fPrefetch);
 }
 
 //_____________________________________________________________________________
@@ -531,6 +531,11 @@ void TFileCacheRead::SetFile(TFile *file)
    }
 
    Prefetch(0,0);
+   
+   if (fPrefetch) {
+      SecondPrefetch(0, 0);
+      fPrefetch->SetFile(file);
+   }
 }
 
 //_____________________________________________________________________________
diff --git a/io/io/src/TFilePrefetch.cxx b/io/io/src/TFilePrefetch.cxx
index 66efd1f9d364b87a6a49cec6b9f0ffc971aa68bf..f01996ab10686d753b1a3abd4303f22630558134 100644
--- a/io/io/src/TFilePrefetch.cxx
+++ b/io/io/src/TFilePrefetch.cxx
@@ -36,13 +36,14 @@ TFilePrefetch::TFilePrefetch(TFile* file)
 
    fConsumer = 0;
    fFile = file;
-   fPendingBlocks = new TList();
-   fReadBlocks = new TList();
-   fMutexReadList = new TMutex();
+   fPendingBlocks    = new TList();
+   fReadBlocks       = new TList();
+   fMutexReadList    = new TMutex();
    fMutexPendingList = new TMutex();
-   fNewBlockAdded = new TCondition(0);
-   fReadBlockAdded = new TCondition(0);
-   fSem = new TSemaphore(0);
+   fMutexSynch       = new TMutex();
+   fNewBlockAdded    = new TCondition(0);
+   fReadBlockAdded   = new TCondition(0);
+   fSem              = new TSemaphore(0);
 }
 
 //____________________________________________________________________________________________
@@ -51,7 +52,9 @@ TFilePrefetch::~TFilePrefetch()
    // Destructor.
 
    //killing consumer thread
-   fSem->Post();
+   fMutexSynch->Lock();     //wait fo thread to finish work
+   fMutexSynch->UnLock();
+   fSem->Post();            //send terminate signal
    fNewBlockAdded->Signal();
    fConsumer->Join();
   
@@ -60,6 +63,7 @@ TFilePrefetch::~TFilePrefetch()
    SafeDelete(fReadBlocks);
    SafeDelete(fMutexReadList);
    SafeDelete(fMutexPendingList);
+   SafeDelete(fMutexSynch);
    SafeDelete(fNewBlockAdded);
    SafeDelete(fReadBlockAdded);
    SafeDelete(fSem);
@@ -78,6 +82,10 @@ void TFilePrefetch::ReadAsync(TFPBlock* block, Bool_t &inCache)
    }
    else{
      fFile->ReadBuffers(block->GetBuffer(), block->GetPos(), block->GetLen(), block->GetNoElem());
+     if (fFile->GetArchive()){
+        for (Int_t i = 0; i < block->GetNoElem(); i++)
+           block->SetPos(i, block->GetPos(i) - fFile->GetArchiveOffset());
+     }
      inCache =kFALSE;
    }
    delete[] path;
@@ -276,6 +284,16 @@ TThread* TFilePrefetch::GetThread() const
    return fConsumer;
 }
 
+
+//____________________________________________________________________________________________
+void TFilePrefetch::SetFile(TFile *file) 
+{
+   // Change the file
+  
+   fFile = file;
+}
+
+
 //____________________________________________________________________________________________
 Int_t TFilePrefetch::ThreadStart()
 {
@@ -293,12 +311,17 @@ TThread::VoidRtnFunc_t TFilePrefetch::ThreadProc(void* arg)
    // Execution loop of the consumer thread.
 
    TFilePrefetch* tmp = (TFilePrefetch*) arg;
+   tmp->fMutexSynch->Lock();
 
    while(tmp->fSem->TryWait() !=0){
       tmp->ReadListOfBlocks();
       if (tmp->fSem->TryWait() == 0) break;
+      tmp->fMutexSynch->UnLock();
       tmp->fNewBlockAdded->Wait();
+      tmp->fMutexSynch->Lock();
    }
+   
+   tmp->fMutexSynch->UnLock();
 
    return (TThread::VoidRtnFunc_t) 1;
 }
diff --git a/tree/tree/src/TChain.cxx b/tree/tree/src/TChain.cxx
index 8a4e732751ef922eb0c9800a2c93b91995e4332f..ad35b085d8431f9691dd8e1591f5173f759e5a91 100644
--- a/tree/tree/src/TChain.cxx
+++ b/tree/tree/src/TChain.cxx
@@ -54,6 +54,7 @@
 #include "TEntryList.h"
 #include "TEntryListFromFile.h"
 #include "TFileStager.h"
+#include "TFilePrefetch.h"
 
 const Long64_t theBigNumber = Long64_t(1234567890)<<28;
 
@@ -171,7 +172,7 @@ TChain::~TChain()
 {
    // -- Destructor.
    gROOT->GetListOfCleanups()->Remove(this);
-
+   
    SafeDelete(fProofChain);
    fStatus->Delete();
    delete fStatus;
@@ -179,6 +180,13 @@ TChain::~TChain()
    fFiles->Delete();
    delete fFiles;
    fFiles = 0;
+
+   //first delete cache if exists
+   if (fFile && fFile->GetCacheRead()) {
+      delete fFile->GetCacheRead();
+      fFile->SetCacheRead(0);
+   }
+
    delete fFile;
    fFile = 0;
    // Note: We do *not* own the tree.
@@ -1389,7 +1397,14 @@ Long64_t TChain::LoadTree(Long64_t entry)
    if (fFile) {
       if (!fDirectory->GetList()->FindObject(this)) {
          tpf = (TTreeCache*) fFile->GetCacheRead();
-         if (tpf) tpf->ResetCache();
+         if (tpf) {
+           tpf->ResetCache();
+           if (tpf->IsEnablePrefetching()){
+              //wait for thread to finish current work
+              tpf->GetPrefetchObj()->GetMutexSynch()->Lock();
+              tpf->GetPrefetchObj()->GetMutexSynch()->UnLock();
+           }
+         }
          fFile->SetCacheRead(0);
          if (fCanDeleteRefs) {
             fFile->Close("R");
diff --git a/tree/tree/src/TTreeCache.cxx b/tree/tree/src/TTreeCache.cxx
index ce562f80722dfb9cfac98ab657f5f229a048002d..db640218a816d7c12855ed2794178158241f4022 100644
--- a/tree/tree/src/TTreeCache.cxx
+++ b/tree/tree/src/TTreeCache.cxx
@@ -305,7 +305,7 @@ TTreeCache::TTreeCache(TTree *tree, Int_t buffersize) : TFileCacheRead(tree->Get
 //______________________________________________________________________________
 TTreeCache::~TTreeCache()
 {
-   // destructor. (in general called by the TFile destructor
+   // destructor. (in general called by the TFile destructor)
 
    delete fBranches;
    if (fBrNames) {fBrNames->Delete(); delete fBrNames; fBrNames=0;}
@@ -943,7 +943,11 @@ void TTreeCache::ResetCache()
 {
    // This will simply clear the cache
    TFileCacheRead::Prefetch(0,0);
-
+   
+   if (fEnablePrefetching) {
+      fFirstTime = kTRUE;
+      TFileCacheRead::SecondPrefetch(0, 0);
+   }
 }
 
 //_____________________________________________________________________________