ROOT logo
// @(#)root/tree:$Id: TBranchBrowsable.cxx 27086 2009-01-05 17:20:57Z pcanal $
// Author: Axel Naumann   14/10/2004

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

#include "TBranchBrowsable.h"
#include "TBranchElement.h"
#include "TBranchObject.h"
#include "TMethod.h"
#include "TBrowser.h"
#include "TTree.h"
#include "TLeafObject.h"
#include "TClonesArray.h"
#include "TVirtualPad.h"
#include "TClass.h"
#include "TBaseClass.h"
#include "TDataMember.h"
#include "TStreamerInfo.h"
#include "TStreamerElement.h"
#include "TVirtualCollectionProxy.h"
#include "TRef.h"
#include <algorithm>

R__EXTERN TTree *gTree;

ClassImp(TVirtualBranchBrowsable);

//______________________________________________________________________________
//
// TVirtualBranchBrowsable is a base class (not really abstract, but useless
// by itself) for helper objects that extend TBranch's browsing support.
// Each registered derived class's generator method is called, which fills
// all created helper objects into a list which can then be browsed.
// For details of what these browser helper objects can do, see e.g. 
// TMethodBrowsable, which allows methods to show up in the TBrowser.
//
// Only registered helper objects are created. By default, only 
// TMethodBrowsable, TNonSplitBrowsable, and TCollectionPropertyBrowsable
// are registered (see RegisterDefaultGenerators). You can prevent any of 
// their objects to show up in the browser by unregistering the generator:
//   TMethodBrowsable::Unregister()
// will stop creating browsable method helper objects from that call on.
// Note that these helper objects are cached (in TBranch::fBrowsables);
// already created (and thus cached) browsables will still appear in the
// browser even after unregistering the corresponding generator.
//
// You can implement your own browsable objects and thier generator; see
// e.g. the simple TCollectionPropertyBrowsable. Note that you will have
// to register your generator just like any other, and that you should 
// implement the following methods for your own class, mainly for 
// consistency reasons:
//   static void Register() { 
//     TVirtualBranchBrowsable::RegisterGenerator(GetBrowsables); }
//   static void Unregister() { 
//     TVirtualBranchBrowsable::UnregisterGenerator(GetBrowsables); }
// where GetBrowsables is a static member function of your class, that 
// creates the browsable helper objects, and has the signature
//   static Int_t GetBrowsables(TList& list, const TBranch* branch,
//                              const TVirtualBranchBrowsable* parent=0);
// It has to return the number of browsable helper objects for parent
// (or, if NULL, for branch) which are added to the list.
//______________________________________________________________________________

std::list<TVirtualBranchBrowsable::MethodCreateListOfBrowsables_t> 
   TVirtualBranchBrowsable::fgGenerators;
Bool_t TVirtualBranchBrowsable::fgGeneratorsSet=kFALSE;

//______________________________________________________________________________
TVirtualBranchBrowsable::TVirtualBranchBrowsable(const TBranch* branch, TClass* type, 
                                                 Bool_t typeIsPointer, 
                                                 const TVirtualBranchBrowsable* parent /*=0*/):
fBranch(branch), fParent(parent), fLeaves(0), fClass(type), fTypeIsPointer(typeIsPointer) 
{
   // constructor setting all members according to parameters.
   if (!fgGeneratorsSet) RegisterDefaultGenerators();
   if (!branch) 
      Warning("TVirtualBranchBrowsable", "branch is NULL!");
}

//______________________________________________________________________________
TVirtualBranchBrowsable::~TVirtualBranchBrowsable() 
{
   // Destructor. Delete our leaves.
   delete fLeaves;
}

//______________________________________________________________________________
void TVirtualBranchBrowsable::Browse(TBrowser *b) 
{
// Calls TTree::Draw on the method if return type is not a class;
// otherwise expands returned object's "folder"

   if (!fClass) {
      TString name;
      GetScope(name);

      // If this is meant to be run on the collection
      // we need to "move" the "@" from branch.@member
      // to branch@.member
      name.ReplaceAll(".@","@.");
      name.ReplaceAll("->@","@->");

      TTree* tree=0;
      if (!fBranch) {
         Warning("Browse", "branch not set - might access wrong tree!");
         tree=gTree;
      } else tree=fBranch->GetTree();
      tree->Draw(name, "", b ? b->GetDrawOption() : "");
      if (gPad) gPad->Update();
   } else 
      if (GetLeaves()) GetLeaves()->Browse(b);
}

//______________________________________________________________________________
Int_t TVirtualBranchBrowsable::FillListOfBrowsables(TList& li, const TBranch* branch, 
   const TVirtualBranchBrowsable* parent /* =0 */) 
{
// Askes all registered generators to fill their browsables into
// the list. The browsables are generated for a given parent,
// or (if 0), for a given branch. The branch is passed down to
// leaves of TVirtualBranchBrowsable, too, as we need to access
// the branch's TTree to be able to traw.
   if (!fgGeneratorsSet) RegisterDefaultGenerators();
   std::list<MethodCreateListOfBrowsables_t>::iterator iGenerator;
   Int_t numCreated=0;
   for (iGenerator=fgGenerators.begin(); iGenerator!=fgGenerators.end(); iGenerator++)
      numCreated+=(*(*iGenerator))(li, branch, parent);
   return numCreated;
}

//______________________________________________________________________________
TClass* TVirtualBranchBrowsable::GetCollectionContainedType(const TBranch* branch, 
                                                            const TVirtualBranchBrowsable* parent,
                                                            TClass* &contained) 
{
// Check whether the branch (or the parent) contains a collection. 
// If it does, set "contained" to the contained type (if we can 
// retrieve it) and return the TClass for the collection. Set 
// "contained" to the branch's (or parent's) contained object's 
// class for non-collections, returning 0.
//
// Only one of "branch" or "parent" can ge given (depending on whether
// we are creating browsable objects for a branch or for another
// browsable object)
   contained=0;
   TClass* type=0;
   if (parent)
      type=parent->GetClassType();
   else if (branch) {
      if (branch->IsA()==TBranchElement::Class()) {
         // could be a split TClonesArray
         TBranchElement* be=(TBranchElement*) branch;

         // this is the contained type - if !=0
         const char* clonesname=be->GetClonesName();
         if (clonesname && strlen(clonesname))
            contained=TClass::GetClass(clonesname);

         // check if we're in a sub-branch of this class
         // we can only find out asking the streamer given our ID
         ULong_t *elems=0;
         TStreamerElement *element=0;
         if (be->GetID()>=0 && be->GetInfo() 
            && ((elems=be->GetInfo()->GetElems()))
            && ((element=(TStreamerElement *)elems[be->GetID()]))) {
            // if contained is set (i.e. GetClonesName was successful),
            // this element containes the container, otherwise it's the 
            // contained
            if (contained)
               // we have all we need
               return element->GetClassPointer();
            else 
               type=element->GetClassPointer();
         } else if (clonesname && strlen(clonesname)) {
            // we have a clones name, and the TCA is not split:
            contained=TClass::GetClass(clonesname);
            return TClass::GetClass(be->GetClassName());
         } else 
            type=TClass::GetClass(be->GetClassName());
      } else if (branch->IsA()==TBranchObject::Class()) {
         // could be an unsplit TClonesArray
         TBranchObject* bo=(TBranchObject*)branch;
         const char* clonesname=bo->GetClassName();
         contained=0;
         if (!clonesname || !strlen(clonesname)) return 0;
         type=TClass::GetClass(clonesname);
      }
   } else {
      if (gTree) gTree->Warning("GetCollectionContainedType", "Neither branch nor parent given!");
      return 0;
   }

   if (!type) return 0;

   TBranch* branchNonCost=const_cast<TBranch*>(branch);
   if (type->InheritsFrom(TClonesArray::Class()) 
      && branch->IsA()==TBranchObject::Class()
      && branchNonCost->GetListOfLeaves()
      && branchNonCost->GetListOfLeaves()->GetEntriesFast()==1) {
      // load first entry of the branch. Yes, this is bad, and might have
      // unexpected side effects for the user, esp as already looking at
      // (and not just drawing) a branch triggeres it.
      // To prove just how ugly it is, we'll also have to const_cast the
      // branch...
      if (branch->GetReadEntry()==-1) branchNonCost->GetEntry(0);
      // now get element
      TLeafObject* lo=(TLeafObject*)branchNonCost->GetListOfLeaves()->First();
      TObject* objContainer=lo->GetObject();
      if (lo && objContainer && objContainer->IsA()==TClonesArray::Class())
         contained=((TClonesArray*)objContainer)->GetClass();
      return type;
   } else    if (type->InheritsFrom(TClonesArray::Class()) 
      && branch->IsA()==TBranchElement::Class()
      && branchNonCost->GetListOfLeaves()
      && branchNonCost->GetListOfLeaves()->GetEntriesFast()==1) {
      // load first entry of the branch. Yes, this is bad, and might have
      // unexpected side effects for the user, esp as already looking at
      // (and not just drawing) a branch triggeres it.
      // To prove just how ugly it is, we'll also have to const_cast the
      // branch...
      
      //if (branch->GetReadEntry()==-1) branchNonCost->GetEntry(0);
      // now get element
      //TLeafObject* lo=(TLeafElement*)branchNonCost->GetListOfLeaves()->First();
      //TObject* objContainer=(TObject*)((TBranchElement*)branch)->GetValuePointer();

      //if (objContainer && objContainer->IsA()==TClonesArray::Class())
      //   contained=((TClonesArray*)objContainer)->GetClass();

      // Currently we can peer into the nested TClonesArray, we need
      // to update TBranchElement::GetValuePointer.
      return type;
   } else if (type->InheritsFrom(TCollection::Class())) {
      // some other container, and we don't know what the contained type is
      return type;
   } else if (type->GetCollectionProxy()) {
      contained=type->GetCollectionProxy()->GetValueClass();
      return type;
   } else if (type->InheritsFrom(TRef::Class()))
      // we don't do TRefs, so return contained and container as 0
      return 0;
   else contained=type;
   return 0;
}

//______________________________________________________________________________
TList* TVirtualBranchBrowsable::GetLeaves() const 
{
// Return list of leaves. If not set up yet we'll create them.
   if (!fLeaves) {
      TList* leaves=new TList();
      leaves->SetOwner();
      FillListOfBrowsables(*leaves, GetBranch(), this);
      const_cast<TVirtualBranchBrowsable*>(this)->fLeaves=leaves;
   }
   return fLeaves; 
}

//______________________________________________________________________________
std::list<TVirtualBranchBrowsable::MethodCreateListOfBrowsables_t>& TVirtualBranchBrowsable::GetRegisteredGenerators() 
{
   // returns the list of registered generator methods
   return fgGenerators;
}

//______________________________________________________________________________
void TVirtualBranchBrowsable::GetScope(TString & scope) const 
{
// Returns the full name for TTree::Draw to draw *this.
// Recursively appends, starting at the top TBranch,
// all method / object names with proper reference operators (->, .)
// depending on fTypeIsPointer.

   if (fParent)
      fParent->GetScope(scope);
   else {
      scope=fBranch->GetName();
      Ssiz_t pos = scope.First('[');
      if (pos != kNPOS) {
         scope.Remove(pos);
      }
      if (!scope.EndsWith(".")) scope+=".";
      const TBranch* mother=fBranch;
      while (mother != mother->GetMother() && (mother=mother->GetMother())) {
         TString nameMother(mother->GetName());
         if (!nameMother.EndsWith(".")) {
            scope.Prepend(".");
            scope.Prepend(nameMother);
         } else {
            if (mother != mother->GetMother()) {
               // If the mother is the top level mother
               // and its ends ends with a ., the name is already
               // embedded!
               scope.Prepend(nameMother);
            }
         }
      }
   }
   if (GetName() && GetName()[0]=='.')
      scope+=(GetName()+1);
   else
      scope+=GetName();
   if (fClass && !scope.EndsWith(".")) { // otherwise we're a leaf, and no delimiter is appended
      if (fTypeIsPointer)
         scope+="->";
      else scope+=".";
   }
}


//______________________________________________________________________________
void TVirtualBranchBrowsable::RegisterDefaultGenerators() 
{
// Adds the default generators. The user can remove any of them as follows:
//   TMethodBrowsable::Unregister();
// which will cause the browser not to show any methods.
   if (fgGeneratorsSet) return;
   // can't call RegisterGenerator - would be recusive infite loop
   fgGenerators.push_back(&TMethodBrowsable::GetBrowsables);
   fgGenerators.push_back(&TNonSplitBrowsable::GetBrowsables);
   fgGenerators.push_back(&TCollectionPropertyBrowsable::GetBrowsables);
   fgGeneratorsSet=kTRUE;
}

void TVirtualBranchBrowsable::RegisterGenerator(MethodCreateListOfBrowsables_t generator) 
{
   // Adds a generator to be called when browsing branches.
   // Called by the Register method, which should be implemented 
   // for all derived classes (see e.g. TMethodBrowsable::Register())
   if (!fgGeneratorsSet) RegisterDefaultGenerators();
   // make sure we're not adding another copy
   fgGenerators.remove(generator);
   fgGenerators.push_back(generator);
}

void TVirtualBranchBrowsable::UnregisterGenerator(MethodCreateListOfBrowsables_t generator) 
{
   // Removes a generator from the list of generators to be called when 
   // browsing branches. The user can remove any of the generators as follows:
   //   TMethodBrowsable::Unregister();
   // which will cause the browser not to show any methods.
   if (!fgGeneratorsSet) RegisterDefaultGenerators();
   fgGenerators.remove(generator);
}


ClassImp(TMethodBrowsable);

//______________________________________________________________________________
//
//  This helper object allows the browsing of methods of objects stored in
//  branches. They will be depicted by a leaf (or a branch, in case the method
//  returns an object) with a red exclamation mark. Only a subset of all 
//  methods will be shown in the browser (see IsMethodBrowsable for the
//  criteria a method has to satisfy). 
//
//  Obviously, methods are only available if the library is loaded which 
//  contains the dictionary for the class to be browsed!
//
//  If a branch contains a collection, TMethodBrowsable tries to find out 
//  what the contained element is (it will only create methods for the 
//  contained elements, but never for the collection). If it fails to extract
//  the type of the contained elements, or if there is no guarantee that the
//  type has any other common denominator than TObject (e.g. in the case of
//  a TObjArray, which can hold any object deriving from TObject) no methods
//  will be added.
//______________________________________________________________________________


//______________________________________________________________________________
TMethodBrowsable::TMethodBrowsable(const TBranch* branch, TMethod* m,
                                   const TVirtualBranchBrowsable* parent /* =0 */):
   TVirtualBranchBrowsable(branch, 0, kFALSE, parent), fMethod(m) 
{
// Constructor.
// Links a TBranchElement to a TMethod, allowing the TBrowser to
// browse simple methods.
//
// The c'tor sets the name for a method "Class::Method(params) const"
// to "Method(params)", title to TMethod::GetPrototype
   TString name(m->GetName());
   name+="()";
   if (name.EndsWith(" const")) name.Remove(name.Length()-6);
   SetName(name);

   name=m->GetPrototype();
   if (m->GetCommentString() && strlen(m->GetCommentString()))
      name.Append(" // ").Append(m->GetCommentString());
   SetTitle(name);

   TString plainReturnType(m->GetReturnTypeName());
   if (plainReturnType.EndsWith("*")) {
      SetTypeIsPointer();
      plainReturnType.Remove(plainReturnType.Length()-1);
      plainReturnType.Strip();
      if(plainReturnType.BeginsWith("const")) {
         plainReturnType.Remove(0,5);
         plainReturnType.Strip();
      }   
   }
   SetType(TClass::GetClass(plainReturnType));
}

//______________________________________________________________________________
void TMethodBrowsable::GetBrowsableMethodsForClass(TClass* cl, TList& li) 
{
// Given a class, this methods fills list with TMethodBrowsables
// for the class and its base classes, and returns the number of 
// added elements. If called from a TBranch::Browse overload, "branch" 
// should be set to the calling TBranch, otherwise "parent" should 
// be set to the TVirtualBranchBrowsable being browsed, and branch
// should be the branch of the parent.

   if (!cl) return;
   TList allClasses;
   allClasses.Add(cl);
   
   for(TObjLink* lnk=allClasses.FirstLink();
       lnk; lnk=lnk->Next()){
      cl=(TClass*)lnk->GetObject();
      TList* bases=cl->GetListOfBases();
      TBaseClass* base;
      TIter iB(bases);
      while ((base=(TBaseClass*)iB())) {
         TClass* bc=base->GetClassPointer();
         if (bc) allClasses.Add(bc);
      }
   }

   TList allMethods;
   TIter iC(&allClasses);
   while ((cl=(TClass*)iC())) {
      TList* methods=cl->GetListOfMethods();
      if (!methods) continue;
      TMethod* method=0;
      TIter iM(methods);
      while ((method=(TMethod*)iM()))
         if (method && !allMethods.FindObject(method->GetName()))
            allMethods.Add(method);
   }

   TIter iM(&allMethods);
   TMethod* m=0;
   while ((m=(TMethod*)iM())) {
      if (TMethodBrowsable::IsMethodBrowsable(m)) {
         li.Add(m);
      }
   }
}


//______________________________________________________________________________
Int_t TMethodBrowsable::GetBrowsables(TList& li, const TBranch* branch, 
                                      const TVirtualBranchBrowsable* parent /*=0*/) 
{
// This methods fills list with TMethodBrowsables
// for the branch's or parent's class and its base classes, and returns 
// the number of added elements. If called from a TBranch::Browse 
// overload, "branch" should be set to the calling TBranch, otherwise 
// "parent" should be set to the TVirtualBranchBrowsable being browsed.
   TClass* cl;
   // we don't care about collections, so only use the TClass argument,
   // and not the return value
   GetCollectionContainedType(branch, parent, cl);
   if (!cl) return 0;

   TList listMethods;
   GetBrowsableMethodsForClass(cl, listMethods);
   TMethod* method=0;
   TIter iMethods(&listMethods);
   while ((method=(TMethod*)iMethods())) {
      li.Add(new TMethodBrowsable(branch, method, parent));
   }
   return listMethods.GetSize();
}

//______________________________________________________________________________
Bool_t TMethodBrowsable::IsMethodBrowsable(const TMethod* m) 
{
// A TMethod is browsable if it is const, public and not pure virtual,
// if does not have any parameter without default value, and if it has 
// a (non-void) return value.
// A method called *, Get*, or get* will not be browsable if there is a 
// persistent data member called f*, _*, or m*, as data member access is 
// faster than method access. Examples: if one of fX, _X, or mX is a 
// persistent data member, the methods GetX(), getX(), and X() will not 
// be browsable.

   if (m->GetNargs()-m->GetNargsOpt()==0
       && (m->Property() & kIsConstant 
           & ~kIsPrivate & ~kIsProtected & ~kIsPureVirtual )
       && m->GetReturnTypeName()
       && strcmp("void",m->GetReturnTypeName())
       && !strstr(m->GetName(),"DeclFile")
       && !strstr(m->GetName(),"ImplFile")
       && strcmp(m->GetName(),"IsA")
       && strcmp(m->GetName(),"Class")
       && strcmp(m->GetName(),"CanBypassStreamer")
       && strcmp(m->GetName(),"Class_Name")
       && strcmp(m->GetName(),"ClassName")
       && strcmp(m->GetName(),"Clone")
       && strcmp(m->GetName(),"DrawClone")
       && strcmp(m->GetName(),"GetName")
       && strcmp(m->GetName(),"GetDrawOption")
       && strcmp(m->GetName(),"GetIconName")
       && strcmp(m->GetName(),"GetOption")
       && strcmp(m->GetName(),"GetTitle")
       && strcmp(m->GetName(),"GetUniqueID")
       && strcmp(m->GetName(),"Hash")
       && strcmp(m->GetName(),"IsFolder")
       && strcmp(m->GetName(),"IsOnHeap")
       && strcmp(m->GetName(),"IsSortable")
       && strcmp(m->GetName(),"IsZombie")) {

      // look for matching data member
      TClass* cl=m->GetClass();
      if (!cl) return kTRUE;
      TList* members=cl->GetListOfDataMembers();
      if (!members) return kTRUE;
      const char* baseName=m->GetName();
      if (!strncmp(m->GetName(), "Get", 3) ||
          !strncmp(m->GetName(), "get", 3))
         baseName+=3;
      if (!baseName[0]) return kTRUE;
      
      TObject* mem=0;
      const char* arrMemberNames[3]={"f%s","_%s","m%s"};
      for (Int_t i=0; !mem && i<3; i++)
         mem=members->FindObject(Form(arrMemberNames[i],baseName));
      return (!mem ||! ((TDataMember*)mem)->IsPersistent());
   };
   return kFALSE;
}

//______________________________________________________________________________
void TMethodBrowsable::Register() 
{
   // Wrapper for the registration method. Needed against MSVC, which 
   // assigned different addr to the same method, depending on what
   // translation unit you're in...
   TVirtualBranchBrowsable::RegisterGenerator(GetBrowsables);
}

//______________________________________________________________________________
void TMethodBrowsable::Unregister() 
{
   // Wrapper for the registration method. Needed against MSVC, which 
   // assigned different addr to the same method, depending on what
   // translation unit you're in...
   TVirtualBranchBrowsable::UnregisterGenerator(GetBrowsables);
}


ClassImp(TNonSplitBrowsable);

//______________________________________________________________________________
//
// Allows a TBrowser to browse non-split branches as if they were split. The
// generator extracts the necessary information from the streamer info in 
// memory (which does not have to be the same as the one on file, in case
// a library was loaded containing the dictionary for this type), i.e. it 
// also works without loading the class's library.
//
// Just as with TMethodBrowsables, if the generator finds a collection it 
// only takes the contained objects into account, not the collections. If
// it identifies a collection, but cannot extract the contained type, or the 
// contained type can be anything deriving from a TObject (like for TObjArray)
// or is not limited at all, no browser helper objects are created.
//______________________________________________________________________________

//______________________________________________________________________________
TNonSplitBrowsable::TNonSplitBrowsable(const TStreamerElement* element, const TBranch* branch, 
                                       const TVirtualBranchBrowsable* parent /* =0 */):
   TVirtualBranchBrowsable(branch, element->GetClassPointer(), 
   element->IsaPointer(), parent) 
{
// Constructor. Creates a TNonSplitBrowsable from a TStreamerElement, containing branch 
// and (if applicable) parent TVirtualBranchBrowsable.
   SetNameTitle(element->GetName(), element->GetTitle());
}


//______________________________________________________________________________
Int_t TNonSplitBrowsable::GetBrowsables(TList& li, const TBranch* branch,
                                        const TVirtualBranchBrowsable* parent /* =0 */) 
{
// Given either a branch "branch" or a "parent" TVirtualBranchBrowsable, we fill
// "list" with objects of type TNonSplitBrowsable which represent the members
// of class "cl" (and its base classes' members).

   // branch has to be unsplit, i.e. without sub-branches
   if (branch && const_cast<TBranch*>(branch)->GetListOfBranches() 
      && const_cast<TBranch*>(branch)->GetListOfBranches()->GetEntries()!=0
      && parent==0) // !(parent && parent->IsA()==TMethodBrowsable::Class()))
      return 0;
   // we only expand our own parents
   //if (parent && parent->IsA()!=TNonSplitBrowsable::Class()) return 0;

   TClass* clContained=0;
   GetCollectionContainedType(branch, parent, clContained);
   TVirtualStreamerInfo* streamerInfo= clContained?clContained->GetStreamerInfo():0;
   if (!streamerInfo 
      || !streamerInfo->GetElements() 
      || !streamerInfo->GetElements()->GetSize())  return 0;

   if (!branch && parent) branch=parent->GetBranch();

   // we simply add all of our and the bases' members into one big list
   TList myStreamerElementsToCheck;
   myStreamerElementsToCheck.AddAll(streamerInfo->GetElements());

   Int_t numAdded=0;
   TStreamerElement* streamerElement=0;
   for (TObjLink *link = myStreamerElementsToCheck.FirstLink();
        link;
        link = link->Next() ) {
      streamerElement = (TStreamerElement*)link->GetObject();
      if (streamerElement->IsBase()) {
         // this is a base class place holder
         // continue with the base class's streamer info
         TClass* base=streamerElement->GetClassPointer();
         if (!base || !base->GetStreamerInfo()) continue;

         // add all of the base class's streamer elements 
         // (which in turn can be a base, which will be 
         // unfolded in a later iteration) to the list
         TObjArray* baseElements=base->GetStreamerInfo()->GetElements();
         if (!baseElements) continue;
         TIter iBaseSE(baseElements);
         TStreamerElement* baseSE=0;
         while ((baseSE=(TStreamerElement*)iBaseSE()))
            // we should probably check whether we're replacing something here...
            myStreamerElementsToCheck.Add(baseSE);
      } else if (!strcmp(streamerElement->GetName(),"This") 
         && !strcmp(clContained->GetName(), streamerElement->GetTypeName())) {
         // this is a collection of the real elements. 
         // So get the class ptr for these elements...
         TClass* clElements=streamerElement->GetClassPointer();
         TVirtualCollectionProxy* collProxy=clElements?clElements->GetCollectionProxy():0;
         clElements=collProxy?collProxy->GetValueClass():0;
         if (!clElements) continue;

         // now loop over the class's streamer elements
         streamerInfo= clElements->GetStreamerInfo();
         TIter iElem(streamerInfo->GetElements());
         TStreamerElement* elem=0;
         while ((elem=(TStreamerElement*)iElem())) {
            TNonSplitBrowsable* nsb=new TNonSplitBrowsable(elem, branch, parent);
            li.Add(nsb);
            numAdded++;
         }
      } else {
         // we have a basic streamer element
         TNonSplitBrowsable* nsb=new TNonSplitBrowsable(streamerElement, branch, parent);
         li.Add(nsb);
         numAdded++;
      }
   }
   return numAdded;
}

//______________________________________________________________________________
void TNonSplitBrowsable::Register() 
{
   // Wrapper for the registration method. Needed against MSVC, which 
   // assigned different addr to the same method, depending on what
   // translation unit you're in...
   TVirtualBranchBrowsable::RegisterGenerator(GetBrowsables);
}

//______________________________________________________________________________
void TNonSplitBrowsable::Unregister() 
{
   // Wrapper for the registration method. Needed against MSVC, which 
   // assigned different addr to the same method, depending on what
   // translation unit you're in...
   TVirtualBranchBrowsable::UnregisterGenerator(GetBrowsables);
}


ClassImp(TCollectionPropertyBrowsable);

//______________________________________________________________________________
//
// A tiny browser helper object (and its generator) for adding a virtual 
// (as in "not actually part of the class", not in C++ virtual) "@size()" 
// method to a collection. For all collections that derive from
// TCollection, or have a TVirtualCollectionProxy associated with them,
// a leaf is created that allows access to the number of elements in the 
// collection. For TClonesArrays and types with an associated 
// TVirtualCollectionProxy, this forwards to TTreeFormula's 
// "@branch.size()" functionality. For all other collections, a method call
// to the appropriate collection's member function is executed when drawing.
//
// These objects are of course only created for elements containing a 
// collection; the generator has no effect on any other elements.
//______________________________________________________________________________


//______________________________________________________________________________
void TCollectionPropertyBrowsable::Browse(TBrowser *b) 
{
   // Browses a TCollectionPropertyBrowsable. The only difference to
   // the generic TVirtualBranchBrowsable::Browse is our fDraw
   GetBranch()->GetTree()->Draw(GetDraw(), "", b ? b->GetDrawOption() : "");
   if (gPad) gPad->Update();
}

//______________________________________________________________________________
Int_t TCollectionPropertyBrowsable::GetBrowsables(TList& li, const TBranch* branch, 
                                                  const TVirtualBranchBrowsable* parent /* =0 */) 
{
// If the element to browse (given by either parent of branch) contains
// a collection (TClonesArray or something for which a TVirtualCollectionProxy
// exists), we will add some special objects to the browser. For now there is
// just one object "@size", returning the size of the collection (as in
// std::list::size(), or TClonesArray::GetEntries()).
// The objects we create are simply used to forward strings (like "@size") to
// TTreeFormula via our Browse method. These strings are stored in fName.
   TClass* clContained=0;
   TClass* clCollection=GetCollectionContainedType(branch, parent, clContained);
   if (!clCollection || !clContained) return 0;

   // Build the fDraw string. Start with our scope.
   TString scope;
   if (parent) {
      parent->GetScope(scope);
      branch=parent->GetBranch();
   } else if (branch){
      scope=branch->GetName();
      scope+=".";
      const TBranch* mother=branch;
      while (mother != mother->GetMother() && (mother=mother->GetMother())) {
         TString nameMother(mother->GetName());
         if (!nameMother.EndsWith(".")) {
            scope.Prepend(".");
            scope.Prepend(nameMother);
         } else {
            if (mother != mother->GetMother()) {
               // If the mother is the top level mother
               // and its ends ends with a ., the name is already
               // embedded!
               scope.Prepend(nameMother);
            }
         }
      }
   } else {
      if (gTree)
         gTree->Warning("GetBrowsables", "Neither branch nor parent is set!");
      return 0;
   }

   // remove trailing delimiters
   if (scope.EndsWith(".")) scope.Remove(scope.Length()-1, 1);
   else if (scope.EndsWith("->")) scope.Remove(scope.Length()-2, 2);

   // now prepend "@" to the last element of the scope,
   // to access the collection and not its containees
   Ssiz_t lastDot=scope.Last('.');
   Ssiz_t lastArrow=scope.Last('>'); // assuming there's no branch name containing ">"...
   Ssiz_t lastPart=lastDot;
   if (lastPart==kNPOS || (lastArrow!=kNPOS && lastPart<lastArrow))
      lastPart=lastArrow;
   if (lastPart==kNPOS) lastPart=0;
   else lastPart++;

   TString size_title("size of ");
   size_title += clCollection->GetName();
   if (clContained) {
      size_title += " of ";
      size_title += clContained->GetName();
   }

   if (clCollection->GetCollectionProxy() || clCollection==TClonesArray::Class()) {
   // the collection is one for which TTree::Draw supports @coll.size()

      scope.Insert(lastPart, "@");
      TCollectionPropertyBrowsable* cpb=
         new TCollectionPropertyBrowsable("@size", size_title, 
         scope+".size()", branch, parent);
      li.Add(cpb);
      return 1;
   } // if a collection proxy or TClonesArray
   else if (clCollection->InheritsFrom(TCollection::Class())) {
      // generic TCollection - we'll build size() ourselves, by mapping
      // it to the proper member function of the collection
      if (clCollection->InheritsFrom(TObjArray::Class()))
         scope+="@.GetEntries()";
      else scope+="@.GetSize()";
      TCollectionPropertyBrowsable* cpb=
         new TCollectionPropertyBrowsable("@size", size_title, scope, branch, parent);
      li.Add(cpb);
      return 1;
   }
   return 0;
}

//______________________________________________________________________________
void TCollectionPropertyBrowsable::Register() 
{
   // Wrapper for the registration method. Needed against MSVC, which 
   // assigned different addr to the same method, depending on what
   // translation unit you're in...
   TVirtualBranchBrowsable::RegisterGenerator(GetBrowsables);
}

//______________________________________________________________________________
void TCollectionPropertyBrowsable::Unregister() 
{
   // Wrapper for the registration method. Needed against MSVC, which 
   // assigned different addr to the same method, depending on what
   // translation unit you're in...
   TVirtualBranchBrowsable::UnregisterGenerator(GetBrowsables);
}


ClassImp(TCollectionMethodBrowsable);

//______________________________________________________________________________
//
// TCollectionMethodBrowsable extends TCollectionPropertyBrowsable by showing
// all methods of the collection itself. If none are available - e.g. for STL 
// classes like std::list, a TVirtualBranchBrowsable object is reated instead. 
// The methods' names will have a "@" prepended, to distinguish them from the 
// contained elements' methods.
//
// This browser helper object is not part of the default list of registered
// generators (see TVirtualBranchBrowsable::RegisterDefaultGenerators()). 
// If you want to use it, you should call 
//   TCollectionMethodBrowsable::Register();
// As it extends the functionality of TVirtualBranchBrowsable, one might want 
// to unregister the generator of the "@size()" method by calling
//   TCollectionPropertyBrowsable::Unregister();
//______________________________________________________________________________


//______________________________________________________________________________
TCollectionMethodBrowsable::TCollectionMethodBrowsable(const TBranch* branch, TMethod* m, 
                                                       const TVirtualBranchBrowsable* parent /*=0*/):
TMethodBrowsable(branch, m, parent) 
{
   // Contructor, see TMethodBrowsable's constructor.
   // Prepends "@" to the name to make this method work on the container.
   SetName(TString("@")+GetName());
}

//______________________________________________________________________________
Int_t TCollectionMethodBrowsable::GetBrowsables(TList& li, const TBranch* branch, 
                                                const TVirtualBranchBrowsable* parent /*=0*/) 
{
// This methods fills list with TMethodBrowsables
// for the branch's or parent's collection class and its base classes, 
// and returns the number of added elements. If called from a TBranch::Browse 
// overload, "branch" should be set to the calling TBranch, otherwise 
// "parent" should be set to the TVirtualBranchBrowsable being browsed.
   TClass* clContained=0;
   // we don't care about the contained class, but only about the collections, 
   TClass* clContainer=GetCollectionContainedType(branch, parent, clContained);
   if (!clContainer || !clContained) return 0;

   TList listMethods;
   GetBrowsableMethodsForClass(clContainer, listMethods);
   TMethod* method=0;
   TIter iMethods(&listMethods);
   while ((method=(TMethod*)iMethods()))
      li.Add(new TCollectionMethodBrowsable(branch, method, parent));

   // if we have no methods, and if the class has a collection proxy, just add
   // the corresponding TCollectionPropertyBrowsable instead.
   // But only do that if TCollectionPropertyBrowsable is not generatated anyway
   // - we don't need two of them.
   if (!listMethods.GetSize() && clContainer->GetCollectionProxy()) {
      std::list<MethodCreateListOfBrowsables_t>& listGenerators=GetRegisteredGenerators();
      std::list<MethodCreateListOfBrowsables_t>::iterator iIsRegistered
         = std::find(listGenerators.begin(), listGenerators.end(), &TCollectionPropertyBrowsable::GetBrowsables);
      if (iIsRegistered==listGenerators.end()) {
         TCollectionPropertyBrowsable::GetBrowsables(li, branch, parent);
         return 1;
      }
   }
   return listMethods.GetSize();
}

//______________________________________________________________________________
void TCollectionMethodBrowsable::Register() 
{
   // Wrapper for the registration method. Needed against MSVC, which 
   // assigned different addr to the same method, depending on what
   // translation unit you're in...
   TVirtualBranchBrowsable::RegisterGenerator(GetBrowsables);
}

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