// @(#)root/base:$Id$
// Author: Gerhard Erich Bruckner, Jan Fiete Grosse-Oetringhaus  04/06/07

/*************************************************************************
 * Copyright (C) 1995-2007, Rene Brun and Fons Rademakers.               *
 * All rights reserved.                                                  *
 *                                                                       *
 * For the licensing terms see $ROOTSYS/LICENSE.                         *
 * For the list of contributors see $ROOTSYS/README/CREDITS.             *
 *************************************************************************/

//////////////////////////////////////////////////////////////////////////
//                                                                      //
// TFileCollection                                                      //
//                                                                      //
// Class that contains a list of TFileInfo's and accumulated meta       //
// data information about its entries. This class is used to describe   //
// file sets as stored by Grid file catalogs, by PROOF or any other     //
// collection of TFile names.                                           //
//                                                                      //
//////////////////////////////////////////////////////////////////////////

#include "TFileCollection.h"
#include "THashList.h"
#include "TFileInfo.h"
#include "TIterator.h"
#include "TMap.h"
#include "TObjString.h"
#include "TUri.h"
#include "TUrl.h"
#include "TSystem.h"
#include "Riostream.h"
#include "TRegexp.h"
#include "TPRegexp.h"
#include "TError.h"


ClassImp(TFileCollection)

//______________________________________________________________________________
TFileCollection::TFileCollection(const char *name, const char *title,
                                 const char *textfile, Int_t nfiles, Int_t firstfile)
   : TNamed(name, title), fList(0), fMetaDataList(0), fDefaultTree(),
     fTotalSize(0), fNFiles(0), fNStagedFiles(0), fNCorruptFiles(0)
{
   // TFileCollection constructor. Specify a name and title describing
   // the list. If textfile is specified the file is opened and a
   // TFileCollection is created containing the files in the textfile.

   fList = new THashList();
   fList->SetOwner();

   fMetaDataList = new TList;
   fMetaDataList->SetOwner();

   AddFromFile(textfile, nfiles, firstfile);
}

//______________________________________________________________________________
TFileCollection::~TFileCollection()
{
   // Cleanup.

   delete fList;
   delete fMetaDataList;
}

//______________________________________________________________________________
Int_t TFileCollection::Add(TFileInfo *info)
{
   // Add TFileInfo to the collection.

   if (fList && info) {
      if (!fList->FindObject(info->GetName())) {
         fList->Add(info);
         if (info->GetIndex() < 0) info->SetIndex(fList->GetSize());
         return 1;
      } else {
         Warning("Add", "file: '%s' already in the list - ignoring",
                        info->GetCurrentUrl()->GetUrl());
      }
   }
   return 0;
}

//______________________________________________________________________________
Int_t TFileCollection::Add(TFileCollection *coll)
{
   // Add content of the TFileCollection to this collection.

   if (fList && coll && coll->GetList()) {
      TIter nxfi(coll->GetList());
      TFileInfo *fi = 0;
      while ((fi = (TFileInfo *) nxfi())) {
         TFileInfo *info = new TFileInfo(*fi);
         fList->Add(info);
         if (fi->GetIndex() < 0) info->SetIndex(fList->GetSize());
      }
      return 1;
   } else {
      return 0;
   }
}

//______________________________________________________________________________
Int_t TFileCollection::AddFromFile(const char *textfile, Int_t nfiles, Int_t firstfile)
{
   // Add file names contained in the specified text file.
   // The file should contain one url per line; empty lines or lines starting with '#'
   // (commented lines) are ignored.
   // If nfiles > 0 only nfiles files are added, starting from file 'firstfile' (>= 1).
   // The method returns the number of added files.

   if (!fList)
     return 0;

   Int_t nf = 0;
   TString fn(textfile);
   if (!fn.IsNull() && !gSystem->ExpandPathName(fn)) {
      std::ifstream f;
      f.open(fn);
      if (f.is_open()) {
         Bool_t all = (nfiles <= 0) ? kTRUE : kFALSE;
         Int_t ff = (!all && (firstfile < 1)) ? 1 : firstfile;
         Int_t nn = 0;
         while (f.good() && (all || nf < nfiles)) {
            TString line;
            line.ReadToDelim(f);
            // Skip commented or empty lines
            if (!line.IsWhitespace() && !line.BeginsWith("#")) {
               nn++;
               if (all || nn >= ff) {
                  TFileInfo *info = new TFileInfo(line);
                  fList->Add(info);
                  if (info->GetIndex() < 0) info->SetIndex(fList->GetSize());
                  nf++;
               }
            }
         }
         f.close();
         Update();
      } else
         Error("AddFromFile", "unable to open file %s (%s)", textfile, fn.Data());
   }
   return nf;
}

//______________________________________________________________________________
Int_t TFileCollection::Add(const char *dir)
{
   // Add all files matching the specified pattern to the collection.
   // 'dir' can include wildcards after the last slash, which causes all
   // matching files in that directory to be added.
   // If dir is the full path of a file, only one element is added.
   // Return value is the number of added files.

   Int_t nf = 0;

   if (!fList)
      return nf;

   if (!dir || !*dir) {
      Error("Add", "input dir undefined");
      return nf;
   }

   FileStat_t st;
   FileStat_t tmp;
   TString baseDir = gSystem->DirName(dir);
   // if the 'dir' or its base dir exist
   if (gSystem->GetPathInfo(dir, st) == 0 ||
       gSystem->GetPathInfo(baseDir, tmp) == 0) {
      // If 'dir' points to a single file, add to the list and exit
      if (R_ISREG(st.fMode)) {
         // regular, single file
         TFileInfo *info = new TFileInfo(dir);
         info->SetBit(TFileInfo::kStaged);
         Add(info);
         nf++;
         Update();
         return nf;
      } else {
         void *dataSetDir = gSystem->OpenDirectory(gSystem->DirName(dir));
         if (!dataSetDir) {
            // directory cannot be opened
            Error("Add", "directory %s cannot be opened",
                  gSystem->DirName(dir));
         } else {
            const char *ent;
            TString filesExp(TString("^") + gSystem->BaseName(dir) + "$");
            filesExp.ReplaceAll("*",".*");
            TRegexp rg(filesExp);
            while ((ent = gSystem->GetDirEntry(dataSetDir))) {
               TString entryString(ent);
               if (entryString.Index(rg) != kNPOS) {
                  // matching dir entry
                  TString fn = gSystem->DirName(dir);
                  fn += "/";
                  fn += ent;
                  gSystem->GetPathInfo(fn, st);
                  if (R_ISREG(st.fMode)) {
                     // regular file
                     TFileInfo *info = new TFileInfo(fn);
                     info->SetBit(TFileInfo::kStaged);
                     Add(info);
                     nf++;
                  }
               }
            }
            // close the directory
            gSystem->FreeDirectory(dataSetDir);
            Update();
         }
      }
   }
   return nf;
}

//______________________________________________________________________________
Int_t TFileCollection::RemoveDuplicates()
{
   // Remove duplicates based on the UUID, typically after a verification.
   // Return the number of entries removed.

   THashList *hl = new THashList;
   hl->SetOwner();

   Int_t n0 = fList->GetSize();
   TIter nxfi(fList);
   TFileInfo *fi = 0;
   while ((fi = (TFileInfo *)nxfi())) {
      if (!(hl->FindObject(fi->GetUUID()->AsString()))) {
         // We hash on the UUID
         fList->Remove(fi);
         fi->SetName(fi->GetUUID()->AsString());
         hl->Add(fi);
      }
   }
   delete fList;
   fList = hl;
   // How many removed?
   Int_t nr = n0 - fList->GetSize();
   if (nr > 0)
      Info("RemoveDuplicates", "%d duplicates found and removed", nr);
   // Done
   return nr;
}

//______________________________________________________________________________
TFileCollection *TFileCollection::GetStagedSubset()
{
   // Creates a subset of the files that have the kStaged & !kCorrupted bit set.

   if (!fList)
     return 0;

   TFileCollection *subset = new TFileCollection(GetName(), GetTitle());

   TIter iter(fList);
   TFileInfo *fileInfo = 0;
   while ((fileInfo = dynamic_cast<TFileInfo*>(iter.Next()))) {
      if (fileInfo->TestBit(TFileInfo::kStaged) && !fileInfo->TestBit(TFileInfo::kCorrupted))
         subset->Add(fileInfo);
   }

   subset->Update();

   return subset;
}

//______________________________________________________________________________
Long64_t TFileCollection::Merge(TCollection *li)
{
   // Merge all TFileCollection objects in li into this TFileCollection object.
   // Updates counters at the end.
   // Returns the number of merged collections or -1 in case of error.


   if (!li) return 0;
   if (li->IsEmpty()) return 0;

   Long64_t nentries=0;
   TIter next(li);
   while (TObject *o = next()) {
      TFileCollection* coll = dynamic_cast<TFileCollection*> (o);
      if (!coll) {
         Error("Add", "attempt to add object of class: %s to a %s",
                      o->ClassName(),this->ClassName());
         return -1;
      }
      Add(coll);
      nentries++;
   }
   Update();

   return nentries;
}

//______________________________________________________________________________
Int_t TFileCollection::Update(Long64_t avgsize)
{
   // Update accumulated information about the elements of the collection
   // (e.g. fTotalSize). If 'avgsize' > 0, use an average file size of 'avgsize'
   // bytes when the size info is not available.
   // Also updates the meta data information by summarizing
   // the meta data of the contained objects.
   // Return -1 in case of any failure, 0 if the total size is exact, 1 if
   // incomplete, 2 if complete but (at least partially) estimated.

   if (!fList)
     return -1;

   Int_t rc = 0;

   fTotalSize = 0;
   fNStagedFiles = 0;
   fNCorruptFiles = 0;

   // Clear internal meta information which is going to be rebuilt in this
   // function
   TIter nxm(fMetaDataList);
   TFileInfoMeta *m = 0;
   while ((m = (TFileInfoMeta *)nxm())) {
      if (!(m->TestBit(TFileInfoMeta::kExternal))) {
         fMetaDataList->Remove(m);
         delete m;
      }
   }

   fNFiles = fList->GetEntries();

   TIter iter(fList);
   TFileInfo *fileInfo = 0;
   while ((fileInfo = dynamic_cast<TFileInfo*> (iter.Next()))) {

      if (fileInfo->GetSize() > 0) {
         fTotalSize += fileInfo->GetSize();
      } else {
         rc = 1;
         if (avgsize > 0) {
            rc = 2;
            fTotalSize += avgsize;
         }
      }

      if (fileInfo->TestBit(TFileInfo::kStaged) && !fileInfo->TestBit(TFileInfo::kCorrupted)) {
         fNStagedFiles++;

         if (fileInfo->GetMetaDataList()) {
            TIter metaDataIter(fileInfo->GetMetaDataList());
            // other than TFileInfoMeta is also allowed in list
            TObject *obj = 0;
            while ((obj = metaDataIter.Next())) {
               TFileInfoMeta *metaData = dynamic_cast<TFileInfoMeta*>(obj);
               if (!metaData)
                  continue;
               if (!metaData->IsTree())
                  continue;

               // find corresponding entry in TFileCollection's meta data
               TFileInfoMeta *metaDataSum = dynamic_cast<TFileInfoMeta*>(fMetaDataList->FindObject(metaData->GetName()));
               Bool_t newObj = kFALSE;
               if (!metaDataSum) {
                  // create explicitly, there are some values that do not make sense for the sum
                  metaDataSum = new TFileInfoMeta(metaData->GetName(), metaData->GetTitle());
                  fMetaDataList->Add(metaDataSum);
                  newObj = kTRUE;
               }

               // sum the values
               if (newObj)
                  metaDataSum->SetEntries(metaData->GetEntries());
               else
                  metaDataSum->SetEntries(metaDataSum->GetEntries() + metaData->GetEntries());
            }
         }
      }
      if (fileInfo->TestBit(TFileInfo::kCorrupted))
         fNCorruptFiles++;
   }

   // Done
   return rc;
}

//______________________________________________________________________________
void TFileCollection::Print(Option_t *option) const
{
   // Prints the contents of the TFileCollection.
   // If option contains:
   //      'M'             print global meta information
   //      'F'             print all the files in the collection in compact form
   //                      (current url, default tree name|class|entries, md5)
   //      'L'             together with 'F', print all the files in the collection
   //                      in long form (uuid, md5, all URLs, all meta objects; on
   //                      many lines)
   //      "filter:[SsCc]" invokes PrintDetailed() which prints out dataset
   //                      content in a formatted fashion by filtering on files
   //                      which are (S)taged or not (s), (C)orrupted or not (c)

   TString opt(option);
   TPMERegexp re("(^|;| )filter:([SsCc]+)( |;|$)", 4);
   if (re.Match(option) == 4) {
     TString showOnly = re[2];
     PrintDetailed(showOnly);
     return;
   }

   Printf("TFileCollection %s - %s contains: %lld files with a size of"
          " %lld bytes, %.1f %% staged - default tree name: '%s'",
          GetName(), GetTitle(), fNFiles, fTotalSize, GetStagedPercentage(),
          GetDefaultTreeName());

   if (opt.Contains("M", TString::kIgnoreCase)) {
      Printf("The files contain the following trees:");

      TIter metaDataIter(fMetaDataList);
      TFileInfoMeta* metaData = 0;
      while ((metaData = dynamic_cast<TFileInfoMeta*>(metaDataIter.Next()))) {
         if (!metaData->IsTree())
            continue;

         Printf("Tree %s: %lld events", metaData->GetName(), metaData->GetEntries());
      }
   }

   if (fList && opt.Contains("F", TString::kIgnoreCase)) {
      Printf("The collection contains the following files:");
      if (!opt.Contains("L") && !fDefaultTree.IsNull())
         opt += TString::Format(" T:%s", fDefaultTree.Data());
      fList->Print(opt);
   }
}

//______________________________________________________________________________
void TFileCollection::PrintDetailed(TString &showOnly) const
{

   Bool_t bS, bs, bC, bc;
   bS = bs = bC = bc = kFALSE;

   if (showOnly.Index('S') >= 0) bS = kTRUE;
   if (showOnly.Index('s') >= 0) bs = kTRUE;
   if (showOnly.Index('C') >= 0) bC = kTRUE;
   if (showOnly.Index('c') >= 0) bc = kTRUE;

   // If Ss (or Cc) omitted, show both Ss (or Cc)
   if (!bc && !bC) bc = bC = kTRUE;
   if (!bs && !bS) bs = bS = kTRUE;

   TIter it(fList);
   TFileInfo *info;
   UInt_t countAll = 0;
   UInt_t countMatch = 0;

   Printf("\033[1m   #. SC | Entries | Size       | URL\033[m");

   TString um;
   Double_t sz;

   while ((info = dynamic_cast<TFileInfo *>(it.Next()))) {

      Bool_t s = info->TestBit(TFileInfo::kStaged);
      Bool_t c = info->TestBit(TFileInfo::kCorrupted);

      TUrl *url;

      countAll++;

      if ( ((s && bS) || (!s && bs)) && ((c && bC) || (!c && bc)) ) {

         TFileInfoMeta *meta = info->GetMetaData();  // gets the first one
         Int_t entries = -1;

         if (meta) entries = meta->GetEntries();

         FormatSize(info->GetSize(), um, sz);

         // First line: current URL with all information
         info->ResetUrl();
         TUrl *curUrl = info->GetCurrentUrl();
         const char *curUrlStr = curUrl ? curUrl->GetUrl() : "n.a.";
         Printf("\033[1m%4u.\033[m %c%c | %-7s | %6.1lf %s | %s",
           ++countMatch,
           (s ? 'S' : 's'), (c ? 'C' : 'c'),
           ((entries > 0) ? Form("% 7d", entries) : "n.a."),
           sz, um.Data(), curUrlStr);
         info->NextUrl();

         // Every other URL shown below current one
         while ((url = info->NextUrl())) {
            Printf("         |         |            | %s", url->GetUrl());
         }
         info->ResetUrl();

      } // end match filters

   } // end loop over entries

   if (countAll) {

     Printf(">> There are \033[1m%u\033[m file(s) in dataset: "
        "\033[1m%u (%5.1f%%)\033[m matched your criteria (%s)",
        countAll, countMatch,
        100.*(Float_t)countMatch/(Float_t)countAll, showOnly.Data());

    FormatSize(fTotalSize, um, sz);
    Printf(">> Total size    : \033[1m%.1f %s\033[m", sz, um.Data());
    Printf(">> Staged (S)    : \033[1m%5.1f %%\033[m", GetStagedPercentage());
    Printf(">> Corrupted (C) : \033[1m%5.1f %%\033[m",
      GetCorruptedPercentage());

  }
  else {
    Printf(">> No files in dataset");
  }

  const char *treeName = GetDefaultTreeName();
  Printf(">> Default tree  : \033[1m%s\033[m",
    (treeName ? treeName : "(no default tree)"));

}

//______________________________________________________________________________
void TFileCollection::FormatSize(Long64_t bytes, TString &um,
   Double_t &size) const
{

   static const char *ums[] = { "byt", "KiB", "MiB", "GiB", "TiB" };
   Int_t maxDiv = sizeof(ums)/sizeof(const char *);
   Int_t nDiv = 0;
   Double_t b = bytes;

   while ((b >= 1024.) && (nDiv+1 < maxDiv)) {
      b /= 1024.;
      nDiv++;
   }

   um = ums[nDiv];
   size = b;
}

//______________________________________________________________________________
void TFileCollection::SetAnchor(const char *anchor)
{
   // Calls TUrl::SetAnchor() for all URLs contained in all TFileInfos.

   if (!fList)
     return;

   TIter iter(fList);
   TFileInfo *fileInfo = 0;
   while ((fileInfo = dynamic_cast<TFileInfo*>(iter.Next()))) {
      fileInfo->ResetUrl();
      TUrl *url = 0;
      while ((url = fileInfo->NextUrl()))
         url->SetAnchor(anchor);
      fileInfo->ResetUrl();
   }
}

//______________________________________________________________________________
void TFileCollection::SetBitAll(UInt_t f)
{
   // Set the bit for all TFileInfos

   if (!fList)
     return;

   TIter iter(fList);
   TFileInfo *fileInfo = 0;
   while ((fileInfo = dynamic_cast<TFileInfo*>(iter.Next())))
      fileInfo->SetBit(f);
}

//______________________________________________________________________________
void TFileCollection::ResetBitAll(UInt_t f)
{
   // Reset the bit for all TFileInfos

   if (!fList)
     return;

   TIter iter(fList);
   TFileInfo *fileInfo = 0;
   while ((fileInfo = dynamic_cast<TFileInfo*>(iter.Next())))
      fileInfo->ResetBit(f);
}

//______________________________________________________________________________
const char *TFileCollection::GetDefaultTreeName() const
{
   // Returns the tree set with SetDefaultTreeName if set
   // Returns the name of the first tree in the meta data list.
   // Returns 0 in case no trees are found in the meta data list.

   if (fDefaultTree.Length() > 0)
     return fDefaultTree;

   TIter metaDataIter(fMetaDataList);
   TFileInfoMeta *metaData = 0;
   while ((metaData = dynamic_cast<TFileInfoMeta*>(metaDataIter.Next()))) {
      if (!metaData->IsTree())
         continue;
      return metaData->GetName();
   }
   return 0;
}

//______________________________________________________________________________
Long64_t TFileCollection::GetTotalEntries(const char *tree) const
{
   // Returns the number of entries for the specified tree (retrieved from meta data).
   // If tree is not specified, use the default tree name.
   // Returns -1 in case the specified tree is not found.

   if (!tree || !*tree) {
      tree = GetDefaultTreeName();
      if (!tree)
         return -1;
   }

   TFileInfoMeta *metaData = dynamic_cast<TFileInfoMeta*>(fMetaDataList->FindObject(tree));
   if (!metaData)
      return -1;

   return metaData->GetEntries();
}

//______________________________________________________________________________
TFileInfoMeta *TFileCollection::GetMetaData(const char *meta) const
{
   // Returns the meta data object with the soecified meta name.
   // Returns 0 in case specified meta data is not found.

   if (!meta || !*meta)
      return 0;

   return dynamic_cast<TFileInfoMeta*>(fMetaDataList->FindObject(meta));
}

//______________________________________________________________________________
void TFileCollection::SetDefaultMetaData(const char *meta)
{
   // Moves the indicated meta data in the first position, so that
   // it becomes efectively the default.

   TFileInfoMeta *fim = GetMetaData(meta);
   if (fim) {
      fMetaDataList->Remove(fim);
      fMetaDataList->AddFirst(fim);
   }
}

//______________________________________________________________________________
void TFileCollection::RemoveMetaData(const char *meta)
{
   // Removes the indicated meta data object in all TFileInfos and this object
   // If no name is given all metadata is removed

   if (fList) {
      TIter iter(fList);
      TFileInfo *fileInfo = 0;
      while ((fileInfo = dynamic_cast<TFileInfo*>(iter.Next())))
         fileInfo->RemoveMetaData(meta);
   }

   if (meta) {
      TObject* obj = fMetaDataList->FindObject("meta");
      if (obj) {
         fMetaDataList->Remove(obj);
         delete obj;
      }
   } else
      fMetaDataList->Clear();
}

//______________________________________________________________________________
void TFileCollection::Sort(Bool_t useindex)
{
   // Sort the collection.

   if (!fList)
     return;

   // Make sure the relevant bit has teh wanted value
   if (useindex) {
      SetBitAll(TFileInfo::kSortWithIndex);
   } else {
      ResetBitAll(TFileInfo::kSortWithIndex);
   }

   fList->Sort();
}

//______________________________________________________________________________
TObjString *TFileCollection::ExportInfo(const char *name, Int_t popt)
{
   // Export the relevant info as a string; use 'name' as collection name,
   // if defined, else use GetName().
   // The output object must be destroyed by the caller

   TString treeInfo;
   if (GetDefaultTreeName()) {
      TFileInfoMeta* meta = GetMetaData(GetDefaultTreeName());
      if (popt == 1) {
         treeInfo = GetDefaultTreeName();
         if (meta)
            treeInfo += TString::Format(", %lld entries", meta->GetEntries());
         TFileInfoMeta *frac = GetMetaData("/FractionOfTotal");
         if (frac)
            treeInfo += TString::Format(", %3.1f %% of total", frac->GetEntries() / 10.);
      } else {
         treeInfo.Form(" %s ", GetDefaultTreeName());
         if (treeInfo.Length() > 14) treeInfo.Replace(13, 1, '>');
         treeInfo.Resize(14);
         if (meta) {
            if (meta->GetEntries() > 99999999) {
               treeInfo += TString::Format("| %8lld ", meta->GetEntries());
            } else {
               treeInfo += TString::Format("| %8.4g ", (Double_t) meta->GetEntries());
            }
         }
      }
   } else {
      treeInfo = "        N/A";
   }
   if (popt == 0) treeInfo.Resize(25);

   // Renormalize the size to kB, MB or GB
   const char *unit[4] = {"kB", "MB", "GB", "TB"};
   Int_t k = 0;
   Long64_t refsz = 1024;
   Long64_t xsz = (Long64_t) (GetTotalSize() / refsz);
   while (xsz > 1024 && k < 3) {
      k++;
      refsz *= 1024;
      xsz = (Long64_t) (GetTotalSize() / refsz);
   }

   // The name
   TString dsname(name);
   if (dsname.IsNull()) dsname = GetName();

   // Create the output string
   TObjString *outs = 0;
   if (popt == 1) {
      outs = new TObjString(Form("%s %lld files, %lld %s, staged %d %%, tree: %s", dsname.Data(),
                                 GetNFiles(), xsz, unit[k],
                                 (Int_t)GetStagedPercentage(), treeInfo.Data()));
   } else {
      outs = new TObjString(Form("%s| %7lld |%s| %5lld %s |  %3d %%", dsname.Data(),
                                 GetNFiles(), treeInfo.Data(), xsz, unit[k],
                                 (Int_t)GetStagedPercentage()));
   }
   // Done
   return outs;
}

//______________________________________________________________________________
TFileCollection *TFileCollection::GetFilesOnServer(const char *server)
{
   // Return the subset of files served by 'server'. The sysntax for 'server' is
   // the standard URI one, i.e. [<scheme>://]<host>[:port]

   TFileCollection *fc = (TFileCollection *)0;

   // Server specification is mandatory
   if (!server || strlen(server) <= 0) {
      Info("GetFilesOnServer", "server undefined - do nothing");
      return fc;
   }

   // Nothing to do for empty lists
   if (!fList || fList->GetSize() <= 0) {
      Info("GetFilesOnServer", "the list is empty - do nothing");
      return fc;
   }

   // Define the server reference string
   TUri uri(server);
   TString srv, scheme("root"), port;
   if (uri.GetScheme() != "") scheme = uri.GetScheme();
   if (uri.GetPort() != "") port.Form(":%s", uri.GetPort().Data());
   srv.Form("%s://%s%s", scheme.Data(), TUrl(server).GetHostFQDN(), port.Data());
   if (gDebug > 0)
      Info("GetFilesOnServer", "searching for files on server: '%s' (input: '%s')",
                               srv.Data(), server);

   // Prepare the output
   fc = new TFileCollection(GetName());
   TString title;
   if (GetTitle() && strlen(GetTitle()) > 0) {
      title.Form("%s (subset on server %s)", GetTitle(), srv.Data());
   } else {
      title.Form("subset of '%s' on server %s", GetName(), srv.Data());
   }
   fc->SetTitle(title.Data());
   // The default tree name
   fc->SetDefaultTreeName(GetDefaultTreeName());

   // We look for URL starting with srv
   srv.Insert(0, "^");

   // Go through the list
   TIter nxf(fList);
   TFileInfo *fi = 0;
   while ((fi = (TFileInfo *)nxf())) {
      TUrl *xu = 0;
      if ((xu = fi->FindByUrl(srv.Data()))) {
         // Create a new TFileInfo object
         TFileInfo *nfi = new TFileInfo(xu->GetUrl(), fi->GetSize(),
                                        fi->GetUUID() ? fi->GetUUID()->AsString() : 0,
                                        fi->GetMD5() ? fi->GetMD5()->AsString() : 0);
         if (fi->GetMetaDataList()) {
            TIter nxm(fi->GetMetaDataList());
            TFileInfoMeta *md = 0;
            while ((md = (TFileInfoMeta *) nxm())) {
               nfi->AddMetaData(new TFileInfoMeta(*md));
            }
         }
         if (fi->TestBit(TFileInfo::kStaged)) nfi->SetBit(TFileInfo::kStaged);
         if (fi->TestBit(TFileInfo::kCorrupted)) nfi->SetBit(TFileInfo::kCorrupted);
         if (gDebug > 1)
            Info("GetFilesOnServer", "adding: %s", xu->GetUrl());
         fc->Add(nfi);
      }
   }

   // If nothing found, delete the object
   if (fc->GetList()->GetSize() <= 0) {
      delete fc;
      fc = 0;
      Info("GetFilesOnServer", "dataset '%s' has no files on server: '%s' (searched for: '%s')",
                               GetName(), server, srv.Data());
   }

   // Fill up sums on the sub file collection
   if (fc) {
      fc->Update();
      // Fraction of total in permille
      Long64_t xf = (fc->GetTotalSize() * 1000) / GetTotalSize();
      TFileInfoMeta *m = new TFileInfoMeta("FractionOfTotal", "External Info", xf);
      m->SetBit(TFileInfoMeta::kExternal);
      fc->AddMetaData(m);
   }

   // Done
   return fc;
}

//______________________________________________________________________________
TMap *TFileCollection::GetFilesPerServer(const char *exclude, Bool_t curronly)
{
   // Return a map of TFileCollections with the files on each data server,
   // excluding servers in the comma-separated list 'exclude'.
   // If curronly is kTRUE, only the URL flagged as current in the TFileInfo
   // are considered.

   TMap *dsmap = 0;

   // Nothing to do for empty lists
   if (!fList || fList->GetSize() <= 0) {
      Info("GetFilesPerServer", "the list is empty - do nothing");
      return dsmap;
   }

   // List of servers to be ignored
   THashList *excl = 0;
   if (exclude && strlen(exclude) > 0) {
      excl = new THashList;
      excl->SetOwner();
      TUri uri;
      TString srvs(exclude), s, srv, scheme, port;
      Int_t from = 0;
      while (srvs.Tokenize(s, from, ",")) {
         uri.SetUri(s.Data());
         scheme = "root";
         port = "";
         if (uri.GetScheme() != "") scheme = uri.GetScheme();
         if (uri.GetPort() != "") port.Form(":%s", uri.GetPort().Data());
         srv.Form("%s://%s%s", scheme.Data(), TUrl(s.Data()).GetHostFQDN(), port.Data());
         // Add
         excl->Add(new TObjString(srv.Data()));
      }
   }

   // Prepare the output
   dsmap = new TMap();

   // Go through the list
   TIter nxf(fList);
   TFileInfo *fi = 0;
   TUri uri;
   TString key;
   TFileCollection *fc = 0;
   while ((fi = (TFileInfo *)nxf())) {
      // Save current URL
      TUrl *curl = fi->GetCurrentUrl();
      // Loop over URLs
      if (!curronly) fi->ResetUrl();
      TUrl *xurl = 0;
      while ((xurl = (curronly) ? curl : fi->NextUrl())) {
         // Find the key for this server
         key.Form("%s://%s", xurl->GetProtocol(), xurl->GetHostFQDN());
         // Check if this has to be ignored
         if (excl && excl->FindObject(key.Data())) {
            if (curronly) break;
            continue;
         } else if (excl && xurl->GetPort() > 0) {
            // Complete the key, if needed, and recheck
            key += TString::Format(":%d", xurl->GetPort());
            if (excl->FindObject(key.Data())) {
               if (curronly) break;
               continue;
            }
         }
         // Get the map entry for this key
         TPair *ent = 0;
         if (!(ent = (TPair *) dsmap->FindObject(key.Data()))) {
            // Create the TFileCollection
            fc = new TFileCollection(GetName());
            TString title;
            if (GetTitle() && strlen(GetTitle()) > 0) {
               title.Form("%s (subset on server %s)", GetTitle(), key.Data());
            } else {
               title.Form("subset of '%s' on server %s", GetName(), key.Data());
            }
            fc->SetTitle(title.Data());
            // The default tree name
            fc->SetDefaultTreeName(GetDefaultTreeName());
            // Add it to the map
            dsmap->Add(new TObjString(key.Data()), fc);
            // Notify
            if (gDebug > 0)
               Info("GetFilesPerServer", "found server: '%s' (fc: %p)", key.Data(), fc);
         } else {
            // Attach to the TFileCollection
            fc = (TFileCollection *) ent->Value();
         }
         // Create a new TFileInfo object
         TFileInfo *nfi = new TFileInfo(xurl->GetUrl(kTRUE), fi->GetSize(),
                                        fi->GetUUID() ? fi->GetUUID()->AsString() : 0,
                                        fi->GetMD5() ? fi->GetMD5()->AsString() : 0);
         if (fi->GetMetaDataList()) {
            TIter nxm(fi->GetMetaDataList());
            TFileInfoMeta *md = 0;
            while ((md = (TFileInfoMeta *) nxm())) {
               nfi->AddMetaData(new TFileInfoMeta(*md));
            }
         }
         if (fi->TestBit(TFileInfo::kStaged)) nfi->SetBit(TFileInfo::kStaged);
         if (fi->TestBit(TFileInfo::kCorrupted)) nfi->SetBit(TFileInfo::kCorrupted);
         fc->Add(nfi);
         // In current_only mode we are done
         if (curronly) break;
      }
      // Restore current URL
      fi->SetCurrentUrl(curl);
   }

   // Fill up sums on the sub file collections
   TIter nxk(dsmap);
   TObject *k = 0;
   while ((k = nxk()) && (fc = (TFileCollection *) dsmap->GetValue(k))) {
      fc->Update();
      // Fraction of total in permille
      Long64_t xf = (fc->GetTotalSize() * 1000) / GetTotalSize();
      TFileInfoMeta *m = new TFileInfoMeta("FractionOfTotal", "External Info", xf);
      m->SetBit(TFileInfoMeta::kExternal);
      fc->AddMetaData(m);
   }

   // Cleanup
   if (excl) delete excl;

   // Done
   return dsmap;
}

//______________________________________________________________________________
Bool_t TFileCollection::AddMetaData(TObject *meta)
{
   // Add's a meta data object to the file collection object. The object will be
   // adopted by the TFileCollection and should not be deleted by the user.
   // Typically objects of class TFileInfoMeta or derivatives should be added,
   // but any class is accepted.
   // NB : a call to TFileCollection::Update will remove these objects unless the
   //      bit TFileInfoMeta::kExternal is set.
   // Returns kTRUE if successful, kFALSE otherwise.

   if (meta) {
      if (!fMetaDataList) {
         fMetaDataList = new TList;
         fMetaDataList->SetOwner();
      }
      fMetaDataList->Add(meta);
      return kTRUE;
   }
   return kFALSE;
}
 TFileCollection.cxx:1
 TFileCollection.cxx:2
 TFileCollection.cxx:3
 TFileCollection.cxx:4
 TFileCollection.cxx:5
 TFileCollection.cxx:6
 TFileCollection.cxx:7
 TFileCollection.cxx:8
 TFileCollection.cxx:9
 TFileCollection.cxx:10
 TFileCollection.cxx:11
 TFileCollection.cxx:12
 TFileCollection.cxx:13
 TFileCollection.cxx:14
 TFileCollection.cxx:15
 TFileCollection.cxx:16
 TFileCollection.cxx:17
 TFileCollection.cxx:18
 TFileCollection.cxx:19
 TFileCollection.cxx:20
 TFileCollection.cxx:21
 TFileCollection.cxx:22
 TFileCollection.cxx:23
 TFileCollection.cxx:24
 TFileCollection.cxx:25
 TFileCollection.cxx:26
 TFileCollection.cxx:27
 TFileCollection.cxx:28
 TFileCollection.cxx:29
 TFileCollection.cxx:30
 TFileCollection.cxx:31
 TFileCollection.cxx:32
 TFileCollection.cxx:33
 TFileCollection.cxx:34
 TFileCollection.cxx:35
 TFileCollection.cxx:36
 TFileCollection.cxx:37
 TFileCollection.cxx:38
 TFileCollection.cxx:39
 TFileCollection.cxx:40
 TFileCollection.cxx:41
 TFileCollection.cxx:42
 TFileCollection.cxx:43
 TFileCollection.cxx:44
 TFileCollection.cxx:45
 TFileCollection.cxx:46
 TFileCollection.cxx:47
 TFileCollection.cxx:48
 TFileCollection.cxx:49
 TFileCollection.cxx:50
 TFileCollection.cxx:51
 TFileCollection.cxx:52
 TFileCollection.cxx:53
 TFileCollection.cxx:54
 TFileCollection.cxx:55
 TFileCollection.cxx:56
 TFileCollection.cxx:57
 TFileCollection.cxx:58
 TFileCollection.cxx:59
 TFileCollection.cxx:60
 TFileCollection.cxx:61
 TFileCollection.cxx:62
 TFileCollection.cxx:63
 TFileCollection.cxx:64
 TFileCollection.cxx:65
 TFileCollection.cxx:66
 TFileCollection.cxx:67
 TFileCollection.cxx:68
 TFileCollection.cxx:69
 TFileCollection.cxx:70
 TFileCollection.cxx:71
 TFileCollection.cxx:72
 TFileCollection.cxx:73
 TFileCollection.cxx:74
 TFileCollection.cxx:75
 TFileCollection.cxx:76
 TFileCollection.cxx:77
 TFileCollection.cxx:78
 TFileCollection.cxx:79
 TFileCollection.cxx:80
 TFileCollection.cxx:81
 TFileCollection.cxx:82
 TFileCollection.cxx:83
 TFileCollection.cxx:84
 TFileCollection.cxx:85
 TFileCollection.cxx:86
 TFileCollection.cxx:87
 TFileCollection.cxx:88
 TFileCollection.cxx:89
 TFileCollection.cxx:90
 TFileCollection.cxx:91
 TFileCollection.cxx:92
 TFileCollection.cxx:93
 TFileCollection.cxx:94
 TFileCollection.cxx:95
 TFileCollection.cxx:96
 TFileCollection.cxx:97
 TFileCollection.cxx:98
 TFileCollection.cxx:99
 TFileCollection.cxx:100
 TFileCollection.cxx:101
 TFileCollection.cxx:102
 TFileCollection.cxx:103
 TFileCollection.cxx:104
 TFileCollection.cxx:105
 TFileCollection.cxx:106
 TFileCollection.cxx:107
 TFileCollection.cxx:108
 TFileCollection.cxx:109
 TFileCollection.cxx:110
 TFileCollection.cxx:111
 TFileCollection.cxx:112
 TFileCollection.cxx:113
 TFileCollection.cxx:114
 TFileCollection.cxx:115
 TFileCollection.cxx:116
 TFileCollection.cxx:117
 TFileCollection.cxx:118
 TFileCollection.cxx:119
 TFileCollection.cxx:120
 TFileCollection.cxx:121
 TFileCollection.cxx:122
 TFileCollection.cxx:123
 TFileCollection.cxx:124
 TFileCollection.cxx:125
 TFileCollection.cxx:126
 TFileCollection.cxx:127
 TFileCollection.cxx:128
 TFileCollection.cxx:129
 TFileCollection.cxx:130
 TFileCollection.cxx:131
 TFileCollection.cxx:132
 TFileCollection.cxx:133
 TFileCollection.cxx:134
 TFileCollection.cxx:135
 TFileCollection.cxx:136
 TFileCollection.cxx:137
 TFileCollection.cxx:138
 TFileCollection.cxx:139
 TFileCollection.cxx:140
 TFileCollection.cxx:141
 TFileCollection.cxx:142
 TFileCollection.cxx:143
 TFileCollection.cxx:144
 TFileCollection.cxx:145
 TFileCollection.cxx:146
 TFileCollection.cxx:147
 TFileCollection.cxx:148
 TFileCollection.cxx:149
 TFileCollection.cxx:150
 TFileCollection.cxx:151
 TFileCollection.cxx:152
 TFileCollection.cxx:153
 TFileCollection.cxx:154
 TFileCollection.cxx:155
 TFileCollection.cxx:156
 TFileCollection.cxx:157
 TFileCollection.cxx:158
 TFileCollection.cxx:159
 TFileCollection.cxx:160
 TFileCollection.cxx:161
 TFileCollection.cxx:162
 TFileCollection.cxx:163
 TFileCollection.cxx:164
 TFileCollection.cxx:165
 TFileCollection.cxx:166
 TFileCollection.cxx:167
 TFileCollection.cxx:168
 TFileCollection.cxx:169
 TFileCollection.cxx:170
 TFileCollection.cxx:171
 TFileCollection.cxx:172
 TFileCollection.cxx:173
 TFileCollection.cxx:174
 TFileCollection.cxx:175
 TFileCollection.cxx:176
 TFileCollection.cxx:177
 TFileCollection.cxx:178
 TFileCollection.cxx:179
 TFileCollection.cxx:180
 TFileCollection.cxx:181
 TFileCollection.cxx:182
 TFileCollection.cxx:183
 TFileCollection.cxx:184
 TFileCollection.cxx:185
 TFileCollection.cxx:186
 TFileCollection.cxx:187
 TFileCollection.cxx:188
 TFileCollection.cxx:189
 TFileCollection.cxx:190
 TFileCollection.cxx:191
 TFileCollection.cxx:192
 TFileCollection.cxx:193
 TFileCollection.cxx:194
 TFileCollection.cxx:195
 TFileCollection.cxx:196
 TFileCollection.cxx:197
 TFileCollection.cxx:198
 TFileCollection.cxx:199
 TFileCollection.cxx:200
 TFileCollection.cxx:201
 TFileCollection.cxx:202
 TFileCollection.cxx:203
 TFileCollection.cxx:204
 TFileCollection.cxx:205
 TFileCollection.cxx:206
 TFileCollection.cxx:207
 TFileCollection.cxx:208
 TFileCollection.cxx:209
 TFileCollection.cxx:210
 TFileCollection.cxx:211
 TFileCollection.cxx:212
 TFileCollection.cxx:213
 TFileCollection.cxx:214
 TFileCollection.cxx:215
 TFileCollection.cxx:216
 TFileCollection.cxx:217
 TFileCollection.cxx:218
 TFileCollection.cxx:219
 TFileCollection.cxx:220
 TFileCollection.cxx:221
 TFileCollection.cxx:222
 TFileCollection.cxx:223
 TFileCollection.cxx:224
 TFileCollection.cxx:225
 TFileCollection.cxx:226
 TFileCollection.cxx:227
 TFileCollection.cxx:228
 TFileCollection.cxx:229
 TFileCollection.cxx:230
 TFileCollection.cxx:231
 TFileCollection.cxx:232
 TFileCollection.cxx:233
 TFileCollection.cxx:234
 TFileCollection.cxx:235
 TFileCollection.cxx:236
 TFileCollection.cxx:237
 TFileCollection.cxx:238
 TFileCollection.cxx:239
 TFileCollection.cxx:240
 TFileCollection.cxx:241
 TFileCollection.cxx:242
 TFileCollection.cxx:243
 TFileCollection.cxx:244
 TFileCollection.cxx:245
 TFileCollection.cxx:246
 TFileCollection.cxx:247
 TFileCollection.cxx:248
 TFileCollection.cxx:249
 TFileCollection.cxx:250
 TFileCollection.cxx:251
 TFileCollection.cxx:252
 TFileCollection.cxx:253
 TFileCollection.cxx:254
 TFileCollection.cxx:255
 TFileCollection.cxx:256
 TFileCollection.cxx:257
 TFileCollection.cxx:258
 TFileCollection.cxx:259
 TFileCollection.cxx:260
 TFileCollection.cxx:261
 TFileCollection.cxx:262
 TFileCollection.cxx:263
 TFileCollection.cxx:264
 TFileCollection.cxx:265
 TFileCollection.cxx:266
 TFileCollection.cxx:267
 TFileCollection.cxx:268
 TFileCollection.cxx:269
 TFileCollection.cxx:270
 TFileCollection.cxx:271
 TFileCollection.cxx:272
 TFileCollection.cxx:273
 TFileCollection.cxx:274
 TFileCollection.cxx:275
 TFileCollection.cxx:276
 TFileCollection.cxx:277
 TFileCollection.cxx:278
 TFileCollection.cxx:279
 TFileCollection.cxx:280
 TFileCollection.cxx:281
 TFileCollection.cxx:282
 TFileCollection.cxx:283
 TFileCollection.cxx:284
 TFileCollection.cxx:285
 TFileCollection.cxx:286
 TFileCollection.cxx:287
 TFileCollection.cxx:288
 TFileCollection.cxx:289
 TFileCollection.cxx:290
 TFileCollection.cxx:291
 TFileCollection.cxx:292
 TFileCollection.cxx:293
 TFileCollection.cxx:294
 TFileCollection.cxx:295
 TFileCollection.cxx:296
 TFileCollection.cxx:297
 TFileCollection.cxx:298
 TFileCollection.cxx:299
 TFileCollection.cxx:300
 TFileCollection.cxx:301
 TFileCollection.cxx:302
 TFileCollection.cxx:303
 TFileCollection.cxx:304
 TFileCollection.cxx:305
 TFileCollection.cxx:306
 TFileCollection.cxx:307
 TFileCollection.cxx:308
 TFileCollection.cxx:309
 TFileCollection.cxx:310
 TFileCollection.cxx:311
 TFileCollection.cxx:312
 TFileCollection.cxx:313
 TFileCollection.cxx:314
 TFileCollection.cxx:315
 TFileCollection.cxx:316
 TFileCollection.cxx:317
 TFileCollection.cxx:318
 TFileCollection.cxx:319
 TFileCollection.cxx:320
 TFileCollection.cxx:321
 TFileCollection.cxx:322
 TFileCollection.cxx:323
 TFileCollection.cxx:324
 TFileCollection.cxx:325
 TFileCollection.cxx:326
 TFileCollection.cxx:327
 TFileCollection.cxx:328
 TFileCollection.cxx:329
 TFileCollection.cxx:330
 TFileCollection.cxx:331
 TFileCollection.cxx:332
 TFileCollection.cxx:333
 TFileCollection.cxx:334
 TFileCollection.cxx:335
 TFileCollection.cxx:336
 TFileCollection.cxx:337
 TFileCollection.cxx:338
 TFileCollection.cxx:339
 TFileCollection.cxx:340
 TFileCollection.cxx:341
 TFileCollection.cxx:342
 TFileCollection.cxx:343
 TFileCollection.cxx:344
 TFileCollection.cxx:345
 TFileCollection.cxx:346
 TFileCollection.cxx:347
 TFileCollection.cxx:348
 TFileCollection.cxx:349
 TFileCollection.cxx:350
 TFileCollection.cxx:351
 TFileCollection.cxx:352
 TFileCollection.cxx:353
 TFileCollection.cxx:354
 TFileCollection.cxx:355
 TFileCollection.cxx:356
 TFileCollection.cxx:357
 TFileCollection.cxx:358
 TFileCollection.cxx:359
 TFileCollection.cxx:360
 TFileCollection.cxx:361
 TFileCollection.cxx:362
 TFileCollection.cxx:363
 TFileCollection.cxx:364
 TFileCollection.cxx:365
 TFileCollection.cxx:366
 TFileCollection.cxx:367
 TFileCollection.cxx:368
 TFileCollection.cxx:369
 TFileCollection.cxx:370
 TFileCollection.cxx:371
 TFileCollection.cxx:372
 TFileCollection.cxx:373
 TFileCollection.cxx:374
 TFileCollection.cxx:375
 TFileCollection.cxx:376
 TFileCollection.cxx:377
 TFileCollection.cxx:378
 TFileCollection.cxx:379
 TFileCollection.cxx:380
 TFileCollection.cxx:381
 TFileCollection.cxx:382
 TFileCollection.cxx:383
 TFileCollection.cxx:384
 TFileCollection.cxx:385
 TFileCollection.cxx:386
 TFileCollection.cxx:387
 TFileCollection.cxx:388
 TFileCollection.cxx:389
 TFileCollection.cxx:390
 TFileCollection.cxx:391
 TFileCollection.cxx:392
 TFileCollection.cxx:393
 TFileCollection.cxx:394
 TFileCollection.cxx:395
 TFileCollection.cxx:396
 TFileCollection.cxx:397
 TFileCollection.cxx:398
 TFileCollection.cxx:399
 TFileCollection.cxx:400
 TFileCollection.cxx:401
 TFileCollection.cxx:402
 TFileCollection.cxx:403
 TFileCollection.cxx:404
 TFileCollection.cxx:405
 TFileCollection.cxx:406
 TFileCollection.cxx:407
 TFileCollection.cxx:408
 TFileCollection.cxx:409
 TFileCollection.cxx:410
 TFileCollection.cxx:411
 TFileCollection.cxx:412
 TFileCollection.cxx:413
 TFileCollection.cxx:414
 TFileCollection.cxx:415
 TFileCollection.cxx:416
 TFileCollection.cxx:417
 TFileCollection.cxx:418
 TFileCollection.cxx:419
 TFileCollection.cxx:420
 TFileCollection.cxx:421
 TFileCollection.cxx:422
 TFileCollection.cxx:423
 TFileCollection.cxx:424
 TFileCollection.cxx:425
 TFileCollection.cxx:426
 TFileCollection.cxx:427
 TFileCollection.cxx:428
 TFileCollection.cxx:429
 TFileCollection.cxx:430
 TFileCollection.cxx:431
 TFileCollection.cxx:432
 TFileCollection.cxx:433
 TFileCollection.cxx:434
 TFileCollection.cxx:435
 TFileCollection.cxx:436
 TFileCollection.cxx:437
 TFileCollection.cxx:438
 TFileCollection.cxx:439
 TFileCollection.cxx:440
 TFileCollection.cxx:441
 TFileCollection.cxx:442
 TFileCollection.cxx:443
 TFileCollection.cxx:444
 TFileCollection.cxx:445
 TFileCollection.cxx:446
 TFileCollection.cxx:447
 TFileCollection.cxx:448
 TFileCollection.cxx:449
 TFileCollection.cxx:450
 TFileCollection.cxx:451
 TFileCollection.cxx:452
 TFileCollection.cxx:453
 TFileCollection.cxx:454
 TFileCollection.cxx:455
 TFileCollection.cxx:456
 TFileCollection.cxx:457
 TFileCollection.cxx:458
 TFileCollection.cxx:459
 TFileCollection.cxx:460
 TFileCollection.cxx:461
 TFileCollection.cxx:462
 TFileCollection.cxx:463
 TFileCollection.cxx:464
 TFileCollection.cxx:465
 TFileCollection.cxx:466
 TFileCollection.cxx:467
 TFileCollection.cxx:468
 TFileCollection.cxx:469
 TFileCollection.cxx:470
 TFileCollection.cxx:471
 TFileCollection.cxx:472
 TFileCollection.cxx:473
 TFileCollection.cxx:474
 TFileCollection.cxx:475
 TFileCollection.cxx:476
 TFileCollection.cxx:477
 TFileCollection.cxx:478
 TFileCollection.cxx:479
 TFileCollection.cxx:480
 TFileCollection.cxx:481
 TFileCollection.cxx:482
 TFileCollection.cxx:483
 TFileCollection.cxx:484
 TFileCollection.cxx:485
 TFileCollection.cxx:486
 TFileCollection.cxx:487
 TFileCollection.cxx:488
 TFileCollection.cxx:489
 TFileCollection.cxx:490
 TFileCollection.cxx:491
 TFileCollection.cxx:492
 TFileCollection.cxx:493
 TFileCollection.cxx:494
 TFileCollection.cxx:495
 TFileCollection.cxx:496
 TFileCollection.cxx:497
 TFileCollection.cxx:498
 TFileCollection.cxx:499
 TFileCollection.cxx:500
 TFileCollection.cxx:501
 TFileCollection.cxx:502
 TFileCollection.cxx:503
 TFileCollection.cxx:504
 TFileCollection.cxx:505
 TFileCollection.cxx:506
 TFileCollection.cxx:507
 TFileCollection.cxx:508
 TFileCollection.cxx:509
 TFileCollection.cxx:510
 TFileCollection.cxx:511
 TFileCollection.cxx:512
 TFileCollection.cxx:513
 TFileCollection.cxx:514
 TFileCollection.cxx:515
 TFileCollection.cxx:516
 TFileCollection.cxx:517
 TFileCollection.cxx:518
 TFileCollection.cxx:519
 TFileCollection.cxx:520
 TFileCollection.cxx:521
 TFileCollection.cxx:522
 TFileCollection.cxx:523
 TFileCollection.cxx:524
 TFileCollection.cxx:525
 TFileCollection.cxx:526
 TFileCollection.cxx:527
 TFileCollection.cxx:528
 TFileCollection.cxx:529
 TFileCollection.cxx:530
 TFileCollection.cxx:531
 TFileCollection.cxx:532
 TFileCollection.cxx:533
 TFileCollection.cxx:534
 TFileCollection.cxx:535
 TFileCollection.cxx:536
 TFileCollection.cxx:537
 TFileCollection.cxx:538
 TFileCollection.cxx:539
 TFileCollection.cxx:540
 TFileCollection.cxx:541
 TFileCollection.cxx:542
 TFileCollection.cxx:543
 TFileCollection.cxx:544
 TFileCollection.cxx:545
 TFileCollection.cxx:546
 TFileCollection.cxx:547
 TFileCollection.cxx:548
 TFileCollection.cxx:549
 TFileCollection.cxx:550
 TFileCollection.cxx:551
 TFileCollection.cxx:552
 TFileCollection.cxx:553
 TFileCollection.cxx:554
 TFileCollection.cxx:555
 TFileCollection.cxx:556
 TFileCollection.cxx:557
 TFileCollection.cxx:558
 TFileCollection.cxx:559
 TFileCollection.cxx:560
 TFileCollection.cxx:561
 TFileCollection.cxx:562
 TFileCollection.cxx:563
 TFileCollection.cxx:564
 TFileCollection.cxx:565
 TFileCollection.cxx:566
 TFileCollection.cxx:567
 TFileCollection.cxx:568
 TFileCollection.cxx:569
 TFileCollection.cxx:570
 TFileCollection.cxx:571
 TFileCollection.cxx:572
 TFileCollection.cxx:573
 TFileCollection.cxx:574
 TFileCollection.cxx:575
 TFileCollection.cxx:576
 TFileCollection.cxx:577
 TFileCollection.cxx:578
 TFileCollection.cxx:579
 TFileCollection.cxx:580
 TFileCollection.cxx:581
 TFileCollection.cxx:582
 TFileCollection.cxx:583
 TFileCollection.cxx:584
 TFileCollection.cxx:585
 TFileCollection.cxx:586
 TFileCollection.cxx:587
 TFileCollection.cxx:588
 TFileCollection.cxx:589
 TFileCollection.cxx:590
 TFileCollection.cxx:591
 TFileCollection.cxx:592
 TFileCollection.cxx:593
 TFileCollection.cxx:594
 TFileCollection.cxx:595
 TFileCollection.cxx:596
 TFileCollection.cxx:597
 TFileCollection.cxx:598
 TFileCollection.cxx:599
 TFileCollection.cxx:600
 TFileCollection.cxx:601
 TFileCollection.cxx:602
 TFileCollection.cxx:603
 TFileCollection.cxx:604
 TFileCollection.cxx:605
 TFileCollection.cxx:606
 TFileCollection.cxx:607
 TFileCollection.cxx:608
 TFileCollection.cxx:609
 TFileCollection.cxx:610
 TFileCollection.cxx:611
 TFileCollection.cxx:612
 TFileCollection.cxx:613
 TFileCollection.cxx:614
 TFileCollection.cxx:615
 TFileCollection.cxx:616
 TFileCollection.cxx:617
 TFileCollection.cxx:618
 TFileCollection.cxx:619
 TFileCollection.cxx:620
 TFileCollection.cxx:621
 TFileCollection.cxx:622
 TFileCollection.cxx:623
 TFileCollection.cxx:624
 TFileCollection.cxx:625
 TFileCollection.cxx:626
 TFileCollection.cxx:627
 TFileCollection.cxx:628
 TFileCollection.cxx:629
 TFileCollection.cxx:630
 TFileCollection.cxx:631
 TFileCollection.cxx:632
 TFileCollection.cxx:633
 TFileCollection.cxx:634
 TFileCollection.cxx:635
 TFileCollection.cxx:636
 TFileCollection.cxx:637
 TFileCollection.cxx:638
 TFileCollection.cxx:639
 TFileCollection.cxx:640
 TFileCollection.cxx:641
 TFileCollection.cxx:642
 TFileCollection.cxx:643
 TFileCollection.cxx:644
 TFileCollection.cxx:645
 TFileCollection.cxx:646
 TFileCollection.cxx:647
 TFileCollection.cxx:648
 TFileCollection.cxx:649
 TFileCollection.cxx:650
 TFileCollection.cxx:651
 TFileCollection.cxx:652
 TFileCollection.cxx:653
 TFileCollection.cxx:654
 TFileCollection.cxx:655
 TFileCollection.cxx:656
 TFileCollection.cxx:657
 TFileCollection.cxx:658
 TFileCollection.cxx:659
 TFileCollection.cxx:660
 TFileCollection.cxx:661
 TFileCollection.cxx:662
 TFileCollection.cxx:663
 TFileCollection.cxx:664
 TFileCollection.cxx:665
 TFileCollection.cxx:666
 TFileCollection.cxx:667
 TFileCollection.cxx:668
 TFileCollection.cxx:669
 TFileCollection.cxx:670
 TFileCollection.cxx:671
 TFileCollection.cxx:672
 TFileCollection.cxx:673
 TFileCollection.cxx:674
 TFileCollection.cxx:675
 TFileCollection.cxx:676
 TFileCollection.cxx:677
 TFileCollection.cxx:678
 TFileCollection.cxx:679
 TFileCollection.cxx:680
 TFileCollection.cxx:681
 TFileCollection.cxx:682
 TFileCollection.cxx:683
 TFileCollection.cxx:684
 TFileCollection.cxx:685
 TFileCollection.cxx:686
 TFileCollection.cxx:687
 TFileCollection.cxx:688
 TFileCollection.cxx:689
 TFileCollection.cxx:690
 TFileCollection.cxx:691
 TFileCollection.cxx:692
 TFileCollection.cxx:693
 TFileCollection.cxx:694
 TFileCollection.cxx:695
 TFileCollection.cxx:696
 TFileCollection.cxx:697
 TFileCollection.cxx:698
 TFileCollection.cxx:699
 TFileCollection.cxx:700
 TFileCollection.cxx:701
 TFileCollection.cxx:702
 TFileCollection.cxx:703
 TFileCollection.cxx:704
 TFileCollection.cxx:705
 TFileCollection.cxx:706
 TFileCollection.cxx:707
 TFileCollection.cxx:708
 TFileCollection.cxx:709
 TFileCollection.cxx:710
 TFileCollection.cxx:711
 TFileCollection.cxx:712
 TFileCollection.cxx:713
 TFileCollection.cxx:714
 TFileCollection.cxx:715
 TFileCollection.cxx:716
 TFileCollection.cxx:717
 TFileCollection.cxx:718
 TFileCollection.cxx:719
 TFileCollection.cxx:720
 TFileCollection.cxx:721
 TFileCollection.cxx:722
 TFileCollection.cxx:723
 TFileCollection.cxx:724
 TFileCollection.cxx:725
 TFileCollection.cxx:726
 TFileCollection.cxx:727
 TFileCollection.cxx:728
 TFileCollection.cxx:729
 TFileCollection.cxx:730
 TFileCollection.cxx:731
 TFileCollection.cxx:732
 TFileCollection.cxx:733
 TFileCollection.cxx:734
 TFileCollection.cxx:735
 TFileCollection.cxx:736
 TFileCollection.cxx:737
 TFileCollection.cxx:738
 TFileCollection.cxx:739
 TFileCollection.cxx:740
 TFileCollection.cxx:741
 TFileCollection.cxx:742
 TFileCollection.cxx:743
 TFileCollection.cxx:744
 TFileCollection.cxx:745
 TFileCollection.cxx:746
 TFileCollection.cxx:747
 TFileCollection.cxx:748
 TFileCollection.cxx:749
 TFileCollection.cxx:750
 TFileCollection.cxx:751
 TFileCollection.cxx:752
 TFileCollection.cxx:753
 TFileCollection.cxx:754
 TFileCollection.cxx:755
 TFileCollection.cxx:756
 TFileCollection.cxx:757
 TFileCollection.cxx:758
 TFileCollection.cxx:759
 TFileCollection.cxx:760
 TFileCollection.cxx:761
 TFileCollection.cxx:762
 TFileCollection.cxx:763
 TFileCollection.cxx:764
 TFileCollection.cxx:765
 TFileCollection.cxx:766
 TFileCollection.cxx:767
 TFileCollection.cxx:768
 TFileCollection.cxx:769
 TFileCollection.cxx:770
 TFileCollection.cxx:771
 TFileCollection.cxx:772
 TFileCollection.cxx:773
 TFileCollection.cxx:774
 TFileCollection.cxx:775
 TFileCollection.cxx:776
 TFileCollection.cxx:777
 TFileCollection.cxx:778
 TFileCollection.cxx:779
 TFileCollection.cxx:780
 TFileCollection.cxx:781
 TFileCollection.cxx:782
 TFileCollection.cxx:783
 TFileCollection.cxx:784
 TFileCollection.cxx:785
 TFileCollection.cxx:786
 TFileCollection.cxx:787
 TFileCollection.cxx:788
 TFileCollection.cxx:789
 TFileCollection.cxx:790
 TFileCollection.cxx:791
 TFileCollection.cxx:792
 TFileCollection.cxx:793
 TFileCollection.cxx:794
 TFileCollection.cxx:795
 TFileCollection.cxx:796
 TFileCollection.cxx:797
 TFileCollection.cxx:798
 TFileCollection.cxx:799
 TFileCollection.cxx:800
 TFileCollection.cxx:801
 TFileCollection.cxx:802
 TFileCollection.cxx:803
 TFileCollection.cxx:804
 TFileCollection.cxx:805
 TFileCollection.cxx:806
 TFileCollection.cxx:807
 TFileCollection.cxx:808
 TFileCollection.cxx:809
 TFileCollection.cxx:810
 TFileCollection.cxx:811
 TFileCollection.cxx:812
 TFileCollection.cxx:813
 TFileCollection.cxx:814
 TFileCollection.cxx:815
 TFileCollection.cxx:816
 TFileCollection.cxx:817
 TFileCollection.cxx:818
 TFileCollection.cxx:819
 TFileCollection.cxx:820
 TFileCollection.cxx:821
 TFileCollection.cxx:822
 TFileCollection.cxx:823
 TFileCollection.cxx:824
 TFileCollection.cxx:825
 TFileCollection.cxx:826
 TFileCollection.cxx:827
 TFileCollection.cxx:828
 TFileCollection.cxx:829
 TFileCollection.cxx:830
 TFileCollection.cxx:831
 TFileCollection.cxx:832
 TFileCollection.cxx:833
 TFileCollection.cxx:834
 TFileCollection.cxx:835
 TFileCollection.cxx:836
 TFileCollection.cxx:837
 TFileCollection.cxx:838
 TFileCollection.cxx:839
 TFileCollection.cxx:840
 TFileCollection.cxx:841
 TFileCollection.cxx:842
 TFileCollection.cxx:843
 TFileCollection.cxx:844
 TFileCollection.cxx:845
 TFileCollection.cxx:846
 TFileCollection.cxx:847
 TFileCollection.cxx:848
 TFileCollection.cxx:849
 TFileCollection.cxx:850
 TFileCollection.cxx:851
 TFileCollection.cxx:852
 TFileCollection.cxx:853
 TFileCollection.cxx:854
 TFileCollection.cxx:855
 TFileCollection.cxx:856
 TFileCollection.cxx:857
 TFileCollection.cxx:858
 TFileCollection.cxx:859
 TFileCollection.cxx:860
 TFileCollection.cxx:861
 TFileCollection.cxx:862
 TFileCollection.cxx:863
 TFileCollection.cxx:864
 TFileCollection.cxx:865
 TFileCollection.cxx:866
 TFileCollection.cxx:867
 TFileCollection.cxx:868
 TFileCollection.cxx:869
 TFileCollection.cxx:870
 TFileCollection.cxx:871
 TFileCollection.cxx:872
 TFileCollection.cxx:873
 TFileCollection.cxx:874
 TFileCollection.cxx:875
 TFileCollection.cxx:876
 TFileCollection.cxx:877
 TFileCollection.cxx:878
 TFileCollection.cxx:879
 TFileCollection.cxx:880
 TFileCollection.cxx:881
 TFileCollection.cxx:882
 TFileCollection.cxx:883
 TFileCollection.cxx:884
 TFileCollection.cxx:885
 TFileCollection.cxx:886
 TFileCollection.cxx:887
 TFileCollection.cxx:888
 TFileCollection.cxx:889
 TFileCollection.cxx:890
 TFileCollection.cxx:891
 TFileCollection.cxx:892
 TFileCollection.cxx:893
 TFileCollection.cxx:894
 TFileCollection.cxx:895
 TFileCollection.cxx:896
 TFileCollection.cxx:897
 TFileCollection.cxx:898
 TFileCollection.cxx:899
 TFileCollection.cxx:900
 TFileCollection.cxx:901
 TFileCollection.cxx:902
 TFileCollection.cxx:903
 TFileCollection.cxx:904
 TFileCollection.cxx:905
 TFileCollection.cxx:906
 TFileCollection.cxx:907
 TFileCollection.cxx:908
 TFileCollection.cxx:909
 TFileCollection.cxx:910
 TFileCollection.cxx:911
 TFileCollection.cxx:912
 TFileCollection.cxx:913
 TFileCollection.cxx:914
 TFileCollection.cxx:915
 TFileCollection.cxx:916
 TFileCollection.cxx:917
 TFileCollection.cxx:918
 TFileCollection.cxx:919
 TFileCollection.cxx:920
 TFileCollection.cxx:921
 TFileCollection.cxx:922
 TFileCollection.cxx:923
 TFileCollection.cxx:924
 TFileCollection.cxx:925
 TFileCollection.cxx:926
 TFileCollection.cxx:927
 TFileCollection.cxx:928
 TFileCollection.cxx:929
 TFileCollection.cxx:930
 TFileCollection.cxx:931
 TFileCollection.cxx:932
 TFileCollection.cxx:933
 TFileCollection.cxx:934
 TFileCollection.cxx:935
 TFileCollection.cxx:936
 TFileCollection.cxx:937
 TFileCollection.cxx:938
 TFileCollection.cxx:939
 TFileCollection.cxx:940
 TFileCollection.cxx:941
 TFileCollection.cxx:942
 TFileCollection.cxx:943
 TFileCollection.cxx:944
 TFileCollection.cxx:945
 TFileCollection.cxx:946
 TFileCollection.cxx:947
 TFileCollection.cxx:948
 TFileCollection.cxx:949
 TFileCollection.cxx:950
 TFileCollection.cxx:951
 TFileCollection.cxx:952
 TFileCollection.cxx:953
 TFileCollection.cxx:954
 TFileCollection.cxx:955
 TFileCollection.cxx:956
 TFileCollection.cxx:957
 TFileCollection.cxx:958
 TFileCollection.cxx:959
 TFileCollection.cxx:960
 TFileCollection.cxx:961
 TFileCollection.cxx:962
 TFileCollection.cxx:963
 TFileCollection.cxx:964
 TFileCollection.cxx:965
 TFileCollection.cxx:966
 TFileCollection.cxx:967
 TFileCollection.cxx:968
 TFileCollection.cxx:969
 TFileCollection.cxx:970
 TFileCollection.cxx:971
 TFileCollection.cxx:972
 TFileCollection.cxx:973
 TFileCollection.cxx:974
 TFileCollection.cxx:975
 TFileCollection.cxx:976
 TFileCollection.cxx:977
 TFileCollection.cxx:978
 TFileCollection.cxx:979
 TFileCollection.cxx:980
 TFileCollection.cxx:981
 TFileCollection.cxx:982
 TFileCollection.cxx:983
 TFileCollection.cxx:984
 TFileCollection.cxx:985
 TFileCollection.cxx:986
 TFileCollection.cxx:987
 TFileCollection.cxx:988
 TFileCollection.cxx:989
 TFileCollection.cxx:990
 TFileCollection.cxx:991
 TFileCollection.cxx:992
 TFileCollection.cxx:993
 TFileCollection.cxx:994
 TFileCollection.cxx:995
 TFileCollection.cxx:996
 TFileCollection.cxx:997
 TFileCollection.cxx:998
 TFileCollection.cxx:999
 TFileCollection.cxx:1000
 TFileCollection.cxx:1001