Index: /trunk/MagicSoft/Mars/manalysis/MMatrixLoop.cc
===================================================================
--- /trunk/MagicSoft/Mars/manalysis/MMatrixLoop.cc	(revision 6498)
+++ /trunk/MagicSoft/Mars/manalysis/MMatrixLoop.cc	(revision 6499)
@@ -64,6 +64,7 @@
 //
 // Return name of MHMatrix, <n/a> if not available
+// The name of the matrix must nor contain a '/'
 //
-TString MMatrixLoop::GetFileName() const
+TString MMatrixLoop::GetFullFileName() const
 {
     return fMatrix ? fMatrix->GetName() : "<n/a>";
Index: /trunk/MagicSoft/Mars/manalysis/MMatrixLoop.h
===================================================================
--- /trunk/MagicSoft/Mars/manalysis/MMatrixLoop.h	(revision 6498)
+++ /trunk/MagicSoft/Mars/manalysis/MMatrixLoop.h	(revision 6499)
@@ -20,5 +20,5 @@
     // MRead
     UInt_t  GetEntries();
-    TString GetFileName() const;
+    TString GetFullFileName() const;
     Bool_t  Rewind() { fNumRow=0; return kTRUE; }
 
Index: /trunk/MagicSoft/Mars/mbase/MInputStreamID.h
===================================================================
--- /trunk/MagicSoft/Mars/mbase/MInputStreamID.h	(revision 6498)
+++ /trunk/MagicSoft/Mars/mbase/MInputStreamID.h	(revision 6499)
@@ -24,4 +24,6 @@
     MInputStreamID(const char *name=NULL, const char *title=NULL);
 
+    Bool_t HasStreamId() const { return fStreamId.CompareTo("all", TString::kIgnoreCase)!=0; }
+
     const TString &GetStreamId() const { return fStreamId; }
     void SetStreamId(const char *t)    { fStreamId = t; }
Index: /trunk/MagicSoft/Mars/mfileio/MRead.cc
===================================================================
--- /trunk/MagicSoft/Mars/mfileio/MRead.cc	(revision 6498)
+++ /trunk/MagicSoft/Mars/mfileio/MRead.cc	(revision 6499)
@@ -52,4 +52,17 @@
     *fLog << err << "ERROR - Rewind() not implemented for " << GetDescriptor() << endl;
     return kFALSE;
+}
+
+// --------------------------------------------------------------------------
+//
+//  Return the name of the file we are actually reading from.
+//
+TString MRead::GetFileName() const
+{
+    TString name(GetFullFileName());
+    if (name.IsNull())
+        return "<n/a>";
+    name.Remove(0, name.Last('/')+1);
+    return name;
 }
 
Index: /trunk/MagicSoft/Mars/mfileio/MRead.h
===================================================================
--- /trunk/MagicSoft/Mars/mfileio/MRead.h	(revision 6498)
+++ /trunk/MagicSoft/Mars/mfileio/MRead.h	(revision 6499)
@@ -18,5 +18,6 @@
 
     virtual UInt_t  GetEntries() = 0;
-    virtual TString GetFileName() const = 0;
+    virtual TString GetFileName() const;
+    virtual TString GetFullFileName() const = 0;
     virtual Bool_t  Rewind();
 
Index: /trunk/MagicSoft/Mars/mfileio/MReadReports.cc
===================================================================
--- /trunk/MagicSoft/Mars/mfileio/MReadReports.cc	(revision 6498)
+++ /trunk/MagicSoft/Mars/mfileio/MReadReports.cc	(revision 6499)
@@ -134,5 +134,5 @@
 // If no master is available "<MReadReports>" is returned.
 //
-TString MReadReports::GetFileName() const
+TString MReadReports::GetFullFileName() const
 {
     if (!TestBit(kHasMaster))
Index: /trunk/MagicSoft/Mars/mfileio/MReadReports.h
===================================================================
--- /trunk/MagicSoft/Mars/mfileio/MReadReports.h	(revision 6498)
+++ /trunk/MagicSoft/Mars/mfileio/MReadReports.h	(revision 6499)
@@ -30,5 +30,5 @@
 
     UInt_t  GetEntries();
-    TString GetFileName() const;
+    TString GetFullFileName() const;
 
     Int_t   PreProcess(MParList *plist);
Index: /trunk/MagicSoft/Mars/mfileio/MReadRflFile.h
===================================================================
--- /trunk/MagicSoft/Mars/mfileio/MReadRflFile.h	(revision 6498)
+++ /trunk/MagicSoft/Mars/mfileio/MReadRflFile.h	(revision 6499)
@@ -53,5 +53,5 @@
     Bool_t Rewind() { fNumFile=0; return kTRUE; }
     UInt_t GetEntries() { return fEntries; }
-    TString GetFileName() const { return fFileName; }
+    TString GetFullFileName() const { return fFileName; }
 
     Bool_t SearchFor(Int_t runno, Int_t eventno);
Index: /trunk/MagicSoft/Mars/mfileio/MReadTree.cc
===================================================================
--- /trunk/MagicSoft/Mars/mfileio/MReadTree.cc	(revision 6498)
+++ /trunk/MagicSoft/Mars/mfileio/MReadTree.cc	(revision 6499)
@@ -1120,14 +1120,12 @@
 //  Return the name of the file we are actually reading from.
 //
-TString MReadTree::GetFileName() const
+TString MReadTree::GetFullFileName() const
 {
     const TFile *file = fChain ? fChain->GetFile() : fTree->GetCurrentFile();
 
     if (!file)
-        return TString("<unknown>");
-
-    TString name(file->GetName());
-    name.Remove(0, name.Last('/')+1);
-    return name;
+        return "<unknown>";
+
+    return file->GetName();
 }
 
Index: /trunk/MagicSoft/Mars/mfileio/MReadTree.h
===================================================================
--- /trunk/MagicSoft/Mars/mfileio/MReadTree.h	(revision 6498)
+++ /trunk/MagicSoft/Mars/mfileio/MReadTree.h	(revision 6499)
@@ -70,5 +70,6 @@
     UInt_t GetEntries();
 
-    TString GetFileName() const;
+    //TString GetFileName() const;
+    TString GetFullFileName() const;
     Int_t   GetFileIndex() const;
 
@@ -92,2 +93,3 @@
 
 #endif
+
Index: /trunk/MagicSoft/Mars/mfileio/MWriteRootFile.cc
===================================================================
--- /trunk/MagicSoft/Mars/mfileio/MWriteRootFile.cc	(revision 6498)
+++ /trunk/MagicSoft/Mars/mfileio/MWriteRootFile.cc	(revision 6499)
@@ -43,5 +43,6 @@
 // constructor or specify 'memory' as option in the constructor.
 //
-// Afterwards the tree can be found using gROOT->FindObject("treename")
+// Afterwards the tree can be found using
+// gROOT->GetListOfFiles()->FindObject("treename")
 //
 // Currently(!) the tree is not deleted at all! Please make sure to
@@ -90,4 +91,5 @@
     //
     fBranches.SetOwner();
+    fCopies.SetOwner();
 
     //
@@ -100,4 +102,32 @@
     gROOT->GetListOfCleanups()->Add(this); // To remove fDisplay
     SetBit(kMustCleanup);
+}
+
+// --------------------------------------------------------------------------
+//
+// Try to get the file from gROOT->GetListOfFiles.
+// If it is found fOut is set to it and returned.
+// Otherwise a new file is opened and returned.
+//
+TFile *MWriteRootFile::OpenFile(const char *name, Option_t *option, const char *title, Int_t comp)
+{
+    TFile *file = dynamic_cast<TFile*>(gROOT->GetListOfFiles()->FindObject(name));
+    if (!file)
+    {
+        file = new TFile(name, option, title, comp);
+        file->SetOption(option); // IMPORTANT!
+        ResetBit(kIsNotOwner);
+        return file;
+    }
+
+    fOut = file;
+    fOut->SetBit(kMustCleanup);
+    SetBit(kIsNotOwner);
+
+    *fLog << inf;
+    *fLog << "File '" << name << "' already open... using." << endl;
+    *fLog << "Make sure that you do NOT write to trees which are" << endl;
+    *fLog << "scheduled already by a different MWriteRootFile..." << endl;
+    return fOut;
 }
 
@@ -139,6 +169,5 @@
     // a valid file. (Stupid workaround - but does a good job)
     //
-    fOut = new TFile("/dev/null", option, ftitle, comp);
-    fOut->SetOption(option); // IMPORTANT!
+    fOut = OpenFile("/dev/null", option, ftitle, comp);
 }
 
@@ -192,17 +221,5 @@
     // Open the rootfile
     //
-    TObject *find = gROOT->FindObject(str);
-    if (find && find->InheritsFrom(TFile::Class()))
-    {
-        fOut = (TFile*)find;
-        fOut->SetBit(kMustCleanup);
-        SetBit(kIsNotOwner);
-
-        *fLog << inf << "File '" << fname << "' already open... using." << endl;
-        *fLog << "Make sure that you do NOT write to trees which are" << endl;
-        *fLog << "scheduled already by a different MWriteRootFile..." << endl;
-    }
-    else
-        fOut = new TFile(str, opt, ftitle, comp);
+    fOut = OpenFile(str, opt, ftitle, comp);
 }
 
@@ -217,8 +234,8 @@
     // Print some statistics to the looging out.
     //
-    Print();
-
     if (fOut && !TestBit(kIsNotOwner))
     {
+        Print();
+
         //
         // If the file is still open (no error) write the keys. This is necessary
@@ -267,5 +284,5 @@
     if (fTrees.GetEntries()==0)
     {
-        *fLog << " No contents." << endl;
+        *fLog << "  No contents." << endl;
         return;
     }
@@ -295,5 +312,5 @@
             *fLog << " + " << t->GetName() << ": \t" << (ULong_t)t->GetEntries() << " entries." << endl;
 
-    TIter NextKey(fOut->GetListOfKeys());
+    TIter NextKey(fOut->GetList());
     while ((obj=NextKey()))
     {
@@ -304,8 +321,7 @@
             continue;
 
-        *fLog << " - " << obj->GetName() << ": \t" << (ULong_t)((TTree*)t)->GetEntries() << " entries." << endl;
+        *fLog << " - " << obj->GetName() << ": \t" << (ULong_t)((TTree*)obj)->GetEntries() << " entries." << endl;
     }
     *fLog << endl;
-
 }
 
@@ -357,6 +373,5 @@
 // is the name of the tree.
 //
-void MWriteRootFile::AddContainer(MParContainer *cont, const char *tname,
-                                  Bool_t must)
+void MWriteRootFile::AddContainer(MParContainer *cont, const char *tname, Bool_t must)
 {
     if (!fOut && !tname)
@@ -380,4 +395,15 @@
     MRootFileBranch *entry = new MRootFileBranch(cont, tname, must);
     fBranches.AddLast(entry);
+}
+
+// --------------------------------------------------------------------------
+//
+// If you want to copy a full tree (or some branches of some trees)
+// completely from one file to another one you can use this
+//
+void MWriteRootFile::AddCopySource(const char *tname, const char *bname)
+{
+    fCopies.Add(new TNamed(tname, bname?bname:"*"));
+    fCopies.Sort();
 }
 
@@ -497,7 +523,7 @@
             tree->SetBit(kIsNewTree);
 
+            *fLog << inf << "Tree " << tname << " created in " << gDirectory->GetName() << endl;
+
             gDirectory = save;
-
-            *fLog << inf << "Tree " << tname << " created." << endl;
         }
 
@@ -666,5 +692,5 @@
     // If we are writing into memory we don't split into seperate files
     //
-    if (!fOut)
+    if (!fOut || TestBit(kIsNotOwner))
         return kTRUE;
 
@@ -694,35 +720,23 @@
 Bool_t MWriteRootFile::ChangeFile(const char *fname)
 {
-    if (!fOut)
-    {
-        TObject *find = gROOT->FindObject(fname);
-        if (find && find->InheritsFrom(TFile::Class()))
-        {
-            fOut = (TFile*)find;
-            SetBit(kIsNotOwner);
-            return kTRUE;
-        }
-
-        *fLog << err << "MWriteRootFile::ChangeFile: Expecting file '" << fname;
-        *fLog << "' in gROOT->FindObject... not found." << endl;
-        return kFALSE;
-    }
-
-    //
-    // The following code is more or less a copy of TTree::ChangeFile
-    //
-    const Int_t   compr = fOut->GetCompressionLevel();
-    const TString title = fOut->GetTitle();
-    const TString opt   = fOut->GetOption();
-
-    *fLog << inf << "MWriteRootFile - Open new file " << fname << " (Title=" << title << ", Option=" << opt << ", Compression=" << compr << ")" << endl;
+    const Int_t   compr = fOut ? fOut->GetCompressionLevel() : 0;
+    const TString title = fOut ? fOut->GetTitle()            : "";
+    const TString opt   = fOut ? fOut->GetOption()           : "";
 
     // Open new file with old setup
-    TFile *newfile = TFile::Open(fname, opt, title, compr);
+    TFile *newfile = OpenFile(fname, opt, title, compr);
+    if (newfile && newfile==fOut)
+    {
+        *fLog << inf << "Found open file " << fname << "... using." << endl;
+        return kTRUE;
+    }
+
     if (!newfile)
     {
         *fLog << err << "ERROR - Cannot open new file " << fname << endl;
-        return kFALSE;
-    }
+         return kFALSE;
+    }
+
+    *fLog << inf << "Open new file " << fname << " (Title=" << title << ", Option=" << opt << ", Compression=" << compr << ")" << endl;
 
     // Print statistics of old file
@@ -743,5 +757,5 @@
 
         // If this is not a tree do nothing.
-        if (!obj->InheritsFrom("TTree"))
+        if (!obj->InheritsFrom(TTree::Class()))
             continue;
 
@@ -784,5 +798,5 @@
 // If you need more difficult rules please send me an eMail...
 //
-TString MWriteRootFile::GetNewFileName(const char *inname) const
+TString MWriteRootFile::GetNewFileName(TString &inname) const
 {
     // Remove the path from the filename
@@ -847,4 +861,6 @@
         path.Append("/");
 
+    inname.Prepend(path);
+
     // Create full qualified pathname
     path += fname;
@@ -854,4 +870,66 @@
 // --------------------------------------------------------------------------
 //
+// Writes a copy of the TTree t to the currently open file using
+// TTree::CloneTree()
+//
+void MWriteRootFile::CopyTree(TTree &t)
+{
+    *fLog << "Copy of tree " << t.GetName() << " in progress..." << flush;
+
+    TTree *clone=t.CloneTree();
+    clone->Write();
+    delete clone;
+
+    *fLog << "done." << endl;
+}
+
+// --------------------------------------------------------------------------
+//
+// Make all copies requested from the currently open file into the new
+// file.
+//
+Bool_t MWriteRootFile::MakeCopies(const char *fname) const
+{
+    if (fCopies.GetEntries()==0)
+        return kTRUE;
+
+    TFile *file = dynamic_cast<TFile*>(gROOT->GetListOfFiles()->FindObject(fname));
+    if (!file)
+    {
+        *fLog << err << "ERROR - MakeCopies: File " << fname << " not found in gROOT->GetListOfFiles()... abort." << endl;
+        return kFALSE;
+    }
+
+    TIter Next(&fCopies);
+    TObject *o=0;
+    TTree   *t=0;
+
+    fOut->cd();
+    while ((o=Next()))
+    {
+        TTree *gettree = dynamic_cast<TTree*>(file->Get(o->GetName()));
+        if (!gettree)
+            continue;
+
+        gettree->SetBranchStatus(o->GetTitle(), 1);
+
+        // First Execution
+        if (t==gettree)
+            continue;
+
+        // Check if its the first call
+        if (t)
+            CopyTree(*t);
+        t = gettree;
+    }
+
+    if (t)
+        CopyTree(*t);
+
+    return kTRUE;
+}
+
+// --------------------------------------------------------------------------
+//
 // ReInit. If file splitting is not allowed call MWriteFile::ReInit.
 //
@@ -868,5 +946,5 @@
 Bool_t MWriteRootFile::ReInit(MParList *pList)
 {
-    if (fSplitRule.IsNull() || !fOut)
+    if (fSplitRule.IsNull() || !(fOut || TestBit(kIsNotOwner)))
         return MWriteFile::ReInit(pList);
 
@@ -883,6 +961,11 @@
     }
 
-    const TString fname = GetNewFileName(read->GetFileName());
-    if (!ChangeFile(fname))
+    TString oldname = read->GetFileName();
+
+    const TString newname = GetNewFileName(oldname);
+    if (!ChangeFile(newname))
+        return kFALSE;
+
+    if (!MakeCopies(oldname))
         return kFALSE;
 
@@ -930,8 +1013,5 @@
 {
     if (obj==fOut && TestBit(kIsNotOwner))
-    {
-        ResetBit(kIsNotOwner);
         fOut=0;
-    }
 }
 
Index: /trunk/MagicSoft/Mars/mfileio/MWriteRootFile.h
===================================================================
--- /trunk/MagicSoft/Mars/mfileio/MWriteRootFile.h	(revision 6498)
+++ /trunk/MagicSoft/Mars/mfileio/MWriteRootFile.h	(revision 6499)
@@ -78,4 +78,5 @@
     TObjArray fBranches;     // List of Branch setup (MRootFileBranch)
     TObjArray fTrees;        //! List of trees
+    TObjArray fCopies;       // Branches and tree to copy
 
     TString fSplitRule;      // file splitting allowed if rule existing (done in ReInit)
@@ -92,6 +93,9 @@
     // File handling
     void    Close();
-    TString GetNewFileName(const char *fname) const;
+    TString GetNewFileName(TString &inname) const;
     Bool_t  ChangeFile(const char *fname);
+    TFile  *OpenFile(const char *name, Option_t *option, const char *title, Int_t comp);
+    void    CopyTree(TTree &t);
+    Bool_t  MakeCopies(const char *oldname) const;
 
     // MWrite
@@ -126,4 +130,5 @@
     void AddContainer(const char *cname,   const char *tname=NULL, Bool_t must=kTRUE);
     void AddContainer(MParContainer *cont, const char *tname=NULL, Bool_t must=kTRUE);
+    void AddCopySource(const char *tname, const char *bname=NULL);
 
     void Print(Option_t *t=NULL) const;
