diff --git a/tree/doc/v520/index.html b/tree/doc/v520/index.html
index ecd6fc80957b152698a6f1f472393cbdf641e381..7aedd4d0b3b19817d2429d4b727f37991b9e383c 100644
--- a/tree/doc/v520/index.html
+++ b/tree/doc/v520/index.html
@@ -129,6 +129,7 @@ where reco_ee_et is a vector<vector<double> >  See http://root.cern.
 <li>Insure that the formula that are used as indices or as argument to special functions have their branch(es) loaded once.  This fixes http://root.cern.ch/phpBB2/viewtopic.php?p=27080#27080
 <li>Correct the drawing of "X[1]:X[5]" when X is a vector&lt; vector&lt;float&gt; &gt;
 and X[1].size()!=X[5].size().  (reported at http://root.cern.ch/phpBB2/viewtopic.php?p=27070)
+<li>Correct the passing of NaN to function being called by TTree::Draw.</li>
 </ul>
 
 <h4>Splitting STL collections of  pointers</h4>
@@ -156,8 +157,37 @@ The size of this unzipping cache is 20% the size of the TTreeCache and can be mo
 This experimental feature is disabled by default, to activate it use the static function <pre>TTreeCache::SetParallelUnzip(TTreeCacheUnzip::EParUnzipMode option = TTreeCacheUnzip::kEnable).</pre> The possible values to pass are: <ul><li>TTreeCacheUnzip::kEnable to enable it</li><li>TTreeCacheUnzip::kDisable to disable it</li><li>TTreeCacheUnzip::kForce to force it.</li></ul>The TTreeCacheUnzip is actived 
 only if you have more than one core.  To activate it with only one core useTTreeCacheUnzip::kForce option (for example to measure the overhead).
 
+<h4>Disk and Memory Space Gain</h4>
+
+In ROOT older than v5.20/00, the branches' last basket, also known as the <i>write basket</i>, was always saved in the same "key" as the TTree object and was always present in memory when reading or writing.  
+When reading this write basket was always present in memory even if the branch was never accessed.
+<p>
+Starting in v5.20/00, TTree::Write closes out, compresses (when requested) and writes to disk in their own file record the <i>write baskets</i> of all the branches.
+(This is implemented via the new function TTree::FlushBaskets, TBranch::FlushBaskets, TBranch::FlushOneBaskets)
+<p>
+TTree::AutoSave supports a new option "FlushBaskets" which will call FlushBaskets before saving the TTree object.
+
+<h5><b><u>Benefits</u></b></h5>
+
+Flushing the write baskets has several advantages:
+<ul>
+<li>Reduce the file size of the TTree object (it not longer contains the last basket), improving read time of the TTree object</li>
+<li>Reduce memory footprint of the TTree object.
+<ul><li>In a TTree which "flushed" buffer, there is now usually only zero or one buffer in memory.</li>
+<li>Previously each branch always had at least one basket in memory and usually 2 (the write basket and one read basket).</li>
+<li>Now only the basket of the branches actually read are loaded in memory.</li>
+</ul>
+</li>
+<li>allow for the basket to be compressed and stored separated, increasing the compression factor.</li>
+</ul>
+
+Note: Calling FlushBaskets too often (either directly of via AutoSave("FlushBaskets")) can lead to unnecessary fragmentation of the ROOT file, 
+since it write the baskets to disk (and a new basket will be started at the next fill) whether or not the content was close to filling the basket or not.
+
 <h4>Others</h4>
 <ul>
+<li>The fast tree cloning (TTreeCloner) was enhanced to support copying in-memory TTrees (that have been save as a single key on file).  This issue was preventing <b>hadd</b> to fast clone files containing any 'in-memory' tree.
+</li>
 <li>Re-enabled the splitting of TVector3 and of any classes starting by TVector
 that is not a TVectorT.</li>
 <li>Fix the list of StreamerInfo stored in the TFile in the case of a slow
@@ -193,5 +223,6 @@ This omission meant that slow CloneTree was (fataly) missing in
 some cases the copy of the TStreamerInfo for class that are part 
 part of the TTree but had only a base and no member or in 
 some cases where it had only object data members.</li>
+<li>Fix the return value of the lookup in TChainIndex 
+when the value searched for does not exist.</li>
 </ul>
-
diff --git a/tree/tree/inc/TBranch.h b/tree/tree/inc/TBranch.h
index 5159411d51de22ce82fabadce7a5887dbfa1a0db..b6571da5f3bdd2439deeb3fb835e540230b1b994 100644
--- a/tree/tree/inc/TBranch.h
+++ b/tree/tree/inc/TBranch.h
@@ -93,6 +93,8 @@ protected:
    void     SetSkipZip(Bool_t skip = kTRUE) { fSkipZip = skip; }
    void     Init(const char *name, const char *leaflist, Int_t compress);
 
+   Int_t    WriteBasket(TBasket* basket, Int_t where);
+
 private:
    TBranch(const TBranch&);             // not implemented
    TBranch& operator=(const TBranch&);  // not implemented
@@ -104,6 +106,7 @@ public:
    virtual ~TBranch();
 
    virtual void      AddBasket(TBasket &b, Bool_t ondisk, Long64_t startEntry);
+   virtual void      AddLastBasket(Long64_t startEntry);
    virtual void      Browse(TBrowser *b);
    virtual void      DeleteBaskets(Option_t* option="");
    virtual void      DropBaskets(Option_t *option = "");
@@ -112,6 +115,9 @@ public:
    virtual void      FillLeaves(TBuffer &b);
    virtual TBranch  *FindBranch(const char *name);
    virtual TLeaf    *FindLeaf(const char *name);
+           Int_t     FlushBaskets();
+           Int_t     FlushOneBasket(UInt_t which);
+
    virtual char     *GetAddress() const {return fAddress;}
    virtual Int_t     GetBasketSize() const {return fBasketSize;}
    virtual const char* GetClassName() const { return ""; }
@@ -175,7 +181,6 @@ public:
    virtual void      SetOffset(Int_t offset=0) {fOffset=offset;}
    virtual void      SetTree(TTree *tree) { fTree = tree;}
    virtual void      UpdateAddress() {;}
-           void      WriteBasket(TBasket* basket);
 
    static  void      ResetCount();
 
diff --git a/tree/tree/inc/TTree.h b/tree/tree/inc/TTree.h
index 66b42ebecaac9a3abf4dd1175499ca7ded2c5d0e..17ee9b373e012f5eb0bd81e6debd0aea494fcf0f 100644
--- a/tree/tree/inc/TTree.h
+++ b/tree/tree/inc/TTree.h
@@ -247,6 +247,7 @@ public:
    virtual TBranch        *FindBranch(const char* name);
    virtual TLeaf          *FindLeaf(const char* name);
    virtual Int_t           Fit(const char* funcname, const char* varexp, const char* selection = "", Option_t* option = "", Option_t* goption = "", Long64_t nentries = 1000000000, Long64_t firstentry = 0); // *MENU*
+   virtual Int_t           FlushBaskets() const;
    virtual const char     *GetAlias(const char* aliasName) const;
    virtual TBranch        *GetBranch(const char* name);
    virtual TBranchRef     *GetBranchRef() const { return fBranchRef; };
@@ -400,6 +401,8 @@ public:
    virtual void            StartViewer(); // *MENU*
    virtual Int_t           UnbinnedFit(const char* funcname, const char* varexp, const char* selection = "", Option_t* option = "", Long64_t nentries = 1000000000, Long64_t firstentry = 0);
    void                    UseCurrentStyle();
+   virtual Int_t           Write(const char *name=0, Int_t option=0, Int_t bufsize=0);
+   virtual Int_t           Write(const char *name=0, Int_t option=0, Int_t bufsize=0) const;
 
    ClassDef(TTree,16)  //Tree descriptor (the main ROOT I/O class)
 };
diff --git a/tree/tree/src/TBasket.cxx b/tree/tree/src/TBasket.cxx
index fb013adb12fe6b6fa488198b34b25b6504317278..541019f09c30abbbcd2c95d6a60fd593d45330ff 100644
--- a/tree/tree/src/TBasket.cxx
+++ b/tree/tree/src/TBasket.cxx
@@ -53,7 +53,7 @@ TBasket::TBasket()
 //_______________________________________________________________________
 TBasket::TBasket(TDirectory *motherDir) : TKey(motherDir)
 {
-   // Simple Constructor.
+   // Constructor used during reading.
 
    fDisplacement  = 0;
    fEntryOffset   = 0;
@@ -71,7 +71,7 @@ TBasket::TBasket(TDirectory *motherDir) : TKey(motherDir)
 TBasket::TBasket(const char *name, const char *title, TBranch *branch) : 
    TKey(branch->GetDirectory())
 {
-   // Basket normal constructor.
+   // Basket normal constructor, used during writing.
 
    SetName(name);
    SetTitle(title);
diff --git a/tree/tree/src/TBranch.cxx b/tree/tree/src/TBranch.cxx
index ddef833c89cc8ae1fd38d29227cb4d2b3aa5f068..489aab5319a12982167d5d695b4b6c3c0cd043f1 100644
--- a/tree/tree/src/TBranch.cxx
+++ b/tree/tree/src/TBranch.cxx
@@ -85,7 +85,7 @@ TBranch::TBranch()
 , fZipBytes(0)
 , fBranches()
 , fLeaves()
-, fBaskets()
+, fBaskets(fMaxBaskets)
 , fNBasketRAM(kMaxRAM+1)
 , fBasketRAM(0)
 , fBasketBytes(0)
@@ -129,7 +129,7 @@ TBranch::TBranch(TTree *tree, const char* name, void* address, const char* leafl
 , fZipBytes(0)
 , fBranches()
 , fLeaves()
-, fBaskets()
+, fBaskets(fMaxBaskets)
 , fNBasketRAM(kMaxRAM+1)
 , fBasketRAM(0)
 , fBasketBytes(0)
@@ -211,7 +211,7 @@ TBranch::TBranch(TBranch *parent, const char* name, void* address, const char* l
 , fZipBytes(0)
 , fBranches()
 , fLeaves()
-, fBaskets()
+, fBaskets(fMaxBaskets)
 , fNBasketRAM(kMaxRAM+1)
 , fBasketRAM(0)
 , fBasketBytes(0)
@@ -403,15 +403,6 @@ void TBranch::Init(const char* name, const char* leaflist, Int_t compress)
    delete[] leaftype;
    leaftype = 0;
 
-   // Create the first basket.
-   //
-   // Note: We cannot do this until we have created the leaves,
-   //       otherwise we do not know the fEntryOffsetLen which
-   //       compensates for variable-sized leaves, like varying
-   //       length arrays.
-   //
-   TBasket* basket = fTree->CreateBasket(this);
-   fBaskets.AddAt(basket, 0);
 }
 
 //______________________________________________________________________________
@@ -530,12 +521,10 @@ void TBranch::AddBasket(TBasket& b, Bool_t ondisk, Long64_t startEntry)
    if (ondisk) {
       fBasketBytes[where] = basket->GetNbytes();  // not for in mem
       fBasketSeek[where] = basket->GetSeekKey();  // not for in mem
+      fBaskets.AddAtAndExpand(0,fWriteBasket);
       ++fWriteBasket;
    } else {
       fBaskets.AddAtAndExpand(basket,fWriteBasket);
-      if (fWriteBasket >= fMaxBaskets) {
-         ExpandBasketArrays();
-      }
       fTree->IncrementTotalBuffers(basket->GetBufferSize());
    }
 
@@ -549,6 +538,26 @@ void TBranch::AddBasket(TBasket& b, Bool_t ondisk, Long64_t startEntry)
    }
 }
 
+//______________________________________________________________________________
+void TBranch::AddLastBasket(Long64_t startEntry)
+{
+   // Add the start entry of the write basket (not yet create)
+
+   if (fWriteBasket >= fMaxBaskets) {
+      ExpandBasketArrays();
+   }
+   Int_t where = fWriteBasket;
+
+   if (where && startEntry < fBasketEntry[where-1]) {
+      // Need to find the right location and move the possible baskets
+
+      Fatal("AddBasket","The last basket must have the highest entry number (%s/%d/%d).",GetName(),startEntry,fWriteBasket);
+
+   }
+   fBasketEntry[where] = startEntry;
+   fBaskets.AddAtAndExpand(0,fWriteBasket);
+}
+
 //______________________________________________________________________________
 void TBranch::Browse(TBrowser* b)
 {
@@ -688,8 +697,11 @@ void TBranch::ExpandBasketArrays()
                                                 newsize*sizeof(Long64_t),fMaxBaskets*sizeof(Long64_t));
    fBasketSeek   = (Long64_t*)TStorage::ReAlloc(fBasketSeek,
                                                 newsize*sizeof(Long64_t),fMaxBaskets*sizeof(Long64_t));
+
    fMaxBaskets   = newsize;
 
+   fBaskets.Expand(newsize);
+
    for (Int_t i=fWriteBasket;i<fMaxBaskets;i++) {
       fBasketBytes[i] = 0;
       fBasketEntry[i] = 0;
@@ -714,7 +726,9 @@ Int_t TBranch::Fill()
 
    TBasket* basket = GetBasket(fWriteBasket);
    if (!basket) {
-      return 0;
+      basket = fTree->CreateBasket(this); //  create a new basket
+      if (!basket) return 0;
+      fBaskets.AddAtAndExpand(basket,fWriteBasket);
    }
    TBuffer* buf = basket->GetBufferRef();
 
@@ -744,7 +758,7 @@ Int_t TBranch::Fill()
             // If the basket already contains entry we need to close it
             // out. (This is because we can only transfer full compressed
             // buffer)
-            WriteBasket(basket);
+            WriteBasket(basket,fWriteBasket);
             // And restart from scratch
             return Fill();
          }
@@ -836,26 +850,7 @@ Int_t TBranch::Fill()
       if (fTree->TestBit(TTree::kCircular)) {
          return nbytes;
       }
-      Int_t nout = basket->WriteBuffer();
-      fBasketBytes[fWriteBasket] = basket->GetNbytes();
-      fBasketSeek[fWriteBasket] = basket->GetSeekKey();
-      Int_t addbytes = basket->GetObjlen() + basket->GetKeylen();
-      if (fDirectory && (fDirectory != gROOT) && fDirectory->IsWritable()) {
-         delete basket;
-         basket = 0;
-         fBaskets[fWriteBasket] = 0;
-      }
-      fZipBytes += nout;
-      fTotBytes += addbytes;
-      fTree->AddTotBytes(addbytes);
-      fTree->AddZipBytes(nout);
-      basket = fTree->CreateBasket(this);
-      ++fWriteBasket;
-      fBaskets.AddAtAndExpand(basket, fWriteBasket);
-      if (fWriteBasket >= fMaxBaskets) {
-         ExpandBasketArrays();
-      }
-      fBasketEntry[fWriteBasket] = fEntryNumber;
+      Int_t nout = WriteBasket(basket,fWriteBasket);
       return (nout >= 0) ? nbytes : -1;
    }
    return nbytes;
@@ -959,6 +954,79 @@ TLeaf* TBranch::FindLeaf(const char* searchname)
    return 0;
 }
 
+
+//______________________________________________________________________________
+Int_t TBranch::FlushBaskets() 
+{
+   // Flush to disk all the baskets of this branch and any of subbranches.
+   // Return the number of bytes written or -1 in case of write error.
+
+   UInt_t nerror = 0;
+   Int_t nbytes = 0;
+
+   for(Int_t i=0; i<=fWriteBasket; ++i) {
+      if (fBaskets.UncheckedAt(i)) {
+         Int_t nwrite = FlushOneBasket(i);
+         if (nwrite<0) {
+            ++nerror;
+         } else {
+            nbytes += nwrite;
+         }
+      }
+   }
+   Int_t len = fBranches.GetEntriesFast();
+   for (Int_t i = 0; i < len; ++i) {
+      TBranch* branch = (TBranch*) fBranches.UncheckedAt(i);
+      if (!branch) {
+         continue;
+      }
+      Int_t nwrite = branch->FlushBaskets();
+      if (nwrite<0) {
+         ++nerror;
+      } else {
+         nbytes += nwrite;
+      }
+   }
+   if (nerror) {
+      return -1;
+   } else {
+      return nbytes;
+   }
+}
+
+//______________________________________________________________________________
+Int_t TBranch::FlushOneBasket(UInt_t ibasket) 
+{
+   // If we have a write basket in memory and it contains some entries and
+   // has not yet been written to disk, we write it and delete it from memory.
+   // Return the number of bytes written;
+   
+   Int_t nbytes = 0;
+   if (fBaskets.GetEntries()) {
+      TBasket *basket = (TBasket*)fBaskets.UncheckedAt(ibasket);
+
+      if (basket) {
+         if (basket->GetNevBuf() 
+             && fBasketSeek[ibasket]==0) {
+            // If the basket already contains entry we need to close it out. 
+            // (This is because we can only transfer full compressed buffer)
+
+            if (basket->GetBufferRef()->IsReading()) {
+               basket->SetWriteMode();
+            }
+            nbytes = WriteBasket(basket,ibasket); // WriteBasket will delete the existing basket.
+
+         } else {
+            // If the basket is empty or has already been written.
+            basket->DropBuffers();
+            delete basket;
+            fBaskets[ibasket] = 0;
+         }
+      }
+   }
+   return nbytes;
+}
+
 //______________________________________________________________________________
 TBasket* TBranch::GetBasket(Int_t basketnumber)
 {
@@ -971,8 +1039,9 @@ TBasket* TBranch::GetBasket(Int_t basketnumber)
    if (basketnumber <0 || basketnumber > fWriteBasket) return 0;
    TBasket *basket = (TBasket*)fBaskets.UncheckedAt(basketnumber);
    if (basket) return basket;
+   if (basketnumber == fWriteBasket) return 0;
 
-     // create/decode basket parameters from buffer
+   // create/decode basket parameters from buffer
    TFile *file = GetFile(0);
    basket = new TBasket(file);
    if (fSkipZip) basket->SetBit(TBufferFile::kNotDecompressed);
@@ -1574,7 +1643,7 @@ void TBranch::Refresh(TBranch* b)
    Int_t nbaskets = b->fBaskets.GetSize();
    fBaskets.Expand(nbaskets);
    //The current fWritebasket must always be in memory.
-   //Take it (just s swap) from the Tree being read
+   //Take it (just swap) from the Tree being read
    TBasket *basket = (TBasket*)b->fBaskets.UncheckedAt(fWriteBasket);
    fBaskets.AddAt(basket,fWriteBasket);
    b->fBaskets.RemoveAt(fWriteBasket);
@@ -1598,8 +1667,6 @@ void TBranch::Reset(Option_t*)
    fZipBytes = 0;
    fEntryNumber = 0;
 
-   Int_t nbaskets = fBaskets.GetEntries();
-
    if (fBasketBytes) {
       for (Int_t i = 0; i < fMaxBaskets; ++i) {
          fBasketBytes[i] = 0;
@@ -1619,11 +1686,6 @@ void TBranch::Reset(Option_t*)
    }
 
    fBaskets.Delete();
-
-   if (nbaskets) {
-      TBasket* basket = fTree->CreateBasket(this);
-      fBaskets.AddAt(basket, 0);
-   }
 }
 
 //______________________________________________________________________________
@@ -1854,6 +1916,7 @@ void TBranch::Streamer(TBuffer& b)
             TLeaf *leaf = (TLeaf*)fLeaves.UncheckedAt(i);
             leaf->SetBranch(this);
          }
+
          Int_t nbaskets = fBaskets.GetEntries();
          for (Int_t j=fWriteBasket,n=0;j>=0 && n<nbaskets;--j) {
             TBasket *bk = (TBasket*)fBaskets.UncheckedAt(j);
@@ -1991,7 +2054,7 @@ void TBranch::Streamer(TBuffer& b)
 
    } else {
       Int_t maxBaskets = fMaxBaskets;
-      fMaxBaskets = fBaskets.GetEntriesFast();
+      fMaxBaskets = fWriteBasket+1;
       if (fMaxBaskets < 10) fMaxBaskets=10;
       b.WriteClassBuffer(TBranch::Class(),this);
       fMaxBaskets = maxBaskets;
@@ -1999,30 +2062,35 @@ void TBranch::Streamer(TBuffer& b)
 }
 
 //_______________________________________________________________________
-void TBranch::WriteBasket(TBasket* basket)
+Int_t TBranch::WriteBasket(TBasket* basket, Int_t where)
 {
-   // Write the current basket to disk
+   // Write the current basket to disk and return the number of bytes
+   // written to the file.
 
    Int_t nout  = basket->WriteBuffer();    //  Write buffer
-   fBasketBytes[fWriteBasket]  = basket->GetNbytes();
-   fBasketSeek[fWriteBasket]   = basket->GetSeekKey();
+   fBasketBytes[where]  = basket->GetNbytes();
+   fBasketSeek[where]   = basket->GetSeekKey();
    Int_t addbytes = basket->GetObjlen() + basket->GetKeylen() ;
-   if (fDirectory != gROOT && fDirectory->IsWritable()) {
+   if (fDirectory && (fDirectory != gROOT) && fDirectory->IsWritable()) {
+      basket->DropBuffers();
       delete basket;
-      fBaskets[fWriteBasket] = 0;
+      fBaskets[where] = 0;
    }
    fZipBytes += nout;
    fTotBytes += addbytes;
    fTree->AddTotBytes(addbytes);
    fTree->AddZipBytes(nout);
 
-   basket = fTree->CreateBasket(this); //  create a new basket
-   fWriteBasket++;
-   fBaskets.AddAtAndExpand(basket,fWriteBasket);
-   if (fWriteBasket >= fMaxBaskets) {
-      ExpandBasketArrays();
+   if (where==fWriteBasket) {
+      ++fWriteBasket;
+      if (fWriteBasket >= fMaxBaskets) {
+         ExpandBasketArrays();
+      }
+      fBaskets.AddAtAndExpand(0,fWriteBasket);
+      fBasketEntry[fWriteBasket] = fEntryNumber;
    }
-   fBasketEntry[fWriteBasket] = fEntryNumber;
+
+   return nout;
 }
 
 //------------------------------------------------------------------------------
diff --git a/tree/tree/src/TBranchClones.cxx b/tree/tree/src/TBranchClones.cxx
index 5c28f666649be74257ec3dcf2d8d9ed3834687e1..9b1f187dabbbfd05f858042a86707454e2289e60 100644
--- a/tree/tree/src/TBranchClones.cxx
+++ b/tree/tree/src/TBranchClones.cxx
@@ -123,9 +123,6 @@ void TBranchClones::Init(TTree *tree, TBranch *parent, const char* name, void* p
    fDirectory = fTree->GetDirectory();
    fFileName = "";
 
-   // Create the first basket.
-   TBasket* basket = new TBasket(branchcount, fTree->GetName(), this);
-   fBaskets.Add(basket);
    // Loop on all public data members of the class and its base classes.
    const char* itype = 0;
    TRealData* rd = 0;
diff --git a/tree/tree/src/TBranchElement.cxx b/tree/tree/src/TBranchElement.cxx
index a8520be26f5be85d53ae36656369e1fefd17532e..57c327644121973aed9a75155cc5dd5fd3851044 100644
--- a/tree/tree/src/TBranchElement.cxx
+++ b/tree/tree/src/TBranchElement.cxx
@@ -262,10 +262,6 @@ void TBranchElement::Init(TTree *tree, TBranch *parent,const char* bname, TStrea
       fBasketSeek[i] = 0;
    }
 
-   // Create a basket for the branch.
-   TBasket* basket = new TBasket(name, fTree->GetName(), this);
-   fBaskets.Add(basket);
-
    // We need to keep track of the counter branch if we have
    // one, since we cannot set it until we have created our
    // leaf, which we do last.
@@ -393,7 +389,7 @@ void TBranchElement::Init(TTree *tree, TBranch *parent,const char* bname, TStrea
             } else {
                clones = (TClonesArray*)pointer;
             }
-            basket->DeleteEntryOffset(); //entryoffset not required for the clonesarray counter
+//             basket->DeleteEntryOffset(); //entryoffset not required for the clonesarray counter
             fEntryOffsetLen = 0;
             // ===> Create a leafcount
             TLeaf* leaf = new TLeafElement(this, name, fID, fStreamerType);
@@ -603,10 +599,6 @@ void TBranchElement::Init(TTree *tree, TBranch *parent, const char* bname, TClon
       fBasketSeek[i]  = 0;
    }
 
-   // Create a basket for the terminal branch
-   TBasket *basket = new TBasket(name, fTree->GetName(), this);
-   fBaskets.Add(basket);
-
    // Reset the bit kAutoDelete to specify that when reading
    // the object should not be deleted before calling the streamer.
    SetAutoDelete(kFALSE);
@@ -734,10 +726,7 @@ void TBranchElement::Init(TTree *tree, TBranch *parent, const char* bname, TVirt
 
    fBasketEntry[0] = fEntryNumber;
    fBasketBytes[0] = 0;
-
-   // Create a basket for the terminal branch
-   TBasket* basket = new TBasket(name, fTree->GetName(), this);
-   fBaskets.Add(basket);
+   fBasketSeek[0] = 0;
 
    // Reset the bit kAutoDelete to specify that, when reading,
    // the object should not be deleted before calling the streamer.
diff --git a/tree/tree/src/TBranchObject.cxx b/tree/tree/src/TBranchObject.cxx
index 836114772e475aed3166d20fb0873a6b985039d5..ee90082848b3c6da7ed1526753f2186b56fdde0b 100644
--- a/tree/tree/src/TBranchObject.cxx
+++ b/tree/tree/src/TBranchObject.cxx
@@ -142,11 +142,6 @@ void TBranchObject::Init(TTree *tree, TBranch *parent, const char* name, const c
    fDirectory = fTree->GetDirectory();
    fFileName = "";
 
-   // Create the first basket.
-   if (!splitlevel) {
-      TBasket* basket = new TBasket(name, fTree->GetName(), this);
-      fBaskets.Add(basket);
-   }
 }
 
 //______________________________________________________________________________
diff --git a/tree/tree/src/TBranchRef.cxx b/tree/tree/src/TBranchRef.cxx
index 5805f34a379ab862ad5c5fd6e46f586a29c5e8a6..da92f6d9a0a36dce4c3226c4052c240b292f6aba 100644
--- a/tree/tree/src/TBranchRef.cxx
+++ b/tree/tree/src/TBranchRef.cxx
@@ -78,9 +78,6 @@ TBranchRef::TBranchRef(TTree *tree)
    fDirectory  = fTree->GetDirectory();
    fFileName   = "";
 
-  //  Create the first basket
-   TBasket *basket = new TBasket("TRefTable",fTree->GetName(),this);
-   fBaskets.Add(basket);
 }
 
 
diff --git a/tree/tree/src/TBranchSTL.cxx b/tree/tree/src/TBranchSTL.cxx
index 92d1d1bbd092c26a484f2c3d2aa0c604e3a2640e..12405267b7b4b52e90aa6a213c23420642e10df6 100644
--- a/tree/tree/src/TBranchSTL.cxx
+++ b/tree/tree/src/TBranchSTL.cxx
@@ -75,11 +75,6 @@ TBranchSTL::TBranchSTL( TTree *tree, const char *name,
       fBasketSeek[i] = 0;
    } 
 
-   //---------------------------------------------------------------------------
-   // Create a basket for the branch.
-   //---------------------------------------------------------------------------
-   TBasket* basket = new TBasket(name, fTree->GetName(), this);
-   fBaskets.Add(basket);
 }
 
 //------------------------------------------------------------------------------
@@ -123,11 +118,6 @@ TBranchSTL::TBranchSTL( TBranch* parent, const char* name,
       fBasketSeek[i] = 0;
    } 
 
-   //---------------------------------------------------------------------------
-   // Create a basket for the branch.
-   //---------------------------------------------------------------------------
-   TBasket* basket = new TBasket(name, fTree->GetName(), this);
-   fBaskets.Add(basket);
 }
 
 //------------------------------------------------------------------------------
diff --git a/tree/tree/src/TTree.cxx b/tree/tree/src/TTree.cxx
index 4aef1c5bdcef9b3346989bc7271f82be8f2243d2..089e394e183201ddc7f3a768ac69f2a8da8adb85 100644
--- a/tree/tree/src/TTree.cxx
+++ b/tree/tree/src/TTree.cxx
@@ -899,6 +899,9 @@ Long64_t TTree::AutoSave(Option_t* option)
    //   if option contains "SaveSelf", gDirectory->SaveSelf() is called.
    //   This allows another process to analyze the Tree while the Tree is being filled.
    //
+   //   if option contains "FlushBaskets", TTree::FlushBaskets is called and all
+   //   the current basket are closed-out and written to disk individually.
+   //
    //   By default the previous header is deleted after having written the new header.
    //   if option contains "Overwrite", the previous Tree header is deleted
    //   before written the new header. This option is slightly faster, but
@@ -950,6 +953,9 @@ Long64_t TTree::AutoSave(Option_t* option)
    }
    TString opt = option;
    opt.ToLower();
+
+   if (opt.Contains("flushbaskets")) FlushBaskets();
+
    fSavedBytes = fTotBytes;
 
    TKey *key = (TKey*)fDirectory->GetListOfKeys()->FindObject(GetName());
@@ -3651,6 +3657,35 @@ Int_t TTree::Fit(const char* funcname, const char* varexp, const char* selection
    return -1;
 }
 
+//______________________________________________________________________________
+Int_t TTree::FlushBaskets() const
+{
+   // Write to disk all the basket that have not yet been individually written.
+   //
+   // Return the number of bytes written or -1 in case of write error.
+   
+   Int_t nbytes = 0;
+   Int_t nerror = 0;
+   TObjArray *lb = const_cast<TTree*>(this)->GetListOfBranches();
+   Int_t nb = lb->GetEntriesFast();
+   for (Int_t j = 0; j < nb; j++) {
+      TBranch* branch = (TBranch*) lb->UncheckedAt(j);
+      if (branch) {
+         Int_t nwrite = branch->FlushBaskets();
+         if (nwrite<0) {
+            ++nerror;
+         } else {
+            nbytes += nwrite;
+         }
+      }
+   }
+   if (nerror) {
+      return -1;
+   } else {
+      return nbytes;
+   }
+}
+
 //______________________________________________________________________________
 const char* TTree::GetAlias(const char* aliasName) const
 {
@@ -6327,6 +6362,25 @@ void TTree::UseCurrentStyle()
    }
 }
 
+//______________________________________________________________________________
+Int_t TTree::Write(const char *name, Int_t option, Int_t bufsize) const 
+{
+   // Write this object to the current directory. For more see TObject::Write
+   // Write calls TTree::FlushBaskets before writing the tree.
+
+   FlushBaskets();
+   return TObject::Write(name, option, bufsize);
+}
+
+//______________________________________________________________________________
+Int_t TTree::Write(const char *name, Int_t option, Int_t bufsize)
+{
+   // Write this object to the current directory. For more see TObject::Write
+   // If option & kFlushBasket, call FlushBasket before writing the tree.
+
+   return ((const TTree*)this)->Write(name, option, bufsize);
+}
+
 //////////////////////////////////////////////////////////////////////////
 //                                                                      //
 // TTreeFriendLeafIter                                                  //
diff --git a/tree/tree/src/TTreeCloner.cxx b/tree/tree/src/TTreeCloner.cxx
index 66de7373755db2f4993b178aa633b4446bc927fd..8de44e0cf490f506cb698c124f0fac1003ce1347 100644
--- a/tree/tree/src/TTreeCloner.cxx
+++ b/tree/tree/src/TTreeCloner.cxx
@@ -136,29 +136,7 @@ void TTreeCloner::CloseOutWriteBaskets()
 
    for(Int_t i=0; i<fToBranches.GetEntries(); ++i) {
       TBranch *to = (TBranch*)fToBranches.UncheckedAt(i);
-
-      TObjArray *array = to->GetListOfBaskets();
-      if (array->GetEntries()) {
-         TBasket *basket = to->GetBasket(to->GetWriteBasket());
-         if (basket) {
-            if (basket->GetNevBuf()) {
-               // If the basket already contains entry we need to close it
-               // out. (This is because we can only transfer full compressed
-               // buffer)
-
-               if (basket->GetBufferRef()->IsReading()) {
-                  basket->SetWriteMode();
-               }
-               to->WriteBasket(basket);
-               basket = to->GetBasket(to->GetWriteBasket()); // WriteBasket create an empty basket
-            }
-            if (basket) {
-               basket->DropBuffers();
-               to->GetListOfBaskets()->RemoveAt(to->GetWriteBasket());
-               delete basket;
-            }
-         }
-      }
+      to->FlushOneBasket(to->GetWriteBasket());
    }
 }
 
@@ -352,10 +330,12 @@ void TTreeCloner::CopyMemoryBaskets()
          basket = (TBasket*)basket->Clone();
          basket->SetBranch(to);
          to->AddBasket(*basket, kFALSE, fToStartEntries+from->GetBasketEntry()[from->GetWriteBasket()]);
+      } else {
+         to->AddLastBasket(  fToStartEntries+from->GetBasketEntry()[from->GetWriteBasket()] );
       }
-      // If the branch is a TBranchElement non-terminal 'object' branch, it's basket will contain 0
-      // events.
-      if (from->GetEntries()!=0 && from->GetWriteBasket()==0 && basket->GetNevBuf()==0) {
+      // In older files, if the branch is a TBranchElement non-terminal 'object' branch, it's basket will contain 0
+      // events, in newer file in the same case, the write basket will be missing.
+      if (from->GetEntries()!=0 && from->GetWriteBasket()==0 && (basket==0 || basket->GetNevBuf()==0)) {
          to->SetEntries(to->GetEntries()+from->GetEntries());
       }
    }
@@ -449,22 +429,25 @@ void TTreeCloner::WriteBaskets()
       Int_t index = fBasketNum[ fBasketIndex[j] ];
 
       Long64_t pos = from->GetBasketSeek(index);
-      if (from->GetBasketBytes()[index] == 0) {
-         from->GetBasketBytes()[index] = basket->ReadBasketBytes(pos, fromfile);
-      }
-      Int_t len = from->GetBasketBytes()[index];
-      Long64_t entryInBasket;
-      if (index == from->GetWriteBasket()) {
-         entryInBasket = from->GetEntries() - from->GetBasketEntry()[index];
+      if (pos!=0) {
+         if (from->GetBasketBytes()[index] == 0) {
+            from->GetBasketBytes()[index] = basket->ReadBasketBytes(pos, fromfile);
+         }
+         Int_t len = from->GetBasketBytes()[index];
+
+         basket->LoadBasketBuffers(pos,len,fromfile);
+         basket->IncrementPidOffset(fPidOffset);
+         basket->CopyTo(tofile);
+         to->AddBasket(*basket,kTRUE,fToStartEntries + from->GetBasketEntry()[index]);
       } else {
-         entryInBasket = from->GetBasketEntry()[index+1] - from->GetBasketEntry()[index];
+         TBasket *frombasket = from->GetBasket( index );
+         if (frombasket->GetNevBuf()>0) {
+            TBasket *tobasket = (TBasket*)frombasket->Clone();
+            tobasket->SetBranch(to);
+            to->AddBasket(*tobasket, kFALSE, fToStartEntries+from->GetBasketEntry()[index]);
+            to->FlushOneBasket(to->GetWriteBasket());
+         }
       }
-
-      basket->LoadBasketBuffers(pos,len,fromfile);
-      basket->IncrementPidOffset(fPidOffset);
-      basket->CopyTo(tofile);
-      to->AddBasket(*basket,kTRUE,fToStartEntries + from->GetBasketEntry()[index]);
-
    }
    delete basket;
 }