#include "QFramework/TQCut.h"
#include "TLeaf.h"  
#include "TObjArray.h"
#include "QFramework/TQAnalysisJob.h"
#include "QFramework/TQStringUtils.h"
#include "QFramework/TQValue.h"
#include "QFramework/TQSample.h"
#include "QFramework/TQIterator.h"
#include "QFramework/TQUtils.h"
#include "QFramework/TQUniqueCut.h"
#include "QFramework/TQToken.h"
// #define _DEBUG_
#include "QFramework/TQLibrary.h"

#include <iostream>
#include <fstream>
#include <sstream>
#include <cstdlib>

#include <stdexcept>

////////////////////////////////////////////////////////////////////////////////////////////////
//
// TQCut 
//
// The TQCut class is a representation of an event selection cut. Instances of this
// class ("cut") may build up a tree-like hierarchy. Every instance has zero or exactly one 
// base instance and any number of descendant instances. Navigation in upward direction is 
// possible by using getBase() and getRoot(), which return the base instance and the root 
// instance of this instance respectively. 
//
// Internally, a TQObservable is used to evaluate the cut on each individual event. 
// 
// The TQCut can be constructed from a string expression of the following syntax:
// 
// cutName : parentCutName << cutExpression ;
// 
// which passes events where cutExpression evaluates to true (1.) 
// and fails events where cutExpression evaluates to false (0.)
// 
// It is also possible to apply weights by extending the syntax as follows
// 
// cutName : parentCutName << cutExpression : weightExpression ;
//
// where weightExpression may evaluate to any floating number that is multiplied 
// to the event weight.
//
// Both, cutExpression and weightExpression, may use any type of expression
// that TQObservable::getTreeObservable function can make sense of. This
// especially includes arithmetic expressions using branch names present in the
// TTree.
//
// Please consider the following example cut definitions for guidance
//
// CutPreSelect << MET > 20000. ;
// CutLeptonPt : CutPreSelect << (lepPt0 > 22000. || lepPt1 > 22000.) ;
// CutBVeto : CutLeptonPt << nJets_Pt25_MV1_85 == 0 : bTagEventWeight ; 
// CutZVeto : CutBVeto << abs(Mll - 91187.6) <= 15000 ; 
// CutZttVeto : CutZVeto << !(x1 > 0 && x2 >0 && abs(Mtt - 91187.6) <= 25000.) ;
// 
// It is also possible and even advisable to construct a TQCut based on an
// instance of TQFolder. Here, the tree-like folder structure can be mapped 1:1
// to the cut structure created, where each folder in the structure may contain
// tags that control the effect of the cut that is created:
// .name: name of this cut, leave empty or omit to use folder name
// .title: title of this cut, leave empty or omit to use name
// .cutExpression: cut expression, leave empty or omit to pass all events
// .weightExpression: weight expression, leave empty or omit to apply unity weight
// .cutObservableName: name of the cut observable to be used, leave empty or
// omit to use "CUTNAME_cut"
// .weightObservableName: name of the weight observable to be used, leave empty or
// omit to use "CUTNAME_weight"
//
// The expressions may contain placeholders that will be filled from tags in
// the sample folder structure. You may choose to use $(bTagWeightName) as a
// placeholder and set the tag "bTagWeightName=bTagEventWeight" on your base
// sample folder. The replacement will be performed each time a new sample is
// opened, which allows you to use different cut or weight expressions for
// different branches of your sample folder structure. For further details,
// please read the documentation of the function
// TQObservable::compileExpression.
//
////////////////////////////////////////////////////////////////////////////////////////////////

ClassImp(TQCut)



//______________________________________________________________________________________________

//auxilliary method, for now not a member of TQCut
//TODO: should this be externalized in its own source file?
TQCut::VariantDefinitionList* getVariantDefinitions(TQSampleFolder* sf) {
  // parses tags on a given SampleFolder and creates a list of variant definitions
  // note: the returned type is a typedef, see TQCut.h for details
  // 
  // This function reads sets of tags from a SampleFolder and converts them to
  // a more accessible structure for further use. The read tags are expected to 
  // have the format
  // <.variant.cut.A.0jet = "[nJets3030]==0"> 
  // <.variant.cut.A.1jet = "[nJets3030]==1"> 
  // <.variant.replaceCut.A = "CutA"> 
  // <.variant.cut.C.1jet = "$(leadJetPt)>50000"> 
  // <.variant.cut.C.ge2jet = "$(leadJetPt)>35000"> 
  // <.variant.replaceCut.C = "CutC"> 
  // which will translate into CutA being replaced by two variants called 
  // "0jet" and "1jet" with respective cut expressions. Similarly for CutC, where
  // both, "CutA" and "CutC" could be any expressions matching to one or more
  // cut names as defined by TQStringUtils::matchesFilter(...) with "," as the 'or separator' .
  // In the above example "1jet" would be a suffix applied to the current folder name
  // (just like "0jet" and "ge2jet"), for which both CutA and CutC would be modified
  TQTaggable variantTags;
  if (!variantTags.importTagsWithoutPrefix(sf,".variant.")) {
    // no tags imported, so there is apparently no variant requested
    return nullptr; 
  }
  TQTaggable replacements;
  replacements.importTagsWithoutPrefix(variantTags,"replaceCut.");
  
  std::shared_ptr<TQTaggable> aliases = TQTaggable::getGlobalTaggable("aliases");
  //we need to combine variants with the same suffix ("1jet") but form different cut sets ("A","C")
  //hence, initially we use a std::map but later will convert it to a VariantDefinitionList (std::vector)
  //for easier handling and to freeze the order.
  std::map<TString,std::vector<TQCut::VariantDefinition>> suffixToVariantsMap;
  TQStringIterator setItr(replacements.getListOfTagNames(),true); //iterator takes ownership of collection
  while(setItr.hasNext()) { //iterate over sets of cut replacements
    //name of the set of replacements
    const TString& setName = setItr.readNext()->GetString();
    //pattern for which cuts should be replaced by the variants' expressions
    TString cutNamePattern = replacements.getTagStringDefault(setName,"");
    
    TQTaggable setCutVariants, setWeightVariants;
    setCutVariants.importTagsWithoutPrefix(variantTags, TString::Format("cut.%s.",setName.Data()));
    setWeightVariants.importTagsWithoutPrefix(variantTags, TString::Format("weight.%s.",setName.Data()));
    //iterate over alternative cut expressions
    TQStringIterator varCutItr(setCutVariants.getListOfTagNames(),true);
    while(varCutItr.hasNext()) {
      TString suffix = varCutItr.readNext()->String();
      TQCut::VariantDefinition varDef;
      varDef.matchingPattern = cutNamePattern;
      setCutVariants.getTagString(suffix,varDef.cutExpression);
      setWeightVariants.getTagString(suffix,varDef.weightExpression); //will stay unchanged if no weightExpression defined
      if (aliases) {
        varDef.cutExpression    = aliases->replaceInTextRecursive(varDef.cutExpression);
        varDef.weightExpression = aliases->replaceInTextRecursive(varDef.weightExpression);
      }
      if (!suffixToVariantsMap.count(suffix)) {
        suffixToVariantsMap[suffix] = {};
      }
      suffixToVariantsMap[suffix].push_back(varDef);
    }
    TQStringIterator varWeightItr(setWeightVariants.getListOfTagNames(),true);
    while(varWeightItr.hasNext()) {
      TString suffix = varWeightItr.readNext()->String();
      if (setCutVariants.hasTag(suffix)) continue; //this case should already covered by the previous loop over cutVariants
      TQCut::VariantDefinition varDef;
      varDef.matchingPattern = cutNamePattern;
      // no cut variant, since we know we don't have a variant cut expression
      setWeightVariants.getTagString(suffix,varDef.weightExpression);
      if (aliases) {
        varDef.weightExpression = aliases->replaceInTextRecursive(varDef.weightExpression);
      }
      if (!suffixToVariantsMap.count(suffix)) {
        suffixToVariantsMap[suffix] = {};
      }
      suffixToVariantsMap[suffix].push_back(varDef);
    }
    
  }  
  TQCut::VariantDefinitionList* retVal = new TQCut::VariantDefinitionList();
  for (std::pair<const TString,std::vector<TQCut::VariantDefinition>> & element : suffixToVariantsMap) {
    retVal->push_back({element.first,element.second});
  }

  return retVal;
}
//______________________________________________________________________________________________

void TQCut::VariantResults::resize(size_t size) {
  this->passed.clear();
  this->passed.resize(size);
  this->weight.clear();
  this->weight.resize(size);
  this->reset(1.);
}

void TQCut::VariantResults::reset(double baseWeight) {
  std::fill(this->passed.begin(), this->passed.end(), true);
  std::fill(this->weight.begin(), this->weight.end(), baseWeight);
}


bool TQCut::VariantResults::passAny() {
  return std::any_of(this->passed.begin(),this->passed.end(), [](bool p) {return p;});
}
//______________________________________________________________________________________________

bool TQCut::isValidName(const TString& name_) {
  // Check whether the string passed is a valid cut name. Return
  // true if name is valid and false otherwise. Valid cut names
  // may contain the letters a..z, A..Z, 0..9 and an underscore "_".
  return TQStringUtils::isValidIdentifier(name_,"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_",1);
}


//______________________________________________________________________________________________

bool TQCut::parseCutDefinition(const TString& definition_, TString * name_, 
                               TString * baseCutName_, TString * cutExpr_, TString * weightExpr_) {
  // parse the definition of the cut and deploy the parsed fields in the argument pointers
  if(name_ && baseCutName_ && cutExpr_ && weightExpr_)
    return TQCut::parseCutDefinition(definition_, *name_, *baseCutName_, *cutExpr_, *weightExpr_);
  return false;
}


//______________________________________________________________________________________________

bool TQCut::parseCutDefinition(TString definition, TString& name, TString& baseCutName, TString& cutExpr, TString& weightExpr) {
  // parse the definition of the cut and deploy the parsed fields in the argument references

  TString buf;

  TQStringUtils::readUpTo(definition,buf, ":","{}","\"\"");
  if(buf.IsNull()) return false;
  name = TQStringUtils::trim(buf);
  if (!isValidName(name)) { return false; }
 
  TQStringUtils::readToken(definition,buf,":");
  buf.Clear();

  if(definition.Contains("<<")){
    TQStringUtils::readUpTo(definition,buf,"<","{}","\"\"");
    baseCutName = TQStringUtils::trim(buf);
    TQStringUtils::readToken(definition,buf,"<");
    if(!isValidName(baseCutName)) return false;
  } else {
    baseCutName="";
  }
  buf.Clear(); 

  TQStringUtils::readUpTo(definition,buf,":;","{}()[]","\"\"");
  if(definition.IsNull()){
    cutExpr = TQStringUtils::compactify(buf);
  } else {
    cutExpr = TQStringUtils::compactify(buf);
    buf.Clear();
    while(TQStringUtils::readToken(definition,buf,":")>=2) {
      if (buf.Length()>2) {
        TQLibrary::ERRORclass("Unexpected number of consecutive ':'s in basecut definition found (max. 2)!");
        return false;
      }
      TQStringUtils::readUpTo(definition,buf,":","{}()[]","\"\"");
      cutExpr+=buf;
      buf.Clear();
    }
    TQStringUtils::readToken(definition,buf," ");
    buf.Clear();
    TQStringUtils::readUpTo(definition,buf,";","{}()[]","\"\"");
    weightExpr = TQStringUtils::compactify(buf); 
  }
  if(cutExpr.IsNull()) return false;

  return true;

}


//______________________________________________________________________________________________

TQCut * TQCut::createCut(const TString& definition_) {
  // create a new TQCut from the given definition

  TString name, baseCutName, cutExpr, weightExpr;

  TQCut * cut = NULL;

  if (parseCutDefinition(definition_, name, baseCutName, cutExpr, weightExpr)) {

    /* we don't allow a base cut in the static method */
    if (baseCutName.Length() > 0) { return 0; }

    /* create the cut */

    cut = new TQCut(name);

    /* set its parameters */
    cut->setCutExpression(cutExpr);
    cut->setWeightExpression(weightExpr);
  } 

  return cut;
}


//______________________________________________________________________________________________

TQCut * TQCut::createCut(const TString& name, const TString& cutExpr, const TString& weightExpr) {
  // create a new TQCut from the given parameters
 
  TQCut* cut = new TQCut(name);
  cut->setCutExpression(cutExpr);
  cut->setWeightExpression(weightExpr);
 
  return cut;
}



//______________________________________________________________________________________________

TQCut* TQCut::createFromFolderInternal(TQFolder* folder, TQTaggable* tags){
  // import the cut from a folder created with TQCut::dumpToFolder(...)

  /* ===== check that the folder is a valid cut description ===== */
  if (!folder) return 0;

  TString name = folder->GetName();
  TString title = folder->GetTitle();
  //@tag: [.name,.title] These folder tags determine the name and title of the cut when importing the cut definition from a TQFolder.
  folder->getTagString(".name",name);
  folder->getTagString(".title",title);

  TQValue * objCutExpr = dynamic_cast<TQValue*>(folder->getObject(".cutExpression"));
  TQValue * objWeightExpr = dynamic_cast<TQValue*>(folder->getObject(".weightExpression"));
  //@tag: [.cutExpression,.weightExpression] These folder tags determine the cut and weight expressions of the cut when importing the cut definition from a TQFolder. Defaults are the values of TQValue objects with the same name as the corresponding tag, if these TQValue objects are found in the TQFolder. Otherwise default is an empty string "".
  TString cutExpression = folder->getTagStringDefault(".cutExpression", objCutExpr ? objCutExpr ->getString() : "");
  TString weightExpression = folder->getTagStringDefault(".weightExpression",objWeightExpr ? objWeightExpr->getString() : "");
  if (cutExpression.Length()==0) {
    if (weightExpression.Length()==0) {
      throw std::runtime_error(TString::Format("Cut with name '%s' and title '%s' has neither tags '.cutExpression' nor '.weightExpression', please check your cut definitions!",name.Data(),title.Data()).Data());
    }else{
      WARNclass("Found weight expression but no cut expression found when creating cut with name '%s' and title '%s'. If you do not intend to veto events at this cut please consider adding '.cutExpression=\"1.\"' to this cut.",name.Data(),title.Data());
    }
  }
  //@tag: [.skipJobs] Folder tag when creating cut hierarchy from a TQFolder structure. Allows to ignore all analysis jobs attached to the particular cut. Default: false.
  bool skipAnalysisJobsGlobal = folder->getTagBoolDefault(".skipJobs",false); //option to blacklist all analysis jobs for the cut we create (applies accros all samples/sample folders)
  //@tag: [.printResults] Folder tag when creating cut hierarchy from a TQFolder structure. If set and not 0 will print results of evaluation of first n events of the current sample seen by this cut (weights only if cut is passed). If n is negative all event seen by this cut are printed.
  int printEvents = folder->getTagIntegerDefault(".printResult",0);
  /* create the new cut */
  TQCut* newcut = nullptr;
  if(cutExpression.BeginsWith("#UNIQUE")){
    TString buffer;
    TString runno,evtno;
    TQStringUtils::readUpTo(cutExpression,buffer,"(");
    buffer.Clear();
    TQStringUtils::readBlock(cutExpression,buffer ,"()");
    TQStringUtils::readUpTo(buffer,runno ,",");
    TQStringUtils::removeLeading(buffer,",");
    evtno = buffer;
    newcut = new TQUniqueCut(name,runno,evtno);
    newcut->SetTitle(title);
    //return newcut;
  } else {
    newcut = new TQCut(name,title);
    newcut->setCutExpression (tags ? tags->replaceInTextRecursive(cutExpression) : cutExpression );
    newcut->setWeightExpression(tags ? tags->replaceInTextRecursive(weightExpression) : weightExpression);
    //return newcut;
  }
  newcut->setSkipAnalysisJobsGlobal(skipAnalysisJobsGlobal);  
  newcut->setPrintResults(printEvents);
  return newcut;
}

//______________________________________________________________________________________________

void TQCut::importFromFolderInternal(TQFolder * folder, TQTaggable* tags){
  /* import descendent cuts from */
  TQFolderIterator itr(folder->getListOfFolders("?"),true);
  while(itr.hasNext()){
    TQFolder* f = itr.readNext();
    if(!f) continue;
    DEBUGclass("reading folder '%s' for import",f->GetName());
    TQCut * subCut = TQCut::createFromFolderInternal(f,tags);
    if (subCut){
      if(!this->addCut(subCut)){
        WARNclass("cannot add cut '%s' to '%s' - a cut with the given name already exists at '%s'!",subCut->GetName(),this->getPath().Data(),this->getRoot()->getCut(subCut->GetName())->getBase()->getPath().Data());
        delete subCut;
      } else {
        subCut->importFromFolderInternal(f,tags);
      }
    } else {
      WARNclass("unable to import cut from folder '%s'",f->GetName());
    }
  }

  this->sort();
}

//______________________________________________________________________________________________

TQCut * TQCut::importFromFolder(TQFolder * folder, TQTaggable* tags) {
  TQCut* cut = createFromFolderInternal(folder,tags);
  cut->importFromFolderInternal(folder,tags);
  return cut;
}


//_____________________________________________________________________________________________

TQCut::TQCut() : 
  TNamed("<template>", "template"),
  fCutItr(this->fCuts),
  fJobItr(this->fAnalysisJobs)
{
  // default constructor, needed for streaming
}


//______________________________________________________________________________________________

TQCut::TQCut(const TString& name_, const TString& title_, const TString& cutExpression, const TString& weightExpression) : 
  TNamed(name_, title_),
  fCutItr(this->fCuts),
  fJobItr(this->fAnalysisJobs)
{
  // constructor taking additioinal arguments
  this->setCutExpression(cutExpression);
  this->setWeightExpression(weightExpression);
}

//______________________________________________________________________________________________

TList * TQCut::exportDefinitions(bool terminatingColon) {
  // export all cut definitions as a TList

  // create new list
  TList * defs = new TList();
  defs->SetOwner(true);
 
  // add this cut
  TString cutDef = TString(this->GetName()) + ": ";
  if (fBase) {
    cutDef.Append(TString::Format("%s << ", fBase->GetName()));
  }
  cutDef.Append(this->getCutExpression());
  TString weights = this->getWeightExpression();
  if (!weights.IsNull()) {
    cutDef.Append(weights.Prepend(" : "));
  }
  if (terminatingColon) {
    cutDef.Append(";");
  }
  defs->Add(new TObjString(cutDef.Data()));
 
  // iterate over descendants
  this->fCutItr.reset();
  while (this->fCutItr.hasNext()){
    TQCut * c = this->fCutItr.readNext();
    TList * subDefs = c->exportDefinitions(terminatingColon);
    defs->AddAll(subDefs);
    subDefs->SetOwner(false);
    delete subDefs;
  }
 
  // return list of definition strings
  return defs;
}


//______________________________________________________________________________________________

void TQCut::setBase(TQCut * base_) {
  // set the base cut
  fBase = base_;
}


//______________________________________________________________________________________________

TQCut * TQCut::getBase() {
  // Return the base cut of this cut

  return fBase;
}


//______________________________________________________________________________________________

TString TQCut::getPath() {
  // Return the path to this cut
  if(this->fBase) return TQFolder::concatPaths(this->fBase->getPath(),this->GetName());
  else return this->GetName();
}

//______________________________________________________________________________________________

const TQCut * TQCut::getBaseConst() const {
  // Return the base cut of this cut
  return fBase;
}


//______________________________________________________________________________________________

TQCut * TQCut::getRoot() {
  // Return the root cut of this cut hierarchy

  if (fBase)
    /* this cut has a base cut: return the root of it */
    return fBase->getRoot();
  else
    /* this cut is the root */
    return this;
}


//______________________________________________________________________________________________

void TQCut::printEvaluation() const {
  // print the evaluation steps for this cut expression 
  // on the currently active event
  // WARNING: THIS FUNCTION ONLY MAKES SENSE FOR PROPERLY INITIALIZED CUTS
  // IT WILL PRODUCE SEVERAL OUTPUT LINES FOR EACH EVENT - EXTREMELY VERBOSE!
  // USE FOR DEBUGGING ONLY!
  Long64_t iEvent = this->fTree->GetReadEntry();
  this->printEvaluation(iEvent);
}

//______________________________________________________________________________________________

void TQCut::printWeightComponents() const{
  // print the evaluation steps for this weight expression 
  // on the currently active event
  // WARNING: THIS FUNCTION ONLY MAKES SENSE FOR PROPERLY INITIALIZED CUTS
  // IT WILL PRODUCE SEVERAL OUTPUT LINES FOR EACH EVENT - EXTREMELY VERBOSE!
  // USE FOR DEBUGGING ONLY!
  Long64_t iEvent = this->fTree->GetReadEntry();
  this->printWeightComponents(iEvent);
}

//______________________________________________________________________________________________

void TQCut::printWeightComponents(Long64_t/*iEvent*/) const{
  // print the evaluation steps for this weight expression 
  // on event number iEvent 
  // WARNING: THIS FUNCTION ONLY MAKES SENSE FOR PROPERLY INITIALIZED CUTS
  // IT WILL PRODUCE SEVERAL OUTPUT LINES FOR EACH EVENT - EXTREMELY VERBOSE!
  // USE FOR DEBUGGING ONLY!
  TQIterator itr(this->fWeightObservable->getBranchNames(),true);
  int index = 0;
  while(itr.hasNext()){
    if(index != 0){
      std::cout << ", ";
    }
    TObject* next = itr.readNext();
    if(!next) continue;
    TLeaf *leaf = fTree->GetLeaf(next->GetName());
    if(!leaf) continue;
    if(fTree->GetBranchStatus(next->GetName()) == 1){
      std::cout << next->GetName() << "=" << leaf->GetValue();
    } else {
      std::cout << TQStringUtils::makeBoldRed(next->GetName()) << " " << TQStringUtils::makeBoldRed("undefined");
    }
    index++;
  }
  std::cout << std::endl;
}

//______________________________________________________________________________________________

void TQCut::printEvaluation(Long64_t iEvent) const {
  // print the evaluation steps for this cut expression 
  // on event number iEvent 
  // WARNING: THIS FUNCTION ONLY MAKES SENSE FOR PROPERLY INITIALIZED CUTS
  // IT WILL PRODUCE SEVERAL OUTPUT LINES FOR EACH EVENT - EXTREMELY VERBOSE!
  // USE FOR DEBUGGING ONLY!
  std::cout << TQStringUtils::makeBoldWhite(TString::Format("considering entry %lld...",iEvent)) << std::endl;
  this->printEvaluationStep(0);
  int index = 0;
  const TQCut* c = this;
  do {
    TQIterator itr(c->fCutObservable->getBranchNames(),true);
    while(itr.hasNext()){
      if(index != 0){
        std::cout << ", ";
      }
      TObject* next = itr.readNext();
      if(!next) continue;
      TLeaf *leaf = fTree->GetLeaf(next->GetName());
      if(!leaf) continue;
      if(fTree->GetBranchStatus(next->GetName()) == 1){
        std::cout << next->GetName() << "=" << leaf->GetValue();
      } else {
        std::cout << TQStringUtils::makeBoldRed(next->GetName()) << " " << TQStringUtils::makeBoldRed("undefined");
      }
      index++;
    }
    c = c->passed() ? c->getBaseConst() : NULL;
  } while (c);
  std::cout << std::endl;
}

//______________________________________________________________________________________________

bool TQCut::printEvaluationStep(size_t indent) const {
  // print a single evaluation step for this cut
  bool passed = this->passed();
  std::cout << TQStringUtils::makeBoldWhite("[");
  if(passed) std::cout << TQStringUtils::makeBoldGreen(" OK ");
  else std::cout << TQStringUtils::makeBoldRed("FAIL");
  std::cout << TQStringUtils::makeBoldWhite("]");
  std::cout << TQStringUtils::repeat("\t",indent);
  if(indent > 0) std::cout << "&& ";
  std::cout << this->getActiveCutExpression();
  std::cout << std::endl;
  if(passed && this->fBase){
    passed = this->fBase->printEvaluationStep(indent+1);
  }
  return passed;
}

//______________________________________________________________________________________________

void TQCut::setCutExpression(const TString& cutExpression){
  // set the cut expression to some string
  this->fCutExpression = TQStringUtils::minimize(cutExpression);
}

//______________________________________________________________________________________________

void TQCut::setWeightExpression(const TString& weightExpression) {
  // set the weight expression to some string
  this->fWeightExpression = TQStringUtils::minimize(weightExpression);
}

//______________________________________________________________________________________________

TQObservable* TQCut::getCutObservable() {
  // get the cut observable
  return this->fCutObservable;
}

//______________________________________________________________________________________________

TQObservable* TQCut::getWeightObservable(){
  // get the weight observable
  return this->fWeightObservable;
}


//______________________________________________________________________________________________

const TString& TQCut::getCutExpression() const {
  // retrieve the cut expression
  return this->fCutExpression;
}


//______________________________________________________________________________________________

TString TQCut::getActiveCutExpression() const {
  // retrieve the currently active cut expression
  return (this->fCutObservable ? this->fCutObservable->getActiveExpression() : TQStringUtils::emptyString);
}

//______________________________________________________________________________________________

TString TQCut::getCompiledCutExpression(TQTaggable* tags) {
  // retrieve the cut expression
  return TQObservable::compileExpression(this->fCutExpression,tags);
}

//______________________________________________________________________________________________

TString TQCut::getGlobalCutExpression(TQTaggable* tags) {
  // retrieve the cut expression
  if(this->fBase){
    TString expr = this->fBase->getGlobalCutExpression(tags);
    expr.Append(" && ( ");
    expr.Append(this->getCompiledCutExpression(tags));
    expr.Append(")");
    return expr;
  }
  return this->getCompiledCutExpression(tags);
}


//______________________________________________________________________________________________

const TString& TQCut::getWeightExpression() const {
  // retrieve the weight expression
  return this->fWeightExpression;
}

//______________________________________________________________________________________________

TString TQCut::getActiveWeightExpression() const {
  // retrieve the currently active cut expression
  return (this->fWeightObservable ? this->fWeightObservable->getActiveExpression() : TQStringUtils::emptyString);
}

//______________________________________________________________________________________________

TString TQCut::getCompiledWeightExpression(TQTaggable* tags) {
  // retrieve the cut expression
  return TQObservable::compileExpression(this->fWeightExpression,tags);
}

//______________________________________________________________________________________________

TString TQCut::getGlobalWeightExpression(TQTaggable* tags) {
  // retrieve the weight expression
  if(this->fBase){
    TString expr = this->fBase->getGlobalWeightExpression(tags);
    expr.Append(" * ");
    expr.Append(this->getCompiledWeightExpression(tags));
    return expr;
  }
  return this->getCompiledWeightExpression(tags);
}


//______________________________________________________________________________________________

TQCut * TQCut::addAndReturnCut(const TString& definition_) {
  // add a cut defined by a string and return it

  TString name, baseCutName, cutExpr, weightExpr;

  if (!parseCutDefinition(definition_, name, baseCutName, cutExpr, weightExpr))
    return NULL;

  /* create the cut */
  TQCut * cut = new TQCut(name);
 
  /* set its parameters */
  cut->setCutExpression(cutExpr);
  cut->setWeightExpression(weightExpr);
 
  /* add the cut */
  if (addCut(cut, baseCutName)) {
    return cut;
  } else {
    delete cut;
  }

  return NULL;
}


//______________________________________________________________________________________________

bool TQCut::addCut(const TString& definition_) {
  // add a cut defined by a string
  // internally calles TQCut::addAndReturnCut

  if (addAndReturnCut(definition_)) {
    return true;
  } else {
    return false;
  }
}


//______________________________________________________________________________________________

bool TQCut::addCut(TQCut * cut_, const TString& baseCutName) {
  // add a given instance of TQCut to a basecut identified by name

  /* try to find the base cut */
  TQCut * cut = getCut(baseCutName);
  
  /* stop if we couldn't find the base cut */
  if (!cut) { return false; }
  
  /* add the cut to the base cut */
  return cut->addCut(cut_);
}

//______________________________________________________________________________________________

bool TQCut::addCut(TQCut * cut_) {
  // add a given instance of TQCut to a basecut identified by name

  /* stop if no cut is given */
  if (!cut_) { return false; }

  /* stop if there is already a cut with the same name */
  if (this->getRoot()->getCut(cut_->GetName())) { return false; }
 
  /* add the new cut to this cut */
  cut_->setBase(this);
  fCuts->Add(cut_);
  return true;
}


//______________________________________________________________________________________________

bool TQCut::isMergeable() const {
  // returns true if this cut is mergeable, false otherwise
  return true;
}


//______________________________________________________________________________________________

void TQCut::consolidate() {
  // try to consolidate the cut hierarchy
  // this function attempts to merge as many cuts as possibel 
  // without obstructing any existing analysis jobs
  // STILL IN EXPERIMENTAL STATE

  /* try to consolidate every child */
  for (int iChild = 0; iChild < fCuts->GetEntries(); iChild++) {
    ((TQCut*)fCuts->At(iChild))->consolidate();
  }

  /* try to remove every child */
  int i = 0;
  while (i < fCuts->GetEntries()) {

    if (removeCut(fCuts->At(i)->GetName()))
      i = 0;
    else
      i++;

  }

}

//______________________________________________________________________________________________

int TQCut::getDepth() const{
  // return the maximum depth of this cut (branch)
  int retval = 0;
  this->fCutItr.reset();
  while(this->fCutItr.hasNext()){
    TQCut* cut = this->fCutItr.readNext();
    if(!cut) continue;
    retval = std::max(retval,cut->getDepth()+1);
  }
  return retval;
}

//______________________________________________________________________________________________

int TQCut::getWidth() const{
  // return the width of this cut (number of immediate child cuts)
  return this->fCuts->GetEntries();
}

//______________________________________________________________________________________________

int TQCut::Compare(const TObject* obj) const {
  const TQCut* c = dynamic_cast<const TQCut*>(obj);
  if(!c) return 0;
  int otherDepth = c->getDepth();
  int myDepth = this->getDepth();
  if(otherDepth > myDepth) return 1;
  if(otherDepth < myDepth) return -1;
  int otherWidth = c->getWidth();
  int myWidth = this->getWidth();
  if(otherWidth > myWidth) return -1;
  if(otherWidth < myWidth) return 1;
  return 0;
}

//______________________________________________________________________________________________

void TQCut::sort() {
  // sort the cut hierarchy
  // this will have no effect on the results of the analysis
  // however, it will reorganize the layout of the cut diagrams
  // in such a way that a vertical structure is most eminent
 
  if(this->fCuts->GetEntries() < 2) return;

  this->fCutItr.reset();
  while(this->fCutItr.hasNext()){
    TQCut* cut = this->fCutItr.readNext();
    if(!cut) continue;
    cut->sort();
  }

  this->fCuts->Sort();
}


//______________________________________________________________________________________________


bool TQCut::isTrivialTrue(const TString& expr){
  // return true if this cut is trivally passed by every event
  TString e(TQStringUtils::trim(expr));
  if(e == "1" || e == "1.") return true;
  return false;
}

//______________________________________________________________________________________________


bool TQCut::isTrivialFalse(const TString& expr){
  // return true if this cut is trivally failed by every event
  TString e(TQStringUtils::trim(expr));
  if(e == "0" || e == "0.") return true;
  return false;
}

//______________________________________________________________________________________________

bool TQCut::includeBase() {
  // merge this cut with its base cut

  /* stop if this is the root */
  if (!fBase) { return false; }

  /* stop if base cut or this cut isn't mergeable */
  if (!isMergeable() || !fBase->isMergeable()) { return false; }

  /* merge cut expressions */
  if(TQCut::isTrivialTrue(this->getCutExpression())){
    this->setCutExpression(this->fBase->getCutExpression());
  } else if(TQCut::isTrivialTrue(this->fBase->getCutExpression()) || TQCut::isTrivialFalse(this->getCutExpression())){
    // we don't need to do anything
  } else if(TQCut::isTrivialFalse(this->fBase->getCutExpression())){
    this->setCutExpression("0.");
  } else {
    this->setCutExpression(TString::Format("( %s ) && ( %s )",this->fBase->getCutExpression().Data(),this->getCutExpression().Data()));
  } 

  /* merge weight expressions */
  TString newWeightExpression = fBase->getWeightExpression();
  if (newWeightExpression.Length() > 0 && this->fWeightObservable){
    newWeightExpression.Append(" * "); }
  newWeightExpression.Append(this->getWeightExpression());
 
  this->setWeightExpression(newWeightExpression);
 
  return true;
 
}


//______________________________________________________________________________________________

bool TQCut::removeCut(const TString& name) {
  // remove a cut from the cut hierarchy (by name)

  /* the index of the cut to be removed */
  int iRemove = -1;

  /* try to find the cut to be removed in the list of children */
  for (int iChild = 0; iChild < fCuts->GetEntries(); iChild++) {
    if (name.CompareTo(fCuts->At(iChild)->GetName(), TString::kIgnoreCase) == 0) {
      iRemove = iChild;
    }
  }

  if (iRemove >= 0) {

    /* get the cut to be removed */
    TQCut * cutToRemove = (TQCut*)fCuts->At(iRemove);

    /* we cannot remove the cut if it has analysis jobs or it cannot be merged */
    if (cutToRemove->getNAnalysisJobs() > 0 || !cutToRemove->isMergeable()) 
      return false;

    /* prepare a new list of sub cuts */
    TObjArray * newSubCuts = new TObjArray();

    /* try to merge the cut to be removed and its subcuts */
    bool success = true;
    TObjArray * subCuts = cutToRemove->getCuts();
    for (int iSubChild = 0; iSubChild < subCuts->GetEntries(); iSubChild++) { 
      /* get a clone of the subcut */
      TQCut * subChild = (TQCut*)(subCuts->At(iSubChild)->Clone());
      /* try to merge the cuts */
      success = subChild->includeBase() && success;
      /* add it to the new list */
      newSubCuts->Add(subChild);
      subChild->setBase(this); 
    }

    if (success) {
 
      /* delete the cut to be removed */
      delete cutToRemove;

      /* replace list of children */
      TObjArray * newCuts = new TObjArray(); 
      for (int iChild = 0; iChild < fCuts->GetEntries(); iChild++) {
        if (iChild < iRemove || iChild > iRemove)
          newCuts->Add(fCuts->At(iChild));
        else 
          for (int iSubChild = 0; iSubChild < newSubCuts->GetEntries(); iSubChild++)
            newCuts->Add(newSubCuts->At(iSubChild));
      }
 
      delete fCuts;
      fCuts = newCuts;

    } else {
 
      /* delete list of clones */
      for (int j = 0; j < newSubCuts->GetEntries(); j++)
        delete newSubCuts->At(j);

    }

    return success; 

  } else {

    /* loop over children and try to remove cut recursively */
    for (int iChild = 0; iChild < fCuts->GetEntries(); iChild++) {
      if (((TQCut*)fCuts->At(iChild))->removeCut(name)) {
        return true;
      }
    }

    return false;

  }

}

//__________________________________________________________________________________|___________

void TQCut::printCut(const TString& options) {
  // wrapper for the "print" function
  this->printInternal(options,0);
}

//______________________________________________________________________________________________

void TQCut::printActiveCutExpression(size_t indent) const {
  // print the currently active cut expression for this cut and all parent cuts
  std::cout << TQStringUtils::repeat("\t",indent);
  if(indent > 0) std::cout << "&& ";
  std::cout << this->getActiveCutExpression();
  std::cout << std::endl;
  if(this->fBase){
    this->fBase->printActiveCutExpression(indent+1);
  }
}


//__________________________________________________________________________________|___________

void TQCut::print(const TString& options) {
  // Print a summary of this cut instance. The following options my be specified:
  // - "r" (default) also print a summary of descendant cuts
  this->printInternal(options,0);
}

//__________________________________________________________________________________|___________

void TQCut::printCuts(const TString& options) {
  // Print a summary of this cut instance. The following options my be specified:
  // - "r" (default) also print a summary of descendant cuts
  this->printInternal(options,0);
}
  
//__________________________________________________________________________________|___________

void TQCut::printInternal(const TString& options, int indent) {
  // Print a summary of this cut instance. The following options my be specified:
  // - "r" (default) also print a summary of descendant cuts
  const int cColWidth_Total = TQLibrary::getConsoleWidth() - 4;
  const int cColWidth_Name = 0.5*cColWidth_Total;
  const int cColWidth_nJobs = 10;
  const int cColWidth_CutExpr = 0.3*cColWidth_Total;
  const int cColWidth_WeightExpr = cColWidth_Total - cColWidth_Name - cColWidth_nJobs - cColWidth_CutExpr;
 
  bool printRecursive = options.Contains("r", TString::kIgnoreCase);
 
  /* print headline if this is first indent */
  if (indent == 0) { 
    TString headline = TString::Format("%-*s %*s %-*s %-*s",
                                       cColWidth_Name, "Name", cColWidth_nJobs, "# Jobs", 
                                       cColWidth_CutExpr, "Cut Expression", cColWidth_WeightExpr, "Weight Expression");
    std::cout << TQStringUtils::makeBoldWhite(headline) << std::endl;
    std::cout << TQStringUtils::makeBoldWhite(TQStringUtils::repeat("=", TQStringUtils::getWidth(headline))) << std::endl;
  }
 
  TString line;
  line.Append(TQStringUtils::fixedWidth(TString::Format("%*s%s", indent, "", GetName()), cColWidth_Name, "l."));
  line.Append(" ");
  line.Append(TQStringUtils::fixedWidth(TString::Format("%d", getNAnalysisJobs()), cColWidth_nJobs,"r"));
  line.Append(" ");
  line.Append(TQStringUtils::fixedWidth(this->getCutExpression(), cColWidth_CutExpr, "l."));
  line.Append(" ");
  line.Append(TQStringUtils::fixedWidth(this->getWeightExpression(), cColWidth_WeightExpr, "l."));
  std::cout << line.Data() << std::endl;

  if (printRecursive) {
    TQIterator itr(fCuts);
    while(itr.hasNext()){
      TQCut* c = dynamic_cast<TQCut*>(itr.readNext());
      if(!c) continue;
      c->printInternal(options, indent + 1);
    }
  }
 
}

//__________________________________________________________________________________|___________

void TQCut::writeDiagramHeader(std::ostream & os, TQTaggable& tags){
  // write the header of the cut diagram file to a stream

  //@tag:[standalone] If this argument tag is set to true, standalone LaTeX document with the cut diagrams is created. Default: false
  bool standalone = tags.getTagBoolDefault("standalone",false);
  if(standalone) os << "\\documentclass{standalone}" << std::endl << "\\usepackage{tikz}" << std::endl << "\\usepackage{underscore}" << std::endl << "\\usepackage[T1]{fontenc}" << std::endl << "\\usetikzlibrary{positioning,arrows}" << std::endl << "\\begin{document}" << std::endl;
  //@tag:[format] This argument tag sets the format in which the cut diagram is produced. Default: "tikz" (other formats are currently not cupported)
  TString format = tags.getTagStringDefault("format","tikz");
  if(format == "tikz"){
    os << "\\begingroup" << std::endl;
    //@tag:[nodes.color,nodes.opacity,nodes.width,nodes.padding,nodes.height,nodes.distance] These argument tags define how nodes are drawn in the cut diagram produced in tikz/LaTeX format. Defaults (in order): "blue", 20, "10em", "2.5pt", "2em", "0.1cm"
    os << "\\tikzstyle{block} = [rectangle, draw, fill=" << tags.getTagStringDefault("nodes.color","blue") << "!" << tags.getTagIntegerDefault("nodes.opacity",20) << ", text width=" << tags.getTagStringDefault("nodes.width","10em") <<", inner sep=" << tags.getTagStringDefault("nodes.padding","2.5pt") << ", text centered, rounded corners, minimum height=" << tags.getTagStringDefault("nodes.height","2em") << "]" << std::endl;
    //@tag:[jobs.color,jobs.opacity,jobs.padding] These argument tags define how jobs (cuts) are drawn in the cut diagram produced in tikz/LaTeX format. Defaults (in order): "red", 20, "2.5pt"
    os << "\\tikzstyle{job} = [rectangle, draw, fill=" << tags.getTagStringDefault("jobs.color","red") << "!" << tags.getTagIntegerDefault("jobs.opacity",20) << ", inner sep=" << tags.getTagStringDefault("jobs.padding","2.5pt") << ", rounded corners, font={\\tiny}]" << std::endl;
    os << "\\tikzstyle{line} = [draw, -latex']" << std::endl;
    os << std::endl;
    os << "\\begin{tikzpicture}[" << "]" << std::endl;
  }
}

//__________________________________________________________________________________|___________

void TQCut::writeDiagramFooter(std::ostream & os, TQTaggable& tags){
  // write the footer of the cut diagram file to a stream
  
  //tag documentation see writeDiagramHeader
  bool standalone = tags.getTagBoolDefault("standalone",false);
  TString format = tags.getTagStringDefault("format","tikz");
  if(format == "tikz"){
    os << "\\end{tikzpicture}" << std::endl;
    os << "\\endgroup" << std::endl;
  }
  if(standalone) os << "\\end{document}" << std::endl;
 
}

//__________________________________________________________________________________|___________

TString TQCut::getNodeName(){
  // retrieve the name of this node for display 

  TString name(this->GetName());
  name.ToLower();
  return TQStringUtils::makeValidIdentifier(name,TQStringUtils::lowerLetters+TQStringUtils::numerals);
}

//__________________________________________________________________________________|___________

int TQCut::writeDiagramText(std::ostream& os, TQTaggable& tags, TString pos){
  // write the code for the cut diagram corresponding to this node

  TString format = tags.getTagStringDefault("format","tikz");
  if(format == "tikz"){
 
    os << "\\node [block";
    if(!pos.IsNull()) os << ", " << pos;
    TString title = TQStringUtils::isEmpty(this->GetTitle()) ? this->GetName() : this->GetTitle();
    if(title.Contains("\\") && !title.Contains("$")) title="$"+title+"$";
    os << "] (" << this->getNodeName() << ") {" << title << "};" << std::endl;
    
  } else {
    WARNclass("unknown format '%s'!",format.Data());
    return 0;
  }
  TQCutIterator itr(fCuts);
  int width = 0;
  pos = "below=of " + this->getNodeName();
  TString anchor = "south";
  while(itr.hasNext()){
    TQCut* c = itr.readNext();
    if(!c) continue;
    int newwidth = c->writeDiagramText(os,tags,pos);
    os << "\\path [line] (node cs:name=" << this->getNodeName() << ", anchor=" << anchor << ") -| (node cs:name=" << c->getNodeName() << ", anchor=north);" << std::endl;
    pos = TString::Format("right=%d*%s+%d*(%s+2*%s) of %s",newwidth,tags.getTagStringDefault("nodes.distance","0.1cm").Data(),newwidth-1,tags.getTagStringDefault("nodes.width","10em").Data(),tags.getTagStringDefault("nodes.padding","2.5pt").Data(),c->getNodeName().Data());
    anchor = "east";
    width += newwidth;
  }
  //@tag: [showJobs] If this argument tag is set to true, the analysis jobs book at each cut are shown in the cut diagram.
  if(tags.getTagBoolDefault("showJobs",false)){
    TQAnalysisJobIterator itr(fAnalysisJobs);
    TString tmppos("below = 1mm of ");
    tmppos.Append(this->getNodeName());
    tmppos.Append(".south east");
    while(itr.hasNext()){
      TQAnalysisJob* aj = itr.readNext();
      if(!aj) continue;
      TString name = this->getNodeName() + ".job" + TString::Format("%d",itr.getLastIndex());
      os << "\\node[job, " << tmppos << "] (" << name << ") {" << aj->GetName() << "};" << std::endl;
      tmppos = "below = 1mm of " + name + ".south";
    }
  }
  return std::max(width,1);
}

//__________________________________________________________________________________|___________

bool TQCut::writeDiagramToFile(const TString& filename, const TString& options){
  // create a cut hierarchy diagram 
  TQTaggable tags(options);
  return this->writeDiagramToFile(filename,tags);
}

//__________________________________________________________________________________|___________

bool TQCut::writeDiagramToFile(const TString& filename, TQTaggable& tags){
  // create a cut hierarchy diagram 
  if(filename.IsNull()) return false;
  TQUtils::ensureDirectoryForFile(filename);
  std::ofstream of(filename.Data());
  if(!of.is_open()){
    ERRORclass("unable to open file '%s'",filename.Data());
    return false;
  }
  TQCut::writeDiagramHeader(of,tags);
  this->writeDiagramText(of,tags);
  TQCut::writeDiagramFooter(of,tags);
  return true;
}


//__________________________________________________________________________________|___________

bool TQCut::printDiagram(const TString& options){
  // create a cut hierarchy diagram 
  TQTaggable tags(options);
  return this->printDiagram(tags);
}

//__________________________________________________________________________________|___________

bool TQCut::printDiagram(TQTaggable& tags){
  // create a cut hierarchy diagram 
  TQCut::writeDiagramHeader(std::cout,tags);
  this->writeDiagramText(std::cout,tags);
  TQCut::writeDiagramFooter(std::cout,tags);
  return true;
}

//__________________________________________________________________________________|___________

TString TQCut::writeDiagramToString(TQTaggable& tags){
  // create a cut hierarchy diagram (as TString)
  std::stringstream of;
  TQCut::writeDiagramHeader(of,tags);
  this->writeDiagramText(of,tags);
  TQCut::writeDiagramFooter(of,tags);
  TString retval(of.str().c_str());
  return retval;
}

//__________________________________________________________________________________|___________

int TQCut::dumpToFolder(TQFolder * folder) {
  // dump the entire cut hierarchy to a TQFolder

  /* stop if folder to write to is invalid */
  if (!folder)
    return 0;

  /* the number of cuts dumped to the folder */
  int nCuts = 1;

  /* create a sub-folder corresponding to this cut */
  TQFolder * cutFolder = folder->getFolder(TString::Format("%s+", GetName()));

  /* stop if we failed to create the sub folder */
  if (!cutFolder)
    return 0;

  cutFolder->setTagString(".name",this->GetName());
  cutFolder->setTagString(".title",this->GetTitle());

  /* set the properties of this cut */
  cutFolder->setTagString(".cutExpression",this->getCutExpression());
  cutFolder->setTagString(".weightExpression",this->getWeightExpression());
  //@tag:[.nAnalysisJobs] This folder tag is set when exporting a TQCut to a TQFolder containing the number of analysis jobs booked at the cut.
  cutFolder->setTagInteger(".nAnalysisJobs",this->getNAnalysisJobs());
  if ( this->getSkipAnalysisJobsGlobal() ) cutFolder->setTagBool(".skipJobs",true); //only set this tag if it's relevant
  if ( fPrintResult != 0 ) cutFolder->setTagInteger(".printResult",fPrintResult); 

  /* add all the descendant cuts */
  TQIterator itr(fCuts);
  while (itr.hasNext()){
    TQCut* c = dynamic_cast<TQCut*>(itr.readNext());
    if(!c) continue;
    nCuts += c->dumpToFolder(cutFolder);
  }

  /* return the number of cuts dumped to the folder */
  return nCuts;
}


//__________________________________________________________________________________|___________
TQCut * TQCut::getCut(const TString& name) {
  // Return the cut matching "name". The hierarchy of cuts will be searched 
  // starting from this cut downwards. Please note: the result might be a null 
  // pointer, if no matching element can be found

  /* Is this instance the cut that is requested? */
  if (name.CompareTo(this->GetName()) == 0) 
    /* return this instance if it is */
    return this;

  /* if not, look for the cut that is requested
   * recursively in the list of descendant cuts */
  TQCut * found = 0;
  this->fCutItr.reset();
  while(this->fCutItr.hasNext() && !found){
    TQCut* c = this->fCutItr.readNext();
    if(c) found = c->getCut(name);
  }
  
  /* return the cut that might have been found */ 
  return found;
}

//__________________________________________________________________________________|___________
void TQCut::getMatchingCuts(TObjArray& matchingCuts, const TString& name) {
    // Add all cuts matching 'name' to the given TObjArray 'matchingCuts'. The
    // syntax of matching cuts is borrowed from TQFolder: * matches any
    // cuts/part of a cut name, ? matches exactly one cut level in the cut
    // hierarchy.

    TObjArray name_segments;
    TQIterator itr(TQStringUtils::tokenize(name, "/"),true);
    while (itr.hasNext()) {
        name_segments.Add(itr.readNext());
    }
    
    getMatchingCuts(matchingCuts, name_segments);
}

//__________________________________________________________________________________|___________
std::vector<TString> TQCut::getCutNames(const TString& cutName) {
    //give the cut name as the input (e.g. GGF_0jet_*) and get all the cutnames which starts with GGF_0jet_ as a result in form of a vector.
    std::vector<TString> cutnames;
    TObjArray matchingCuts;
    getMatchingCuts(matchingCuts, cutName);
    for (int i = 0; i < matchingCuts.GetEntries(); i++) {
        TQCut* fullcut = dynamic_cast<TQCut*>(matchingCuts.At(i));
	cutnames.push_back(fullcut->GetName());
	
    }
    return cutnames;
}

//__________________________________________________________________________________|___________
void TQCut::propagateMatchingCuts(TObjArray& matchingCuts, const TObjArray& name_segments, int offset) {
  // Propagate getMatchingCuts to all attached cuts.
  this->fCutItr.reset();
  while(this->fCutItr.hasNext()) {
    TQCut* c = this->fCutItr.readNext();
    if (c) {
        c->getMatchingCuts(matchingCuts, name_segments, offset);
    }
  }
}

//__________________________________________________________________________________|___________
void TQCut::getMatchingCuts(TObjArray& matchingCuts, const TObjArray& name_segments, int offset) {
    // Same as getMatchingCuts(TObjArray& matchingCuts, const TString& name),
    // but name is a tokenized by the directory delimiter.
    // If offset != 0, it means that the first segments have already been
    // parsed.
    
    if (offset >= name_segments.GetEntries()) {
        // offset of beyond the last name segment
        return;
    }
    
    TObjString* first_obj = dynamic_cast<TObjString*>(name_segments.At(0 + offset));
    if (!first_obj) {
        // list of path segments is empty
        return;
    }
    TString first = first_obj->GetString();
    DEBUGclass("%s: current token: %s; offset: %d", this->GetName(), first.Data(), offset);

    if (first.CompareTo("*") == 0) {
        // current path segment is an asterisk
        if (offset + 1 < name_segments.GetEntries()) {
            // part after asterisk exists
            DEBUGclass("%s: parsed asterisk; propagate next segment", this->GetName());

            // * matches none
            getMatchingCuts(matchingCuts, name_segments, offset + 1);

            if (offset != 0) {
                DEBUGclass("%s: propagate asterisk", this->GetName());
                // * matches many
                propagateMatchingCuts(matchingCuts, name_segments, offset);
            }
        } else {
            // asterisk is final part
            DEBUGclass("%s: parsed asterisk; asterisk is final part", this->GetName());
            if (matchingCuts.IndexOf(this) == -1) {
                // add only if not in list
                matchingCuts.Add(this);
            }
            DEBUGclass("%s: added <----", this->GetName());

            if (offset != 0) {
                DEBUGclass("%s: propagate asterisk", this->GetName());
                propagateMatchingCuts(matchingCuts, name_segments, offset);
            }
        }

    } else if (first.CompareTo("?") == 0) {
        // current path segment is an question mark
        if (offset + 1 < name_segments.GetEntries()) {
            // part after question mark exists
            DEBUGclass("%s: parsed question mark; propagate next segment", this->GetName());

            if (isResidualMatchingSegmentOptional(name_segments, offset)) {
                // path ends in a(n) (series of) asterisk(s)
                DEBUGclass("%s: residual is optional; added <----", this->GetName());
                if (matchingCuts.IndexOf(this) == -1) {
                    // add only if not in list
                    matchingCuts.Add(this);
                }
            }
            // consuming the wildcard, and propagate
            propagateMatchingCuts(matchingCuts, name_segments, offset + 1);
        } else {
            // question mark is final part
            DEBUGclass("%s: parsed question mark; wildcard is final part", this->GetName());
            if (matchingCuts.IndexOf(this) == -1) {
                // add only if not in list
                matchingCuts.Add(this);
            }
            DEBUGclass("%s: added <----", this->GetName());
        }

    } else {
        // regular path segment
        DEBUGclass("%s: regular path segment (%s)", this->GetName(), first.Data());
        if (TQStringUtils::matches(this->GetName(), first)) {
            // the cut name matches the current name segment
            if (offset + 1 < name_segments.GetEntries()) {
                if (isResidualMatchingSegmentOptional(name_segments, offset)) {
                    // path ends in a(n) (series of) asterisk(s)
                    DEBUGclass("%s: residual is optional; added <----", this->GetName());
                    if (matchingCuts.IndexOf(this) == -1) {
                        // add only if not in list
                        matchingCuts.Add(this);
                    }
                }

                // there are other segments
                DEBUGclass("%s: matched; propagate next segment", this->GetName());
                propagateMatchingCuts(matchingCuts, name_segments, offset + 1);

            } else {
                // this was final segment
                DEBUGclass("%s: this was final; added <----", this->GetName());
                if (matchingCuts.IndexOf(this) == -1) {
                    // add only if not in list
                    matchingCuts.Add(this);
                }
            }
        }
    }

    if (offset == 0) {
        // no name segments have been matched so far
        // also search recursively for other matching cuts, 
        DEBUGclass("%s: offset==0, propagate recursively", this->GetName());
        propagateMatchingCuts(matchingCuts, name_segments, 0);
    }
}

//______________________________________________________________________________________________
bool TQCut::isResidualMatchingSegmentOptional(const TObjArray& name_segments, int offset) {
  // check if residual parts are optional
  for (int i = offset + 1; i < name_segments.GetEntries(); i++) {
      TObjString* obj = dynamic_cast<TObjString*>(name_segments.At(i));
      if (!obj) { continue; }
      TString seg = obj->GetString();
      if (seg.CompareTo("*") != 0) {
          return false;
      }
  }
  return true;
}

//______________________________________________________________________________________________

TObjArray * TQCut::getCuts() {
  // Return the list of descendant cuts of this instance 
  return fCuts;
}


//______________________________________________________________________________________________

TObjArray * TQCut::getJobs() {
  // Return the list of analysis jobs at this cut
  return fAnalysisJobs;
}


//______________________________________________________________________________________________

void TQCut::setCuts(TObjArray* cuts){
  // set the internal list of descendant cuts to something different
  fCuts = cuts;
}

//______________________________________________________________________________________________

void TQCut::printAnalysisJobs(const TString& options) {
  // print the list of analysis jobs directly appended to this cut
  TQAnalysisJobIterator itr(this->fAnalysisJobs);
  while(itr.hasNext()){
    TQAnalysisJob* job = itr.readNext();
    job->print(options);
  }
}
  

//______________________________________________________________________________________________

TObjArray * TQCut::getListOfCuts() {
  // Return a list of all cuts in the hierarchy of cuts starting 
  // from this cut downwards

  /* create a new TObjArray and add 
   * this instance of TQCut */
  TObjArray * result = new TObjArray();
  result->Add(this);

  if(!this->fCuts){
    ERRORclass("unable to retrieve child list from cut '%s'!",this->GetName());
    return result;
  }

  /* add the descendant cuts recursively */
  TQCutIterator itr(fCuts);
  while(itr.hasNext()){
    TQCut* c = itr.readNext();
    if(!c) continue;
    TObjArray* list = c->getListOfCuts();
    if(!list){
      ERRORclass("unable to retrieve child list from cut '%s'!",c->GetName());
      continue;
    }
    result->AddAll(list);
    delete list;
  }
 
  /* return the list */
  return result;

}

//______________________________________________________________________________________________


TObjArray* TQCut::getOwnBranches() {
  // add the branches needed by this cut to the internal branch list
  if(!this->fSample){
    throw std::runtime_error(TString::Format("TQCut '%s': cannot retrieve branches on uninitialized object!", this->GetName()).Data());
  }
  TObjArray* branchNames = new TObjArray();

  if(this->fCutObservable){
    DEBUGclass("retrieving branches from cutObservable %s %s", this->getCutExpression().Data(), this->fCutObservable->ClassName());
    TCollection* cutBranches = this->fCutObservable->getBranchNames();
    if(cutBranches){
      cutBranches->SetOwner(false);
      branchNames->AddAll(cutBranches);
      delete cutBranches;
    }
  }
  if(this->fWeightObservable){
    DEBUGclass("retrieving branches from weightObservable %s %s", this->getWeightExpression().Data(), this->fWeightObservable->ClassName());
    TCollection* weightBranches = this->fWeightObservable->getBranchNames();
    if(weightBranches){
      weightBranches->SetOwner(false);
      branchNames->AddAll(weightBranches);
      delete weightBranches;
    }
  }
  if (this->fVariantStack.size()>0) {
    //also consider branches from variants' cut/weight Obs
    for (VariantHandle& variant : this->fVariantStack.back()->payload) {
      if (variant.cutObs) {
        TCollection* varCutBranches = variant.cutObs->getBranchNames();
        if(varCutBranches){
          varCutBranches->SetOwner(false);
          branchNames->AddAll(varCutBranches);
          delete varCutBranches;
        }
      }
      if (variant.weightObs) {
        TCollection* varWeightBranches = variant.weightObs->getBranchNames();
        if(varWeightBranches){
          varWeightBranches->SetOwner(false);
          branchNames->AddAll(varWeightBranches);
          delete varWeightBranches;
        }
      }
    }
  }
  return branchNames;
}

//______________________________________________________________________________________________

TObjArray* TQCut::getListOfBranches() {
  // collect all used branch names from cuts, weights and analysis jobs
  // and return then in a TObjArray* of TObjString

  TString expr;
  DEBUGclass("getting own branches");
  TObjArray* branchNames = this->getOwnBranches();

  DEBUGclass("getting analysis job branches");
  {
    //if we skip our analysis jobs, then they haven't been initialized and would complain about being asked for branch names!
    if ( (!this->fSkipAnalysisJobs) && (!this->fSkipAnalysisJobsGlobal) ) {
      /* get all branch names from analysis jobs */
      if (this->fVariantStack.size()==0) {
        TQAnalysisJobIterator itr(fAnalysisJobs);
        while(itr.hasNext()){
          TQAnalysisJob* job = itr.readNext();
          if(!job) continue;
          TObjArray* bNames = job -> getBranchNames();
          
    #ifdef _DEBUG_
          if(bNames && bNames->GetEntries()>0){
            DEBUGclass("recieved list of branches from analysis job '%s':",job->GetName());
            bNames->Print();
          } else {
            DEBUGclass("recieved empty list of branches from analysis job '%s'",job->GetName());
          }
    #endif

          /* strip all valid branch names from each string */
          if(bNames){
            branchNames -> AddAll(bNames);
            bNames->SetOwner(false);
            delete bNames;
          }
        }
      } else {
        //we have variants, so we need to ask them
        for (VariantHandle& variant : this->fVariantStack.back()->payload) {
          for (TQAnalysisJob* anaJob : variant.analysisJobs) {
            if (!anaJob) continue;
            TObjArray* bNames = anaJob->getBranchNames();
            if (bNames) {
              branchNames -> AddAll(bNames);
              bNames->SetOwner(false);
              delete bNames;
            }
          }
        }
      
      }
    }
  }

  DEBUGclass("getting sub-cut branches");
  {
    TQCutIterator itr(fCuts);
    while(itr.hasNext()){
      TQCut* cut = itr.readNext();
      if(!cut) continue;
      TObjArray* bNames = cut -> getListOfBranches();
      if(bNames){
        branchNames ->AddAll(bNames);
        bNames->SetOwner(false);
        delete bNames;
      }
    }
  }

  DEBUGclass("merging branches");
  TQToken* tok = this->fSample ? this->fSample->getTreeToken() : NULL;
  if(tok){
    tok->setOwner(this);
    TTree* tree = (TTree*)(tok->getContent());
    if(tree){
      TQIterator itr(branchNames);
      while(itr.hasNext()){
        TObject* obj = itr.readNext();
        TString name(obj->GetName());
        if(name.First('*') == kNPOS && !tree->FindBranch(obj->GetName())){
          branchNames->Remove(obj);
          delete obj;
        }
      }
    }
    this->fSample->returnTreeToken(tok);
  }
 
  branchNames -> Compress();
  //branchNames->Print();
  /* remove duplicated names */
  for (int iName = 0; iName < branchNames -> GetEntries(); iName++) {
    TString name1 = branchNames -> At(iName)->GetName();
    for (int jName = branchNames->GetEntries()-1; jName > iName; jName--) {
      TString name2 = branchNames -> At(jName)->GetName();
      if (name1 == name2) {
        branchNames -> RemoveAt(jName);
      } 
    }
    branchNames -> Compress();
  }
  return branchNames;
}


//______________________________________________________________________________________________

bool TQCut::addAnalysisJob(TQAnalysisJob * newJob_, const TString& cuts_) {
  // add a new analysis job to this cut
  // and any descendent cuts matching the string

  /* stop if no analysis job is given */
  if (!newJob_) { return false; }

  if (cuts_.IsNull()) {

    /* make a copy of the job */
    TQAnalysisJob * newJob = newJob_->getClone();

    /* set the parent cut of the analysis job */
    newJob->setCut(this);

    // meaningful title for analysis job
    newJob->SetTitle(TString::Format("%s @ %s", newJob->IsA()->GetName(), this->GetName()));

    /* add this job to the list */
    fAnalysisJobs->Add(newJob);
 
    return true;

  } 

  TString cuts = TQStringUtils::trim(cuts_);
 
  /* prepare the list of cuts */

  bool success = true;
 
    /* loop over all cuts given in the list */
    TQIterator itr(TQStringUtils::tokenize(cuts_), true);
    while(itr.hasNext()){
      TObject* obj = itr.readNext();
      if(!obj) continue;

      /* extract the name */
      TString cutName = TQStringUtils::trim(obj->GetName());

      TObjArray matchingCuts;
      getMatchingCuts(matchingCuts, cutName);
      if (matchingCuts.GetEntries() == 0) {
        ERRORclass("unable to find cut '%s'",cutName.Data());
        success = false;
      }
      for (int i = 0; i < matchingCuts.GetEntries(); i++) {
        TQCut* cut = dynamic_cast<TQCut*>(matchingCuts.At(i));
        if (!cut) {
            continue;
        }
        if (!cut->addAnalysisJob(newJob_)) {
             success = false;
        }
      }
    } 
 
  return success;
}


//______________________________________________________________________________________________

bool TQCut::executeAnalysisJobs(double weight) {
  // Execute analysis jobs attached to this cut instance. The parameter
  // "weight" will be propagated to the job's execute(...) methods.
  // Returns true if every job's execute(...) method returned true and
  // false otherwise

  if (this->fSkipAnalysisJobs || this->fSkipAnalysisJobsGlobal) {
    return true;
  }
  
  DEBUGclass("executing %d analysis jobs at cut '%s'",fAnalysisJobs->GetEntriesFast(),this->GetName());
  bool success = true;
  this->fJobItr.reset();
  while(this->fJobItr.hasNext()){
    TQAnalysisJob* j = this->fJobItr.readNext();
    if(!j){
      throw std::runtime_error("encountered NULL job in execute!");
    }
    DEBUGclass("executing job '%s'",j->GetName());
    success =  j->execute(weight) && success;
    DEBUGclass("done executing job!");
  }

  return success;
}


//______________________________________________________________________________________________

int TQCut::getNAnalysisJobs() {
  // Return the number of analysis jobs attached to 
  // this cut

  return fAnalysisJobs->GetEntriesFast();
}


//______________________________________________________________________________________________

bool TQCut::passed(bool doPrint) const {
  // checks if the currently investigated event passes this cut
  if(!fCutObservable){
    if (doPrint) INFOclass("[TreeIndex: %ld] Cut '%s' passed (no Observable assinged)", this->fTree?this->fTree->GetReadEntry():-1, this->GetName());
    // DEBUGclass("%s: passed, observable NULL",this->GetName());
    return true;
  }
  DEBUGclass("checking '%s'...",this->GetName());
  //  try {
  const double val = fCutObservable->getValue();
  if (doPrint) {
    INFOclass("[TreeIndex: %ld] Cut '%s' %s, cutObservable evaluates to %f", this->fTree?this->fTree->GetReadEntry():-1, this->GetName(), val!=0 ? "passed" : "failed", val);
  }
  return (val != 0);
  //  } catch (const std::exception& e){
  //    BREAK("ERROR in '%s': %s",fCutObservable->GetName(),e.what());
  //  }
  // DEBUGclass("%s: %s == %f",this->GetName(),fCutObservable->getActiveExpression().Data(),val);
  return false;
}


//______________________________________________________________________________________________

bool TQCut::passedGlobally() const {
  // checks if the currently investigated event passes this cut and all parent cuts
  return (!fBase || fBase->passedGlobally()) && this->passed();
}


//______________________________________________________________________________________________

double TQCut::getWeight(bool doPrint) const {
  // retrieve the weight assigned to the current event at this cut
  if (fWeightObservable){
    DEBUGclass("retrieving weight for '%s'...",this->GetName());
    // std::cout << this->GetName() << ":" << fWeightObservable->getExpression() << " = " << fWeightObservable->getValue() << std::endl;
    // std::cout << this->fWeightObservable->getValue() << ": "; this->printWeightComponents();
    if (doPrint) {
      double weight = fWeightObservable->getValue();
      INFOclass("    [TreeIndex: %ld] Cut '%s' applies (multiplicative) weight %f", this->fTree?this->fTree->GetReadEntry():-1, this->GetName(), weight);
      return weight; //minor optimization, avoiding re-evaluation in case weight Observable is not caching
    }
    return fWeightObservable->getValue();
  } 
  if (doPrint) {
    INFOclass("    [TreeIndex: %ld] Cut '%s' applies (multiplicative) weight %f (no weight Observable assigned)", this->fTree?this->fTree->GetReadEntry():-1, this->GetName(), 1.0);
  }
  return 1.;
}


//______________________________________________________________________________________________

double TQCut::getGlobalWeight() const {
  // retrieve the weight assigned to the current event by this cut and all parent cuts
  return getWeight() * (fBase ? fBase->getGlobalWeight() : 1.);
}


//______________________________________________________________________________________________

bool TQCut::skipAnalysisJobs(TQSampleFolder * sf) {
  // skips the analysis jobs for some folder

  if (!sf) {
    return false;
  }

  TString skipList;
  //@tag:[~.cc.skipAnalysisJobs] SampleFolder tag specifying a csv list of cuts where the execution of analysis jobs should be skipped. 
  if (!sf->getTagString("~.cc.skipAnalysisJobs", skipList)) {
    return false;
  }

  TQIterator itr(TQStringUtils::tokenize(skipList, ",", true), true);
  while (itr.hasNext()) {
    TString item = itr.readNext()->GetName();
    if ((item.CompareTo("*") == 0) || (TQStringUtils::removeTrailing(item, "*", 1) && this->isDescendantOf(item))
        || (item.CompareTo(this->GetName()) == 0)) {
      //@tag: [.cc.nSkippedAnalysisJobs.<cutName>] This sampleFolder tag contains the number of analysis jobs skipped.
      sf->setTagInteger(TString::Format(".cc.nSkippedAnalysisJobs.%s", this->GetName()),
                        fAnalysisJobs->GetEntriesFast());
      return true;
    }
  }

  return false;
}


//______________________________________________________________________________________________

bool TQCut::isDescendantOf(TString cutName) {
  // returns true if this cut is a descendant of the cut identified by the name given as argument 
  // returns false otherwise

  if (fBase) {
    if (cutName.CompareTo(fBase->GetName()) == 0) {
      // parent cut is the one looked for
      return true;
    } else {
      // check parent cut
      return fBase->isDescendantOf(cutName);
    }
  } else {
    // no parent cut present
    return false;
  }
}

//______________________________________________________________________________________________

bool TQCut::initializeObservables() {
  // initialize the observables directly related to this cut on the given sample
  DEBUGclass("\tcut: %s",this->fCutExpression.Data());
  DEBUGclass("\tweight:%s",this->fWeightExpression.Data());

  if(!this->fCutExpression.IsNull() ){
    this->fCutObservable = TQObservable::getObservable(this->fCutExpression,this->fSample);
    if(!this->fCutObservable) return false;
    if(!fCutObservable->initialize(this->fSample)){
      ERRORclass("Failed to initialize cut observable with expression '%s' for cut '%s'.",this->fCutExpression.Data(),this->GetName());
      this->fCutObservable = NULL;
      return false;
    }
    //#ifdef _DEBUG_
//    if(!TQStringUtils::equal(fCutObservable->getExpression(),this->fCutExpression.Data())){
//      throw std::runtime_error(TString::Format("cut '%s' has retrieved dissonant cut observable '%s' for '%s'",this->GetName(),fCutObservable->getExpression().Data(),this->fCutExpression.Data()).Data());
//    }
    //#endif
    DEBUGclass("cut '%s' with expression '%s' has retrieved cut observable '%s' with expression '%s'",this->GetName(),this->fCutExpression.Data(),this->fCutObservable->GetName(),this->fCutObservable->getExpression().Data());
  }

  if(!this->fWeightExpression.IsNull() ){
    this->fWeightObservable = TQObservable::getObservable(this->fWeightExpression,this->fSample);
    if(!this->fWeightObservable) return false;
    if(!fWeightObservable->initialize(this->fSample)){
      ERRORclass("Failed to initialize weight observable with expression '%s' for cut '%s'.",this->fWeightExpression.Data(),this->GetName());
      this->fWeightObservable = NULL;
      this->fCutObservable = NULL;
      return false;
    }
    //#ifdef _DEBUG_
//    if(!TQStringUtils::equal(fWeightObservable->getExpression(),this->fWeightExpression.Data())){
//      throw std::runtime_error(TString::Format("cut '%s' has retrieved dissonant weight observable '%s' for '%s'",this->GetName(),fWeightObservable->getExpression().Data(),this->fWeightExpression.Data()).Data());
//    }
    //#endif
    DEBUGclass("cut '%s' with expression '%s' has retrieved weight observable '%s' with expression '%s'",this->GetName(),this->fWeightExpression.Data(),this->fWeightObservable->GetName(),this->fWeightObservable->getExpression().Data());
  }
  return true;
}

//______________________________________________________________________________________________

bool TQCut::finalizeObservables() {
  // finalize the observables directly related to this cut on the given sample

  bool retval = true;
  if (fCutObservable){
    DEBUGclass("finalizing observable '%s'",this->fCutObservable->GetName());
    if(!fCutObservable->finalize()) retval = false;
    this->fCutObservable = NULL;
  }
  
  if (fWeightObservable){
    DEBUGclass("finalizing observable '%s'",this->fWeightObservable->GetName());
    if(!fWeightObservable->finalize()) retval = false;
    this->fWeightObservable = NULL;
  }
  return retval;
}

//______________________________________________________________________________________________

bool TQCut::initializeVariants(TQSample* sample, bool hasNewVariantLayer) {
  bool success = true;
  for (VariantHandle& variant : this->fVariantStack.back()->payload) {
    variant.nominalSFs.push_back(sample);
    if (!hasNewVariantLayer) {
      //we first need to retrieve the variant SampleFolder to initialize with
      TQSample* variantSF = variant.variantSFs.back()->getSample(sample->GetName());
      if (!variantSF) {
        variant.variantSFs.back()->print("dt");
        throw std::runtime_error(TString::Format("[Cut: %s] Failed to find variant SampleFolder with name '%s' within variant SampleFolder with path '%s'. Contents of the latter are printed above",this->GetName(),sample->GetName(), variant.variantSFs.back()->getPath().Data()).Data());
      }
      variant.variantSFs.push_back(variantSF); //add it to the stack of the variant
    }
    TQSample* asSample = dynamic_cast<TQSample*>(variant.variantSFs.back());
    //make sure the variant sample does NOT handle anything file related - 
    //it's not in any friends list and would create a huge mess with multiple seemingly identical file handles
    asSample->setProxySample(sample);
    //propagate possible adjusted normalization (e.g. when restricting the number of events per sample)
    //asSample->setNormalisation(sample->getNormalisation()); 
    
    if (!asSample) {
      //this really shouldn't happen...
      throw std::runtime_error("Internal logic error: somehow the top of the initialization stack is not a TQSample while trying to initialize on one...");
    }
    if ( (!this->fSkipAnalysisJobs) && (!this->fSkipAnalysisJobsGlobal) ) {
      for (TQAnalysisJob* anaJob : variant.analysisJobs) {
        if (!anaJob->initialize(asSample )) {
          success = false;
        }
      }
    }
    //obtain and initialize cut/weight Observables where needed
    if(!variant.cutExpression.IsNull() ){
      variant.cutObs = TQObservable::getObservable(variant.cutExpression,asSample);
      if(!variant.cutObs) return false;
      if(!variant.cutObs->initialize(asSample)){
        ERRORclass("Failed to initialize variant cut observable with expression '%s' for cut '%s'.",variant.cutExpression.Data(),this->GetName());
        variant.cutObs = nullptr;
        return false;
      }
    }
    if(!variant.weightExpression.IsNull() ){
      variant.weightObs = TQObservable::getObservable(variant.weightExpression,asSample);
      if(!variant.weightObs) return false;
      if(!variant.weightObs->initialize(asSample)){
        ERRORclass("Failed to initialize variant weight observable with expression '%s' for cut '%s'.",variant.weightExpression.Data(),this->GetName());
        variant.weightObs = nullptr;
        return false;
      }
    }
  }
  return success;
}

//______________________________________________________________________________________________

bool TQCut::verifyVariantSetup(const std::vector<VariantHandle>& parentHandles) {
  bool allGood = ( this->fVariantStack.back()->payload.size() == parentHandles.size() );
  if (allGood) {
    for (size_t index=0; index < parentHandles.size(); ++index) {
      const VariantHandle& myVariant  = this->fVariantStack.back()->payload[index];
      const VariantHandle& parVariant = parentHandles[index];
      allGood = allGood && ( myVariant.variantSFs.back() == parVariant.variantSFs.back() );
      allGood = allGood && ( myVariant.nominalSFs.back() == parVariant.nominalSFs.back() );
    }
  }
  
  if (!allGood) {
    throw std::runtime_error(TString::Format("Inconsistent setup of variants between different TQCut instances detected at cut '%s'- please contact experts!", this->GetName()).Data());
  }
  
  if(fCuts){
    /* verify descendant cuts */
    DEBUGclass("iterating over child cuts");
    this->fCutItr.reset();
    while(this->fCutItr.hasNext()){
      TQCut* c = this->fCutItr.readNext();
      if(!c) throw std::runtime_error("encountered NULL cut");
      allGood = allGood && c->verifyVariantSetup(this->fVariantStack.back()->payload); 
    }
  }
  return allGood;
}

//______________________________________________________________________________________________

bool TQCut::initialize(TQSample* sample){ 
  // publicly accessible interface
  
  //note: variantDefs only applies to the current SF!
  TQCut::VariantDefinitionList* variationDefs = getVariantDefinitions(sample);

  bool retVal = this->initialize(sample, variationDefs);
  
  delete variationDefs;
  variationDefs=nullptr;
  return retVal;
}

//______________________________________________________________________________________________

bool TQCut::initialize(TQSample * sample, const TQCut::VariantDefinitionList* variantDefs) {
  // initialize this cut and all observables on the given sample
  if (!sample) {
    throw std::runtime_error(TString::Format("cannot initialize cut '%s' with NULL sample",this->GetName()).Data());
    return false;
  }
  
  TQSampleFolder* previousInit = fInitializationHistory.size()>0 ? fInitializationHistory[fInitializationHistory.size()-1] : nullptr;
  if ( previousInit && !(previousInit->areRelated(sample)>0) ) { //this cut was initialized before on a sample folder but the sample is not a descendant folder of the sample folder -> things are prone to get inconsistent here, abort!
    throw std::runtime_error(TString::Format("Caught attempt to initialize cut '%s' using sample with path '%s' while it was previously initialized on sample folder '%s'. Either TQCut::finalizeSampleFolder was not called correctly or something went terribly wrong.", this->GetName(), sample->getPath().Data(), previousInit->getPath().Data() ).Data());
    return false;
  }
  
  if (fTreeToken){ 
    return false;
  }
 
  DEBUGclass("retrieving tree");

  /* try to get tree token */
  this->fTreeToken = sample->getTreeToken();
 
  if (!this->fTreeToken){
    throw std::runtime_error(TString::Format("unable to initialize cut '%s': unable to obtain tree token",this->GetName()).Data());
    DEBUGclass("unable to retrieve tree token");
    return false;
  }

  this->fTreeToken->setOwner(this);
  this->fSample = sample;
  this->fTree = (TTree*)(fTreeToken->getContent());

  if(!fTree){
    DEBUGclass("received invalid tree pointer");
    sample->returnTreeToken(fTreeToken);
    throw std::runtime_error(TString::Format("unable to initialize cut '%s': received invalid tree pointer",this->GetName()).Data());
    return false;
  }
  
  bool hasNewVariantLayer = false;
  if (variantDefs) { //we need to fan out and create new variants
    createVariants(sample, variantDefs);
    hasNewVariantLayer = true;
  }
  
  // check whether to skip assiociated analysis jobs for this sample
  this->fSkipAnalysisJobs = skipAnalysisJobs(sample);

  if(fCuts){
    /* initialize descendant cuts */
    DEBUGclass("iterating over child cuts");
    this->fCutItr.reset();
    while(this->fCutItr.hasNext()){
      TQCut* c = this->fCutItr.readNext();
      if(!c) throw std::runtime_error("encountered NULL cut");
      if(!c->initialize(sample, variantDefs)) throw std::runtime_error(TString::Format("unable to initialize cut '%s'",c->GetName()).Data());
    }
  }
  /* initialize analysis jobs */
  if (this->fVariantStack.size()==0) {
    if ( (!this->fSkipAnalysisJobs) && (!this->fSkipAnalysisJobsGlobal) ) {
      DEBUGclass("iterating over analysis jobs for cut '%s'",this->GetName());
      TQAnalysisJobIterator itr(fAnalysisJobs);
      while(itr.hasNext()){
        TQAnalysisJob* job = itr.readNext();
        if(!job) throw std::runtime_error("encountered NULL job");
        if(!job->initialize(sample)) throw std::runtime_error(TString::Format("unable to initialize analysis job %s at %s",job->GetName(),this->GetName()).Data());
      }
    }
  } else {
    //we have active variants, so initialize analysisJobs of these instead
    this->initializeVariants(sample,hasNewVariantLayer);
    //TODO: verify that variants are consistent with other cuts (if this is the base cut)
    if (!this->fVariantResults) {
      this->fVariantResults = new VariantResults;
      size_t nVariants = this->fVariantStack.back()->payload.size();
      this->fVariantResults->resize(nVariants);
      if (!this->verifyVariantSetup(this->fVariantStack.back()->payload)) {
        return false;
      }
    } else {
      throw std::runtime_error("found already existing VariantResults pointer during cut initialization - this should not happen!");
      return false;
    }
  }
  //note: regular cut/weigth observables act as fallbacks if the respective is not defined for a variant, so we need them in any case!
  if(!this->initializeObservables()) {
    throw std::runtime_error(TString::Format("unable to initialize observables for cut '%s'",this->GetName()).Data());
  }
  return true;
}

//______________________________________________________________________________________________

bool TQCut::finalizeVariants() {
  bool success = true;
  size_t nStacksEmpty = 0;
  for (VariantHandle& variant : this->fVariantStack.back()->payload) {
    //first loop: finalize AnalysisJobs and directly used Observables
    if ( (!this->fSkipAnalysisJobs) && (!this->fSkipAnalysisJobsGlobal) ) {
      for (TQAnalysisJob* anaJob : variant.analysisJobs) {
        if (!anaJob->finalize()) {
          success = false;
        }
      }
    }
    //finalize cut/weight Observables where needed
    if (variant.cutObs) {
      success = variant.cutObs->finalize() && success;
      variant.cutObs = nullptr; //ownership remains with ObservableManager, don't delete Observables!
    }
    if (variant.weightObs) {
      success = variant.weightObs->finalize() && success;
      variant.weightObs = nullptr; //ownership remains with ObservableManager, don't delete Observables!
    }
    
  }
  
  // the split into two separate loops is required here
  
  for (VariantHandle& variant : this->fVariantStack.back()->payload) {
    //second loop: remove proxy links and pop stacks
    TQSample* asSample = dynamic_cast<TQSample*>(variant.variantSFs.back());
    if (!asSample) {
      //this really shouldn't happen...
      throw std::runtime_error("Internal logic error: somehow the top of the initialization stack is not a TQSample while trying to finalize on one...");
    }
    TQSample* asNominalSample = dynamic_cast<TQSample*>(variant.nominalSFs.back());
    if (!asNominalSample) {
      //this really shouldn't happen...
      throw std::runtime_error("Internal logic error: somehow the top of the nominal initialization stack is not a TQSample while trying to finalize on one...");
    }
    //note: we rely here on the visitor stamping samples before asking cuts to finalize!
    asSample->mergeTags(asNominalSample);
    
    // remove the connection between the nominal and variant sample again 
    // to avoid potential dangling pointers!
    // do this at the very end, else Observables can't return their tokens correctly!
    // (they might even use a different variant Sample internally as we don't create 
    // copies for each variant (unlike for channels!). Hence, need to remove this once
    // all variants have finalized everything that might have a token
    // also, only do this from the base cut, else we remove the link while other cuts
    // may still have AnalysisJobs/Observables to finalize!
    if (!fBase) asSample->setProxySample(nullptr);
    variant.variantSFs.pop_back();
    variant.nominalSFs.pop_back();
    if (variant.variantSFs.empty()) {
      nStacksEmpty++;
      for (TQAnalysisJob* anaJob : variant.analysisJobs) {
        delete anaJob;
      }
    }
  }
  //if we exhausted the variant SampleFolder stack for this layer of variants, clean it up
  if (nStacksEmpty == this->fVariantStack.back()->payload.size()) {
    VariantStackElement* toDelete = this->fVariantStack.back();
    this->fVariantStack.pop_back();
    delete toDelete;
  } else if (nStacksEmpty > 0) {
    //something is off, the individual variants' SampleFolder stacks should always have the same size!
    throw std::runtime_error("Inconsistent stack sizes of variants SampleFolder stacks detected, please inform experts!");
    return false;
  }
  return success;
}

bool TQCut::finalize() {
  // finalize this cut and all observables on the given sample
  this->finalizeObservables();

  bool success = true;
  
  /* finalize descendant cuts */
  this->fCutItr.reset();
  while(this->fCutItr.hasNext()){
    TQCut* cut = this->fCutItr.readNext();
    if(!cut) continue;
    if(!cut->finalize()) success = false;
  }

  /* finalize analysis jobs */
  if (this->fVariantStack.size()==0) {
    if ( (!fSkipAnalysisJobsGlobal) && (!fSkipAnalysisJobs) ) { //only finalize if they were also initialized
      this->fJobItr.reset();
      while(this->fJobItr.hasNext()){
        TQAnalysisJob* job = this->fJobItr.readNext();
        if(!job) continue;
        if(!job->finalize()) success = false;
      }
    }
  } else {
    success = this->finalizeVariants() && success;
    if (this->fVariantResults) {
      delete this->fVariantResults;
      this->fVariantResults = nullptr; 
    }
  }
  
  if(this->fSample){
    success = this->fSample->returnToken(this->fTreeToken) && success;
  }
  
  this->fTreeToken = 0;
  this->fSample = 0;
  this->fTree = 0;
  
  return success;
}

//______________________________________________________________________________________________

bool TQCut::canInitialize(TQSampleFolder* sf) const {
  // returns true if the sample folder is eligible for initializing this cut on
  if (!sf) return false;
  TQSampleFolder* previousInit = fInitializationHistory.size()>0 ? fInitializationHistory[fInitializationHistory.size()-1] : nullptr;
  if ( previousInit && !(previousInit->areRelated(sf)>0) ) { //this cut was initialized before on a sample folder but the new folder (sf) is not a descendant folder of the previous one -> This is not a valid sample folder to initialize this cut on!
    DEBUGclass("Sample (folder) with path '%s' is not eligible for initializing cut '%s'. The cut was last initialized on '%s'.",sf->getPath().Data(),this->GetName(),previousInit->getPath().Data());
    return false;
  }
  return true; //no reason not to initialize, go ahead!
}

//______________________________________________________________________________________________



int TQCut::createVariantFolders(TQSampleFolder* sf, const TQCut::VariantDefinitionList* variantDefs) { //, std::vector<TQSampleFolder*>& variantFolders) {
  //returns the number of variants folders created or -1 in case of an error
  if (!variantDefs) return -1;
  int nCreated = 0;
  for (auto const& [name, varDefs] : *variantDefs) {
    //for (const VariantDefinition& varDef : varDefs) {
      //if (TQStringUtils::matchesFilter(this->GetName(), varDef.matchingPattern, ",", true)) {
        //we got a match, so set up things for running over this variant
        TQSampleFolder* base = sf->getBaseSampleFolder();
        if (!base) {
          throw std::runtime_error("Cannot create variants for the root node of a SampleFolder structure, please ensure that variants are only requested starting from the second folder level!");
        }
        TString varSFname = TString::Format("%s_%s",sf->GetName(), name.Data());
        TQSampleFolder* varSF = base->getSampleFolder(varSFname);
        if (!varSF) { //should we consider the else case as an error? The variant version shouldn't exist before...
          varSF = dynamic_cast<TQSampleFolder*>(sf->copy(varSFname));
          varSF->setIsVariant(true);
          base->addFolder(varSF);
          //variantFolders.push_back(varSF);
          nCreated++;
        }
      //}
    //}
  }
  return nCreated;
}

//______________________________________________________________________________________________

TQCut::VariantStackElement* TQCut::createVariantLayer(const std::vector<VariantHandle>& preceedingHandles, TQSampleFolder* nextSF, const VariantDefinitionList* variantDefs) {
  DEBUGclass("%s: function called with %d preceeding handles and %d definitions",this->GetName(),preceedingHandles.size(),variantDefs->size());  
  VariantStackElement* newElement = new VariantStackElement();
  for (const VariantHandle& preHandle : preceedingHandles) {
    TQSampleFolder* preVarSF = preHandle.variantSFs.back();
    for (auto const& [name, varDefs] : *variantDefs) {
      DEBUGclass("%s: creating new handle '%s' at '%s'",this->GetName(),name.Data(),preVarSF->getPath().Data());
      VariantHandle newHandle;
      for (TQAnalysisJob* preAnaJob : preHandle.analysisJobs) {
	if(preAnaJob->isPooling()){
	  throw std::runtime_error("Cannot create variants on a sample folder with jobs that are pooling at a higher level, please fix your pooling specifications to be more specific than your variants!");
	}
        TQAnalysisJob* anaJob = preAnaJob->getClone();
	TString jobname = TString::Format("%s.%s.%s",preAnaJob->GetName(),this->GetName(), name.Data());
	DEBUGclass("   cloning job %s",jobname.Data());
	anaJob->SetName(jobname);
        anaJob->copyTransientMembersFrom(preAnaJob);
        newHandle.analysisJobs.push_back(anaJob);
      }
      //check if there is a definition applicable to this cut
      const VariantDefinition* matchingDef = nullptr;
      for (const VariantDefinition &vd : varDefs) {
        if (TQStringUtils::matchesFilter(this->GetName(), vd.matchingPattern, ",", true)) {
          matchingDef = &vd;
          break; //we only ever consider the first matching one, otherwise there's an ambiguity
        }
      }
      //default: carry over cut and weight expression from previous layer
      newHandle.cutExpression = preHandle.cutExpression;
      newHandle.weightExpression = preHandle.weightExpression;
      //if we have a matching def then use cut/weight expressions from that one unless empty
      if (matchingDef && matchingDef->cutExpression.Length()>0) {
        newHandle.cutExpression = matchingDef->cutExpression;
      }
      if (matchingDef && matchingDef->weightExpression.Length()>0) {
        newHandle.weightExpression = matchingDef->weightExpression;
      }
      //we already set the frist nominal and variant SFs here to ensure they are well combined
      TQSampleFolder* firstVarFolder = preVarSF->getSampleFolder(TString::Format("%s_%s",nextSF->GetName(), name.Data()));
      newHandle.variantSFs.push_back(firstVarFolder);
      newHandle.nominalSFs.push_back(nextSF);
      
      //add the new element to the new layer of variants
      newElement->payload.push_back(newHandle);
      newElement->variantRoots.push_back(firstVarFolder);
    }
  
  }
  return newElement;
}

//______________________________________________________________________________________________

bool TQCut::createVariants(TQSampleFolder* nextSF, const VariantDefinitionList* variantDefs) {
  if (!nextSF || !nextSF->getBaseSampleFolder()) {
    throw std::runtime_error("Cannot create variants for the root node of a SampleFolder structure!");
    return false;
  }
  
  // since we have a new layer of variants we need to add to the variant stack (fVariantStack) 
  // even if this cut in particular is not modified (we still need to redirect/copy analysisJobs!)
  if (fVariantStack.size() == 0) { //first variant layer
    if (!fBase) {//this is the root-node cut (since it has no base)
      //create all required variant folders
      DEBUGclass("'%s': creating all variant folders at '%s'",this->GetName(),nextSF->getPath().Data());
      this->createVariantFolders(nextSF, variantDefs);
    }
    //create a temporary VariantHandle 
    VariantHandle tempHandle;
    //populate it
    //convert TObjArray of anaJobs to std::vector
    std::vector<TQAnalysisJob*> anaJobs;
    if (this->fAnalysisJobs) {
      TQAnalysisJobIterator itr(this->fAnalysisJobs,false);
      while(itr.hasNext()) {
        anaJobs.push_back(itr.readNext());
      }
    }
    tempHandle.analysisJobs = anaJobs;
    tempHandle.variantSFs.push_back(nextSF->getBaseSampleFolder());
    
    fVariantStack.push_back(this->createVariantLayer( {tempHandle}, nextSF, variantDefs ));
    
  } else { //we already have a layer of variants before
    if (!fBase) {//this is the root-node cut (since it has no base)
      //create all required variant folders
      for (const VariantHandle& preHan : fVariantStack.back()->payload) {
        TQSampleFolder* varNominal = preHan.variantSFs.back()->getSampleFolder(nextSF->GetName());//same name as nextSF but from the folder on top of the stack of the previous variant layer
        if (!varNominal) {
          throw std::runtime_error(TString::Format("Failed to create new layer of variants, could not find subfolder with name '%s' in variant folder '%s'",nextSF->GetName(),preHan.variantSFs.back()->getPath().Data()).Data());
          return false;
        }
        this->createVariantFolders(varNominal, variantDefs);
      }
    }
    fVariantStack.push_back(this->createVariantLayer( fVariantStack.back()->payload, nextSF, variantDefs ));
  }
  return true;
  
}

//______________________________________________________________________________________________

bool TQCut::initializeVariantsSampleFolder(TQSampleFolder* sf, bool hasNewVariantLayer) {
  bool success = true;
  for (VariantHandle& variant : this->fVariantStack.back()->payload) {
    variant.nominalSFs.push_back(sf);
    if (!hasNewVariantLayer) {
      //we first need to retrieve the variant SampleFolder to initialize with
      TQSampleFolder* variantSF = variant.variantSFs.back()->getSampleFolder(sf->GetName());
      if (!variantSF) {
        variant.variantSFs.back()->print("dt");
        throw std::runtime_error(TString::Format("Failed to find variant SampleFolder with name '%s' within variant SampleFolder with path '%s'. Contents of the latter are printed above",sf->GetName(), variant.variantSFs.back()->getPath().Data()).Data());
      }
      variant.variantSFs.push_back(variantSF); //add it to the stack of the variant
    }
   if ( (!this->fSkipAnalysisJobs) && (!this->fSkipAnalysisJobsGlobal) ) {
      for (TQAnalysisJob* anaJob : variant.analysisJobs) {
        if (!anaJob->initializeSampleFolder(variant.variantSFs.back() )) {
          success = false;
        }
      }
    }
  }
  return success;
}

//______________________________________________________________________________________________

bool TQCut::initializeSampleFolder(TQSampleFolder* sf){ 
  // publicly accessible interface
  
  //note: variantDefs only applies to the current SF!
  TQCut::VariantDefinitionList* variationDefs = getVariantDefinitions(sf);
  //std::vector<TQSampleFolder*> variantFolders;
  //if (variationDefs) createVariantFolders(sf, variationDefs, variantFolders);
  
  bool retVal = this->initializeSampleFolder(sf, variationDefs);//, variantFolders);
  
  delete variationDefs;
  variationDefs=nullptr;
  return retVal;
}

//______________________________________________________________________________________________

bool TQCut::initializeSampleFolder(TQSampleFolder* sf, const TQCut::VariantDefinitionList* variantDefs){
  // initialize this cut and all observables on the given sample folder
  this->initializeSelfSampleFolder(sf);
  
  //check if we are initializing on a valid sample folder, i.e., if we already initialized on some sample folder before the new one has to be a subfolder
  if ( !this->canInitialize(sf) ) { //this cut was initialized before on a sample folder but the new folder (sf) is not a descendant folder of the previous one -> things are prone to get inconsistent here, abort!
    if (!sf) {//check if it is "only" a nullptr
      WARNclass("Cannot initialize cut '%s' with a nullptr to a TQSampleFolder",this->GetName());
      return false;
    }
    TQSampleFolder* previousInit = this->fInitializationHistory.size()>0 ? fInitializationHistory[fInitializationHistory.size()-1] : nullptr;
    throw std::runtime_error(TString::Format("Caught attempt to initialize cut '%s' using sample folder with path '%s' while it was previously initialized on sample folder '%s'. Either TQCut::finalizeSampleFolder was not called or something went terribly wrong.", this->GetName(), sf->getPath().Data(), previousInit==nullptr? "<none>" : previousInit->getPath().Data() ).Data());
    return false;
  } 
  
  fInitializationHistory.push_back(sf); 
  if (!fBase) {
    DEBUGclass("Initializing cut '%s' on sample folder '%s'",this->GetName(),sf->getPath().Data());
  }
  
  bool hasNewVariantLayer = false;
  if (variantDefs) { //we need to fan out and create new variants
    createVariants(sf, variantDefs);
    hasNewVariantLayer = true;
  }
  
  bool success = true;

  /* initialize descendant cuts */
  this->fCutItr.reset();
  while(this->fCutItr.hasNext()){
    TQCut* cut = this->fCutItr.readNext();
    if(!cut) continue;
    if(!cut->initializeSampleFolder(sf,variantDefs)) success = false;
  }

  /* initialize analysis jobs */
  if (this->fVariantStack.size()==0) {
    DEBUGclass("%s: initializing sample folder '%s' without variants",this->GetName(),sf->getPath().Data());
    if ( (!fSkipAnalysisJobsGlobal) && (!fSkipAnalysisJobs) ) {
      this->fJobItr.reset();
      while(this->fJobItr.hasNext()){
        TQAnalysisJob* job = this->fJobItr.readNext();
        if(!job) continue;
        if(!job->initializeSampleFolder(sf)) success = false;
      }
    }
  } else { 
    //we have active variants, so initialize analysisJobs of these instead
    DEBUGclass("%s: initializing sample folder '%s' with variants",this->GetName(),sf->getPath().Data());    
    this->initializeVariantsSampleFolder(sf,hasNewVariantLayer);
  }
  this->fPrintResultCount = 0; //reset printout counter
  
  return success;
}

//______________________________________________________________________________________________

bool TQCut::canFinalize(TQSampleFolder* sf) const {
  // returns true if this cut was previously initialized on this sample folder
  if (!sf) return false;
  if (sf == this->fSample) return true; //the acutal sample is not stored in the fInitializationHistoy
  for (auto hist : fInitializationHistory) {
    if (sf == hist) return true;
  }
  //no folder in the history matched, i.e., this cut was not previously initialized on the sample folder
  return false;
}

//______________________________________________________________________________________________

bool TQCut::finalizeVariantsSampleFolder(TQSampleFolder* sf) {
  bool success = true;
  size_t nStacksEmpty = 0;
  std::set<TQSampleFolder*> uniqueNominals;
  for (VariantHandle& variant : this->fVariantStack.back()->payload) {
    TQSampleFolder* varSF = variant.variantSFs.back();
    if (!(variant.nominalSFs.back() == sf)) {
      //this hopefully shouldn't happen...
      throw std::runtime_error("Internal logic error: the nominal SampleFolder to finalize for does not match the nominal one in the stack");
    }
    if ( (!this->fSkipAnalysisJobs) && (!this->fSkipAnalysisJobsGlobal) ) {
      for (TQAnalysisJob* anaJob : variant.analysisJobs) {
        if (!anaJob->finalizeSampleFolder(varSF)) {
          success = false;
        }
      }
    }
    if (success) {
      //if everything is fine, mark the nominal folder for deletion
      sf->setTagBool(".asv.revisit.purge",true);
    }
    variant.variantSFs.pop_back();
    uniqueNominals.insert(variant.nominalSFs.back()); //store in case we later need to delete it
    variant.nominalSFs.pop_back();
    if (variant.variantSFs.empty()) {
      nStacksEmpty++;
      for (TQAnalysisJob* anaJob : variant.analysisJobs) {
        delete anaJob;
      }
    }
  }
  
  //if we exhausted the variant SampleFolder stack for this layer of variants, clean it up
  if (nStacksEmpty == this->fVariantStack.back()->payload.size()) {
    VariantStackElement* toDelete = this->fVariantStack.back();
    if (!fBase) { //only delete once, i.e., in the outer most iteration (the root node cut)
      for (TQSampleFolder* nom : uniqueNominals) {
        if (nom != sf) {
          //only delete if it's not the sampleFolder still being handled by the visitor
          //this applies when dealing with nested Variants where the nominal folder for the nested variant is part of the fully-nominal path but also exists in the outer Variant.
          //What we delete here is this nested-nominal folder which the visitors are unaware of but not the fully nominal one, as the visitor may still want to use it!
          delete nom;
        }
      }
    }
    this->fVariantStack.pop_back();
    delete toDelete;
  } else if (nStacksEmpty > 0) {
    //something is off, the individual variants' SampleFolder stacks should always have the same size!
    throw std::runtime_error("Inconsistent stack sizes of variants SampleFolder stacks detected, please inform experts!");
    return false;
  }
  return success;
  
  
}

//______________________________________________________________________________________________

bool TQCut::finalizeSampleFolder(TQSampleFolder* sf){
  // finalize this cut and all observables on the given sample folder
  
  //if we still have a sample we should finalize it first
  if (this->fSample && !this->finalize()) return false;
  if (!sf) return false;
  
  this->finalizeSelfSampleFolder(sf);
  
  if (!fBase) {
    DEBUGclass("Finalizing cut '%s' on sample folder '%s'. History has %d entries",this->GetName(),sf->getPath().Data(),(int)fInitializationHistory.size());
  }
  
  TQSampleFolder* lastInit = fInitializationHistory.size()>0 ? fInitializationHistory[fInitializationHistory.size()-1] : nullptr;
  while (lastInit != nullptr && (lastInit->areRelated(sf)<0) ) { //read: while the last initialization was performed on a descendant folder of sf (excluding lastInit==sf)
    if (!this->finalizeSampleFolder(lastInit)) return false; //recursively go back in history to finalize at all places this cut was initialized
    lastInit = fInitializationHistory.size()>0 ? fInitializationHistory[fInitializationHistory.size()-1] : nullptr;
  }
  //At this point lastInit should either be equal to sf (in which case areRelated returns 1) or the folders have no relation to each other (=error!). We also throw an error if it was requested to finalize this cut on any folder if it has never been initialized on a sample folder (case lastInit==nullptr).
  
  if ( !lastInit || lastInit != sf ) { //this cut was not initialized on 'sf' -> things are prone to get inconsistent here, abort!
    throw std::runtime_error(TString::Format("Caught attempt to finalize cut '%s' using sample folder with path '%s' while it was not initialized on it.", this->GetName(), sf->getPath().Data() ).Data());
    return false;
  }
  if (fInitializationHistory.size()>0) fInitializationHistory.pop_back(); //remove last element (which at this point should be ensured to be 'sf')
    
  bool success = true;

  /* finalize descendant cuts */
  this->fCutItr.reset();
  while(this->fCutItr.hasNext()){
    TQCut* cut = this->fCutItr.readNext();
    if(!cut) continue;
    if(!cut->finalizeSampleFolder(sf)) success = false;
  }

  /* finalize analysis jobs */
  if (this->fVariantStack.size()==0) {
    if ( (!fSkipAnalysisJobsGlobal) && (!fSkipAnalysisJobs) ) { //only finalize if they were also initialized
      this->fJobItr.reset();
      while(this->fJobItr.hasNext()){
        TQAnalysisJob* job = this->fJobItr.readNext();
        if(!job) continue;
        if(!job->finalizeSampleFolder(sf)) success = false;
      }
    }
  } else {
    success = finalizeVariantsSampleFolder(sf) && success;
  }
  return success;
}


//______________________________________________________________________________________________

TQCut::~TQCut() {
  // destructor
 
  /* finalize cuts */
  this->finalize();
 
  /* delete descendant cuts */
  this->fCuts->Delete();
  /* delete the list of cuts itself */
  delete fCuts;
 
  /* delete analysis jobs */
  this->fAnalysisJobs->Delete();
  /* delete the list of analysis jobs itself */
  delete fAnalysisJobs;
}

//______________________________________________________________________________________________

void TQCut::clearAnalysisJobs(){
  // clear all analysis jobs from this cut
  if(fAnalysisJobs)
    fAnalysisJobs->Delete();
}

//__________________________________________________________________________________|___________

TQCut * TQCut::getSingleCut(TString name, TString excl_pattern) {
  // Return the cut matching "name". The hierarchy of cuts will be searched 
  // starting from this cut downwards. Please note: the result might be a null 
  // pointer, if no matching element can be found
  // The difference between this function and getCut() is that this function
  // will return TQCut with standalone single cut (all the hierarchy collapsed
  // down to the cut requested.)

  TString tmpName = name;
  bool addDescendants = TQStringUtils::removeTrailing(tmpName, "*") > 0;

  /* Is this instance the cut that is requested? */
  if (tmpName.CompareTo(this->GetName()) == 0) {

    /* get base cut */
    TQCut * tmpcut = this->getBase();

    /* create return object */
    TQCut * aggregatedCut = new TQCut(this->GetName());
    TString thiscutname = this->GetName();

    if (thiscutname.Contains(excl_pattern)) {
      /* if this cut is the one being excluded the aggregated cut will start with null cut */
      aggregatedCut->setCutExpression("1");
      aggregatedCut->setWeightExpression("1");
    } else {
      /* if not we start with this cut */
      aggregatedCut->setCutExpression(this->getCutExpression());
      if (!(this->getWeightExpression().IsNull()))
        aggregatedCut->setWeightExpression(this->getWeightExpression());
      else
        aggregatedCut->setWeightExpression("1");
    }

    /* if requested also add all the necessary descendant cuts */
    if (addDescendants)
      aggregatedCut->setCuts(this->getCuts());

    while (tmpcut) {
      TString cutexprorg = aggregatedCut->getCutExpression();
      TString cutexprnew = tmpcut->getCutExpression();
      TString cutnamenew = tmpcut->GetName();
      /* if exclusion pattern exists for the cuts above we skip that one. */
      if (cutnamenew.Contains(excl_pattern)) {
        tmpcut = tmpcut->getBase();
        continue;
      }
      if (!cutexprnew.IsNull())
        aggregatedCut->setCutExpression("(" + cutexprorg + ")*(" + cutexprnew + ")");
      TString wgtexprorg = aggregatedCut->getWeightExpression();
      TString wgtexprnew = tmpcut->getWeightExpression();
      if (!wgtexprnew.IsNull())
        aggregatedCut->setWeightExpression("(" + wgtexprorg + ")*(" + wgtexprnew + ")");
      tmpcut = tmpcut->getBase();
    }

    /* before returning print the full cut expr */
    TString cutexpr = aggregatedCut->getCutExpression();
    cutexpr.ReplaceAll(" ","");
    //std::cout << "" << std::endl;
    //std::cout << name << " " << excl_pattern<< std::endl;
    //std::cout << "-----------------------" << std::endl;
    //std::cout << cutexpr << std::endl;
    //std::cout << "-----------------------" << std::endl;
    //std::cout << "" << std::endl;

    /* return the aggregatedCut if it is this. */
    return aggregatedCut;

  } else {
 
    /* if not, look for the cut that is requested
     * recursively in the list of descendant cuts */
    this->fCutItr.reset();
    while (this->fCutItr.hasNext()){
      TQCut* c = this->fCutItr.readNext();
      if(!c) continue;
      TQCut* found = c->getSingleCut(name, excl_pattern);
      if(found) return found;
    }

    /* return the cut that might have been found */ 
    return NULL;

  }
}

//__________________________________________________________________________________|___________

TQSample* TQCut::getSample(){
  // retrieve the sample currently assigned to this cut
  return this->fSample;
}


//__________________________________________________________________________________|___________

TQCut* TQCut::getClone(){
  // return a clone of this cut (and all descendants)
  TQCut* clone = nullptr;
  if (this->IsA() == TQUniqueCut::Class()) {
    //make a custom clone if it's a TQUniqueCut
    TQUniqueCut* asUnique = static_cast<TQUniqueCut*>(this);
    clone = new TQUniqueCut(asUnique->GetName(), asUnique->getRunNumberExpression(), asUnique->getEventNumberExpression()); 
    clone->SetTitle(asUnique->GetTitle());
    //cut expression is implicit for TQUniqueCut, it's decision depends solely on run and event number
    clone->setWeightExpression(asUnique->getWeightExpression());
  } else {
    clone = new TQCut(this->GetName(),this->GetTitle(),this->getCutExpression(),this->getWeightExpression());
  }
  
  clone->setSkipAnalysisJobsGlobal(this->getSkipAnalysisJobsGlobal());
  clone->setPrintResults(this->fPrintResult);
  
  this->fJobItr.reset();
  while(this->fJobItr.hasNext()){
    TQAnalysisJob* j = this->fJobItr.readNext();
    clone->addAnalysisJob(j->getClone());
  }    
  this->fCutItr.reset();
  while(this->fCutItr.hasNext()){
    TQCut* c = this->fCutItr.readNext();
    TQCut* cl = c->getClone();
    clone->addCut(cl);
  }
  return clone;
}

//__________________________________________________________________________________|___________

TQCut* TQCut::getCompiledClone(TQTaggable* tags){
  // return a clone of this cut (and all descendants)
  if(!tags) return this->getClone();
  
  TQCut* clone = new TQCut(this->GetName(),this->GetTitle(),
                           tags->replaceInText(this->getCutExpression()),
                           tags->replaceInText(this->getWeightExpression()));
  
  this->fJobItr.reset();
  while(this->fJobItr.hasNext()){
    TQAnalysisJob* j = this->fJobItr.readNext();
    clone->addAnalysisJob(j->getClone());
  }    
  this->fCutItr.reset();
  while(this->fCutItr.hasNext()){
    TQCut* c = this->fCutItr.readNext();
    TQCut* cl = c->getCompiledClone(tags);
    clone->addCut(cl);
  }
  return clone;
}


//__________________________________________________________________________________|___________

void TQCut::analyse(double weight, bool useWeights) {
  // apply this cut and execute the analyis jobs appended to this cut
  DEBUGclass("Cut: '%s' with useweights '%d", this->GetName(), useWeights);
  bool doPrint = false;
  if ( (fPrintResult>fPrintResultCount) || fPrintResult<0 ) { //we have not yet reached the number of events to be printed or have no limitation on how how many events to print
    doPrint = true;
    ++fPrintResultCount;
  }
  if (this->fVariantStack.size()==0) {
    const bool passed = this->passed(doPrint);
    if (!passed) {
      return;
    }
    DEBUGclass("passed cut '%s' with expression '%s'",this->GetName(),this->fCutObservable ? this->fCutObservable->getActiveExpression().Data() : "");
    if (useWeights) {
      weight *= this->getWeight(doPrint);
    }
    this->executeAnalysisJobs(weight);
    this->fCutItr.reset();
    while(this->fCutItr.hasNext()){
      this->fCutItr.readNext()->analyse(weight, useWeights);
    }
  } else {
    //we have variants, so forward to the suitable function
    this->analyseVariants(nullptr, useWeights, weight); //yes, the weight passed on does not include the weight of this cut, analyseVariants takes care of this itself
  } 
}

//__________________________________________________________________________________|___________

void TQCut::analyseVariants(const VariantResults* preceedingResults_, bool useWeights, double baseWeight) {
  //baseWeight is only used if no valid preceedingResults_ is given (i.e. if it's a nullptr).
  //In this case reset our own VariantResult member to baseWeight and use it as 
  //preceedingWeights. Note that this means we may not edit the pass/weight values more than once!
  const VariantResults* preceedingResults = preceedingResults_;
  if (!preceedingResults) {
    this->fVariantResults->reset(baseWeight);
    preceedingResults = this->fVariantResults;
  }
  size_t variantIndex = 0;
  bool fallBackPass = this->passed(false);
  LazyWeight fallBackWeight(this);
  for (VariantHandle& variant : this->fVariantStack.back()->payload) {
    if (variant.cutObs) {
      this->fVariantResults->passed[variantIndex] = preceedingResults->passed[variantIndex] && variant.cutObs->getValue();
    } else {
      this->fVariantResults->passed[variantIndex] = fallBackPass && preceedingResults->passed[variantIndex];
    }
    if (this->fVariantResults->passed[variantIndex]) {
      //the variant is still "alive" 
      if (variant.weightObs) {
        this->fVariantResults->weight[variantIndex] = preceedingResults->weight[variantIndex] * variant.weightObs->getValue();
      } else {
        this->fVariantResults->weight[variantIndex] = double(fallBackWeight) * preceedingResults->weight[variantIndex];
      }
    
      //execute analysisJobs
      if (this->fSkipAnalysisJobs || this->fSkipAnalysisJobsGlobal) {
        continue;
      }
      bool success = true;
      for (TQAnalysisJob* anaJob : variant.analysisJobs) {
        if(!anaJob){
          throw std::runtime_error("encountered NULL job in execute!");
        }
        DEBUGclass("executing job '%s'",anaJob->GetName());
        success =  anaJob->execute(this->fVariantResults->weight[variantIndex]) && success;
        DEBUGclass("done executing job!");
      }
      if (!success) {
        throw std::runtime_error("There was an error executing one or more AnalysisJobs at Cut '%s', variant '%s'");
      }
    }  
    
    variantIndex++;
  }
  
  if (this->fVariantResults->passAny() || this->fVariantResults->passed.size()==0) {
    //evaluate subsequent cuts
    this->fCutItr.reset();
    while(this->fCutItr.hasNext()){
      this->fCutItr.readNext()->analyseVariants(this->fVariantResults, useWeights); //we pass a valid variantResults ptr, so baseWeight would be ignored anyways
    }
  }
  
  
}

//__________________________________________________________________________________|___________

bool TQCut::initializeSelfSampleFolder(TQSampleFolder*/*sf*/){  return true;}

//__________________________________________________________________________________|___________

bool TQCut::finalizeSelfSampleFolder  (TQSampleFolder*/*sf*/){  return true;}
 TQCut.cxx:1
 TQCut.cxx:2
 TQCut.cxx:3
 TQCut.cxx:4
 TQCut.cxx:5
 TQCut.cxx:6
 TQCut.cxx:7
 TQCut.cxx:8
 TQCut.cxx:9
 TQCut.cxx:10
 TQCut.cxx:11
 TQCut.cxx:12
 TQCut.cxx:13
 TQCut.cxx:14
 TQCut.cxx:15
 TQCut.cxx:16
 TQCut.cxx:17
 TQCut.cxx:18
 TQCut.cxx:19
 TQCut.cxx:20
 TQCut.cxx:21
 TQCut.cxx:22
 TQCut.cxx:23
 TQCut.cxx:24
 TQCut.cxx:25
 TQCut.cxx:26
 TQCut.cxx:27
 TQCut.cxx:28
 TQCut.cxx:29
 TQCut.cxx:30
 TQCut.cxx:31
 TQCut.cxx:32
 TQCut.cxx:33
 TQCut.cxx:34
 TQCut.cxx:35
 TQCut.cxx:36
 TQCut.cxx:37
 TQCut.cxx:38
 TQCut.cxx:39
 TQCut.cxx:40
 TQCut.cxx:41
 TQCut.cxx:42
 TQCut.cxx:43
 TQCut.cxx:44
 TQCut.cxx:45
 TQCut.cxx:46
 TQCut.cxx:47
 TQCut.cxx:48
 TQCut.cxx:49
 TQCut.cxx:50
 TQCut.cxx:51
 TQCut.cxx:52
 TQCut.cxx:53
 TQCut.cxx:54
 TQCut.cxx:55
 TQCut.cxx:56
 TQCut.cxx:57
 TQCut.cxx:58
 TQCut.cxx:59
 TQCut.cxx:60
 TQCut.cxx:61
 TQCut.cxx:62
 TQCut.cxx:63
 TQCut.cxx:64
 TQCut.cxx:65
 TQCut.cxx:66
 TQCut.cxx:67
 TQCut.cxx:68
 TQCut.cxx:69
 TQCut.cxx:70
 TQCut.cxx:71
 TQCut.cxx:72
 TQCut.cxx:73
 TQCut.cxx:74
 TQCut.cxx:75
 TQCut.cxx:76
 TQCut.cxx:77
 TQCut.cxx:78
 TQCut.cxx:79
 TQCut.cxx:80
 TQCut.cxx:81
 TQCut.cxx:82
 TQCut.cxx:83
 TQCut.cxx:84
 TQCut.cxx:85
 TQCut.cxx:86
 TQCut.cxx:87
 TQCut.cxx:88
 TQCut.cxx:89
 TQCut.cxx:90
 TQCut.cxx:91
 TQCut.cxx:92
 TQCut.cxx:93
 TQCut.cxx:94
 TQCut.cxx:95
 TQCut.cxx:96
 TQCut.cxx:97
 TQCut.cxx:98
 TQCut.cxx:99
 TQCut.cxx:100
 TQCut.cxx:101
 TQCut.cxx:102
 TQCut.cxx:103
 TQCut.cxx:104
 TQCut.cxx:105
 TQCut.cxx:106
 TQCut.cxx:107
 TQCut.cxx:108
 TQCut.cxx:109
 TQCut.cxx:110
 TQCut.cxx:111
 TQCut.cxx:112
 TQCut.cxx:113
 TQCut.cxx:114
 TQCut.cxx:115
 TQCut.cxx:116
 TQCut.cxx:117
 TQCut.cxx:118
 TQCut.cxx:119
 TQCut.cxx:120
 TQCut.cxx:121
 TQCut.cxx:122
 TQCut.cxx:123
 TQCut.cxx:124
 TQCut.cxx:125
 TQCut.cxx:126
 TQCut.cxx:127
 TQCut.cxx:128
 TQCut.cxx:129
 TQCut.cxx:130
 TQCut.cxx:131
 TQCut.cxx:132
 TQCut.cxx:133
 TQCut.cxx:134
 TQCut.cxx:135
 TQCut.cxx:136
 TQCut.cxx:137
 TQCut.cxx:138
 TQCut.cxx:139
 TQCut.cxx:140
 TQCut.cxx:141
 TQCut.cxx:142
 TQCut.cxx:143
 TQCut.cxx:144
 TQCut.cxx:145
 TQCut.cxx:146
 TQCut.cxx:147
 TQCut.cxx:148
 TQCut.cxx:149
 TQCut.cxx:150
 TQCut.cxx:151
 TQCut.cxx:152
 TQCut.cxx:153
 TQCut.cxx:154
 TQCut.cxx:155
 TQCut.cxx:156
 TQCut.cxx:157
 TQCut.cxx:158
 TQCut.cxx:159
 TQCut.cxx:160
 TQCut.cxx:161
 TQCut.cxx:162
 TQCut.cxx:163
 TQCut.cxx:164
 TQCut.cxx:165
 TQCut.cxx:166
 TQCut.cxx:167
 TQCut.cxx:168
 TQCut.cxx:169
 TQCut.cxx:170
 TQCut.cxx:171
 TQCut.cxx:172
 TQCut.cxx:173
 TQCut.cxx:174
 TQCut.cxx:175
 TQCut.cxx:176
 TQCut.cxx:177
 TQCut.cxx:178
 TQCut.cxx:179
 TQCut.cxx:180
 TQCut.cxx:181
 TQCut.cxx:182
 TQCut.cxx:183
 TQCut.cxx:184
 TQCut.cxx:185
 TQCut.cxx:186
 TQCut.cxx:187
 TQCut.cxx:188
 TQCut.cxx:189
 TQCut.cxx:190
 TQCut.cxx:191
 TQCut.cxx:192
 TQCut.cxx:193
 TQCut.cxx:194
 TQCut.cxx:195
 TQCut.cxx:196
 TQCut.cxx:197
 TQCut.cxx:198
 TQCut.cxx:199
 TQCut.cxx:200
 TQCut.cxx:201
 TQCut.cxx:202
 TQCut.cxx:203
 TQCut.cxx:204
 TQCut.cxx:205
 TQCut.cxx:206
 TQCut.cxx:207
 TQCut.cxx:208
 TQCut.cxx:209
 TQCut.cxx:210
 TQCut.cxx:211
 TQCut.cxx:212
 TQCut.cxx:213
 TQCut.cxx:214
 TQCut.cxx:215
 TQCut.cxx:216
 TQCut.cxx:217
 TQCut.cxx:218
 TQCut.cxx:219
 TQCut.cxx:220
 TQCut.cxx:221
 TQCut.cxx:222
 TQCut.cxx:223
 TQCut.cxx:224
 TQCut.cxx:225
 TQCut.cxx:226
 TQCut.cxx:227
 TQCut.cxx:228
 TQCut.cxx:229
 TQCut.cxx:230
 TQCut.cxx:231
 TQCut.cxx:232
 TQCut.cxx:233
 TQCut.cxx:234
 TQCut.cxx:235
 TQCut.cxx:236
 TQCut.cxx:237
 TQCut.cxx:238
 TQCut.cxx:239
 TQCut.cxx:240
 TQCut.cxx:241
 TQCut.cxx:242
 TQCut.cxx:243
 TQCut.cxx:244
 TQCut.cxx:245
 TQCut.cxx:246
 TQCut.cxx:247
 TQCut.cxx:248
 TQCut.cxx:249
 TQCut.cxx:250
 TQCut.cxx:251
 TQCut.cxx:252
 TQCut.cxx:253
 TQCut.cxx:254
 TQCut.cxx:255
 TQCut.cxx:256
 TQCut.cxx:257
 TQCut.cxx:258
 TQCut.cxx:259
 TQCut.cxx:260
 TQCut.cxx:261
 TQCut.cxx:262
 TQCut.cxx:263
 TQCut.cxx:264
 TQCut.cxx:265
 TQCut.cxx:266
 TQCut.cxx:267
 TQCut.cxx:268
 TQCut.cxx:269
 TQCut.cxx:270
 TQCut.cxx:271
 TQCut.cxx:272
 TQCut.cxx:273
 TQCut.cxx:274
 TQCut.cxx:275
 TQCut.cxx:276
 TQCut.cxx:277
 TQCut.cxx:278
 TQCut.cxx:279
 TQCut.cxx:280
 TQCut.cxx:281
 TQCut.cxx:282
 TQCut.cxx:283
 TQCut.cxx:284
 TQCut.cxx:285
 TQCut.cxx:286
 TQCut.cxx:287
 TQCut.cxx:288
 TQCut.cxx:289
 TQCut.cxx:290
 TQCut.cxx:291
 TQCut.cxx:292
 TQCut.cxx:293
 TQCut.cxx:294
 TQCut.cxx:295
 TQCut.cxx:296
 TQCut.cxx:297
 TQCut.cxx:298
 TQCut.cxx:299
 TQCut.cxx:300
 TQCut.cxx:301
 TQCut.cxx:302
 TQCut.cxx:303
 TQCut.cxx:304
 TQCut.cxx:305
 TQCut.cxx:306
 TQCut.cxx:307
 TQCut.cxx:308
 TQCut.cxx:309
 TQCut.cxx:310
 TQCut.cxx:311
 TQCut.cxx:312
 TQCut.cxx:313
 TQCut.cxx:314
 TQCut.cxx:315
 TQCut.cxx:316
 TQCut.cxx:317
 TQCut.cxx:318
 TQCut.cxx:319
 TQCut.cxx:320
 TQCut.cxx:321
 TQCut.cxx:322
 TQCut.cxx:323
 TQCut.cxx:324
 TQCut.cxx:325
 TQCut.cxx:326
 TQCut.cxx:327
 TQCut.cxx:328
 TQCut.cxx:329
 TQCut.cxx:330
 TQCut.cxx:331
 TQCut.cxx:332
 TQCut.cxx:333
 TQCut.cxx:334
 TQCut.cxx:335
 TQCut.cxx:336
 TQCut.cxx:337
 TQCut.cxx:338
 TQCut.cxx:339
 TQCut.cxx:340
 TQCut.cxx:341
 TQCut.cxx:342
 TQCut.cxx:343
 TQCut.cxx:344
 TQCut.cxx:345
 TQCut.cxx:346
 TQCut.cxx:347
 TQCut.cxx:348
 TQCut.cxx:349
 TQCut.cxx:350
 TQCut.cxx:351
 TQCut.cxx:352
 TQCut.cxx:353
 TQCut.cxx:354
 TQCut.cxx:355
 TQCut.cxx:356
 TQCut.cxx:357
 TQCut.cxx:358
 TQCut.cxx:359
 TQCut.cxx:360
 TQCut.cxx:361
 TQCut.cxx:362
 TQCut.cxx:363
 TQCut.cxx:364
 TQCut.cxx:365
 TQCut.cxx:366
 TQCut.cxx:367
 TQCut.cxx:368
 TQCut.cxx:369
 TQCut.cxx:370
 TQCut.cxx:371
 TQCut.cxx:372
 TQCut.cxx:373
 TQCut.cxx:374
 TQCut.cxx:375
 TQCut.cxx:376
 TQCut.cxx:377
 TQCut.cxx:378
 TQCut.cxx:379
 TQCut.cxx:380
 TQCut.cxx:381
 TQCut.cxx:382
 TQCut.cxx:383
 TQCut.cxx:384
 TQCut.cxx:385
 TQCut.cxx:386
 TQCut.cxx:387
 TQCut.cxx:388
 TQCut.cxx:389
 TQCut.cxx:390
 TQCut.cxx:391
 TQCut.cxx:392
 TQCut.cxx:393
 TQCut.cxx:394
 TQCut.cxx:395
 TQCut.cxx:396
 TQCut.cxx:397
 TQCut.cxx:398
 TQCut.cxx:399
 TQCut.cxx:400
 TQCut.cxx:401
 TQCut.cxx:402
 TQCut.cxx:403
 TQCut.cxx:404
 TQCut.cxx:405
 TQCut.cxx:406
 TQCut.cxx:407
 TQCut.cxx:408
 TQCut.cxx:409
 TQCut.cxx:410
 TQCut.cxx:411
 TQCut.cxx:412
 TQCut.cxx:413
 TQCut.cxx:414
 TQCut.cxx:415
 TQCut.cxx:416
 TQCut.cxx:417
 TQCut.cxx:418
 TQCut.cxx:419
 TQCut.cxx:420
 TQCut.cxx:421
 TQCut.cxx:422
 TQCut.cxx:423
 TQCut.cxx:424
 TQCut.cxx:425
 TQCut.cxx:426
 TQCut.cxx:427
 TQCut.cxx:428
 TQCut.cxx:429
 TQCut.cxx:430
 TQCut.cxx:431
 TQCut.cxx:432
 TQCut.cxx:433
 TQCut.cxx:434
 TQCut.cxx:435
 TQCut.cxx:436
 TQCut.cxx:437
 TQCut.cxx:438
 TQCut.cxx:439
 TQCut.cxx:440
 TQCut.cxx:441
 TQCut.cxx:442
 TQCut.cxx:443
 TQCut.cxx:444
 TQCut.cxx:445
 TQCut.cxx:446
 TQCut.cxx:447
 TQCut.cxx:448
 TQCut.cxx:449
 TQCut.cxx:450
 TQCut.cxx:451
 TQCut.cxx:452
 TQCut.cxx:453
 TQCut.cxx:454
 TQCut.cxx:455
 TQCut.cxx:456
 TQCut.cxx:457
 TQCut.cxx:458
 TQCut.cxx:459
 TQCut.cxx:460
 TQCut.cxx:461
 TQCut.cxx:462
 TQCut.cxx:463
 TQCut.cxx:464
 TQCut.cxx:465
 TQCut.cxx:466
 TQCut.cxx:467
 TQCut.cxx:468
 TQCut.cxx:469
 TQCut.cxx:470
 TQCut.cxx:471
 TQCut.cxx:472
 TQCut.cxx:473
 TQCut.cxx:474
 TQCut.cxx:475
 TQCut.cxx:476
 TQCut.cxx:477
 TQCut.cxx:478
 TQCut.cxx:479
 TQCut.cxx:480
 TQCut.cxx:481
 TQCut.cxx:482
 TQCut.cxx:483
 TQCut.cxx:484
 TQCut.cxx:485
 TQCut.cxx:486
 TQCut.cxx:487
 TQCut.cxx:488
 TQCut.cxx:489
 TQCut.cxx:490
 TQCut.cxx:491
 TQCut.cxx:492
 TQCut.cxx:493
 TQCut.cxx:494
 TQCut.cxx:495
 TQCut.cxx:496
 TQCut.cxx:497
 TQCut.cxx:498
 TQCut.cxx:499
 TQCut.cxx:500
 TQCut.cxx:501
 TQCut.cxx:502
 TQCut.cxx:503
 TQCut.cxx:504
 TQCut.cxx:505
 TQCut.cxx:506
 TQCut.cxx:507
 TQCut.cxx:508
 TQCut.cxx:509
 TQCut.cxx:510
 TQCut.cxx:511
 TQCut.cxx:512
 TQCut.cxx:513
 TQCut.cxx:514
 TQCut.cxx:515
 TQCut.cxx:516
 TQCut.cxx:517
 TQCut.cxx:518
 TQCut.cxx:519
 TQCut.cxx:520
 TQCut.cxx:521
 TQCut.cxx:522
 TQCut.cxx:523
 TQCut.cxx:524
 TQCut.cxx:525
 TQCut.cxx:526
 TQCut.cxx:527
 TQCut.cxx:528
 TQCut.cxx:529
 TQCut.cxx:530
 TQCut.cxx:531
 TQCut.cxx:532
 TQCut.cxx:533
 TQCut.cxx:534
 TQCut.cxx:535
 TQCut.cxx:536
 TQCut.cxx:537
 TQCut.cxx:538
 TQCut.cxx:539
 TQCut.cxx:540
 TQCut.cxx:541
 TQCut.cxx:542
 TQCut.cxx:543
 TQCut.cxx:544
 TQCut.cxx:545
 TQCut.cxx:546
 TQCut.cxx:547
 TQCut.cxx:548
 TQCut.cxx:549
 TQCut.cxx:550
 TQCut.cxx:551
 TQCut.cxx:552
 TQCut.cxx:553
 TQCut.cxx:554
 TQCut.cxx:555
 TQCut.cxx:556
 TQCut.cxx:557
 TQCut.cxx:558
 TQCut.cxx:559
 TQCut.cxx:560
 TQCut.cxx:561
 TQCut.cxx:562
 TQCut.cxx:563
 TQCut.cxx:564
 TQCut.cxx:565
 TQCut.cxx:566
 TQCut.cxx:567
 TQCut.cxx:568
 TQCut.cxx:569
 TQCut.cxx:570
 TQCut.cxx:571
 TQCut.cxx:572
 TQCut.cxx:573
 TQCut.cxx:574
 TQCut.cxx:575
 TQCut.cxx:576
 TQCut.cxx:577
 TQCut.cxx:578
 TQCut.cxx:579
 TQCut.cxx:580
 TQCut.cxx:581
 TQCut.cxx:582
 TQCut.cxx:583
 TQCut.cxx:584
 TQCut.cxx:585
 TQCut.cxx:586
 TQCut.cxx:587
 TQCut.cxx:588
 TQCut.cxx:589
 TQCut.cxx:590
 TQCut.cxx:591
 TQCut.cxx:592
 TQCut.cxx:593
 TQCut.cxx:594
 TQCut.cxx:595
 TQCut.cxx:596
 TQCut.cxx:597
 TQCut.cxx:598
 TQCut.cxx:599
 TQCut.cxx:600
 TQCut.cxx:601
 TQCut.cxx:602
 TQCut.cxx:603
 TQCut.cxx:604
 TQCut.cxx:605
 TQCut.cxx:606
 TQCut.cxx:607
 TQCut.cxx:608
 TQCut.cxx:609
 TQCut.cxx:610
 TQCut.cxx:611
 TQCut.cxx:612
 TQCut.cxx:613
 TQCut.cxx:614
 TQCut.cxx:615
 TQCut.cxx:616
 TQCut.cxx:617
 TQCut.cxx:618
 TQCut.cxx:619
 TQCut.cxx:620
 TQCut.cxx:621
 TQCut.cxx:622
 TQCut.cxx:623
 TQCut.cxx:624
 TQCut.cxx:625
 TQCut.cxx:626
 TQCut.cxx:627
 TQCut.cxx:628
 TQCut.cxx:629
 TQCut.cxx:630
 TQCut.cxx:631
 TQCut.cxx:632
 TQCut.cxx:633
 TQCut.cxx:634
 TQCut.cxx:635
 TQCut.cxx:636
 TQCut.cxx:637
 TQCut.cxx:638
 TQCut.cxx:639
 TQCut.cxx:640
 TQCut.cxx:641
 TQCut.cxx:642
 TQCut.cxx:643
 TQCut.cxx:644
 TQCut.cxx:645
 TQCut.cxx:646
 TQCut.cxx:647
 TQCut.cxx:648
 TQCut.cxx:649
 TQCut.cxx:650
 TQCut.cxx:651
 TQCut.cxx:652
 TQCut.cxx:653
 TQCut.cxx:654
 TQCut.cxx:655
 TQCut.cxx:656
 TQCut.cxx:657
 TQCut.cxx:658
 TQCut.cxx:659
 TQCut.cxx:660
 TQCut.cxx:661
 TQCut.cxx:662
 TQCut.cxx:663
 TQCut.cxx:664
 TQCut.cxx:665
 TQCut.cxx:666
 TQCut.cxx:667
 TQCut.cxx:668
 TQCut.cxx:669
 TQCut.cxx:670
 TQCut.cxx:671
 TQCut.cxx:672
 TQCut.cxx:673
 TQCut.cxx:674
 TQCut.cxx:675
 TQCut.cxx:676
 TQCut.cxx:677
 TQCut.cxx:678
 TQCut.cxx:679
 TQCut.cxx:680
 TQCut.cxx:681
 TQCut.cxx:682
 TQCut.cxx:683
 TQCut.cxx:684
 TQCut.cxx:685
 TQCut.cxx:686
 TQCut.cxx:687
 TQCut.cxx:688
 TQCut.cxx:689
 TQCut.cxx:690
 TQCut.cxx:691
 TQCut.cxx:692
 TQCut.cxx:693
 TQCut.cxx:694
 TQCut.cxx:695
 TQCut.cxx:696
 TQCut.cxx:697
 TQCut.cxx:698
 TQCut.cxx:699
 TQCut.cxx:700
 TQCut.cxx:701
 TQCut.cxx:702
 TQCut.cxx:703
 TQCut.cxx:704
 TQCut.cxx:705
 TQCut.cxx:706
 TQCut.cxx:707
 TQCut.cxx:708
 TQCut.cxx:709
 TQCut.cxx:710
 TQCut.cxx:711
 TQCut.cxx:712
 TQCut.cxx:713
 TQCut.cxx:714
 TQCut.cxx:715
 TQCut.cxx:716
 TQCut.cxx:717
 TQCut.cxx:718
 TQCut.cxx:719
 TQCut.cxx:720
 TQCut.cxx:721
 TQCut.cxx:722
 TQCut.cxx:723
 TQCut.cxx:724
 TQCut.cxx:725
 TQCut.cxx:726
 TQCut.cxx:727
 TQCut.cxx:728
 TQCut.cxx:729
 TQCut.cxx:730
 TQCut.cxx:731
 TQCut.cxx:732
 TQCut.cxx:733
 TQCut.cxx:734
 TQCut.cxx:735
 TQCut.cxx:736
 TQCut.cxx:737
 TQCut.cxx:738
 TQCut.cxx:739
 TQCut.cxx:740
 TQCut.cxx:741
 TQCut.cxx:742
 TQCut.cxx:743
 TQCut.cxx:744
 TQCut.cxx:745
 TQCut.cxx:746
 TQCut.cxx:747
 TQCut.cxx:748
 TQCut.cxx:749
 TQCut.cxx:750
 TQCut.cxx:751
 TQCut.cxx:752
 TQCut.cxx:753
 TQCut.cxx:754
 TQCut.cxx:755
 TQCut.cxx:756
 TQCut.cxx:757
 TQCut.cxx:758
 TQCut.cxx:759
 TQCut.cxx:760
 TQCut.cxx:761
 TQCut.cxx:762
 TQCut.cxx:763
 TQCut.cxx:764
 TQCut.cxx:765
 TQCut.cxx:766
 TQCut.cxx:767
 TQCut.cxx:768
 TQCut.cxx:769
 TQCut.cxx:770
 TQCut.cxx:771
 TQCut.cxx:772
 TQCut.cxx:773
 TQCut.cxx:774
 TQCut.cxx:775
 TQCut.cxx:776
 TQCut.cxx:777
 TQCut.cxx:778
 TQCut.cxx:779
 TQCut.cxx:780
 TQCut.cxx:781
 TQCut.cxx:782
 TQCut.cxx:783
 TQCut.cxx:784
 TQCut.cxx:785
 TQCut.cxx:786
 TQCut.cxx:787
 TQCut.cxx:788
 TQCut.cxx:789
 TQCut.cxx:790
 TQCut.cxx:791
 TQCut.cxx:792
 TQCut.cxx:793
 TQCut.cxx:794
 TQCut.cxx:795
 TQCut.cxx:796
 TQCut.cxx:797
 TQCut.cxx:798
 TQCut.cxx:799
 TQCut.cxx:800
 TQCut.cxx:801
 TQCut.cxx:802
 TQCut.cxx:803
 TQCut.cxx:804
 TQCut.cxx:805
 TQCut.cxx:806
 TQCut.cxx:807
 TQCut.cxx:808
 TQCut.cxx:809
 TQCut.cxx:810
 TQCut.cxx:811
 TQCut.cxx:812
 TQCut.cxx:813
 TQCut.cxx:814
 TQCut.cxx:815
 TQCut.cxx:816
 TQCut.cxx:817
 TQCut.cxx:818
 TQCut.cxx:819
 TQCut.cxx:820
 TQCut.cxx:821
 TQCut.cxx:822
 TQCut.cxx:823
 TQCut.cxx:824
 TQCut.cxx:825
 TQCut.cxx:826
 TQCut.cxx:827
 TQCut.cxx:828
 TQCut.cxx:829
 TQCut.cxx:830
 TQCut.cxx:831
 TQCut.cxx:832
 TQCut.cxx:833
 TQCut.cxx:834
 TQCut.cxx:835
 TQCut.cxx:836
 TQCut.cxx:837
 TQCut.cxx:838
 TQCut.cxx:839
 TQCut.cxx:840
 TQCut.cxx:841
 TQCut.cxx:842
 TQCut.cxx:843
 TQCut.cxx:844
 TQCut.cxx:845
 TQCut.cxx:846
 TQCut.cxx:847
 TQCut.cxx:848
 TQCut.cxx:849
 TQCut.cxx:850
 TQCut.cxx:851
 TQCut.cxx:852
 TQCut.cxx:853
 TQCut.cxx:854
 TQCut.cxx:855
 TQCut.cxx:856
 TQCut.cxx:857
 TQCut.cxx:858
 TQCut.cxx:859
 TQCut.cxx:860
 TQCut.cxx:861
 TQCut.cxx:862
 TQCut.cxx:863
 TQCut.cxx:864
 TQCut.cxx:865
 TQCut.cxx:866
 TQCut.cxx:867
 TQCut.cxx:868
 TQCut.cxx:869
 TQCut.cxx:870
 TQCut.cxx:871
 TQCut.cxx:872
 TQCut.cxx:873
 TQCut.cxx:874
 TQCut.cxx:875
 TQCut.cxx:876
 TQCut.cxx:877
 TQCut.cxx:878
 TQCut.cxx:879
 TQCut.cxx:880
 TQCut.cxx:881
 TQCut.cxx:882
 TQCut.cxx:883
 TQCut.cxx:884
 TQCut.cxx:885
 TQCut.cxx:886
 TQCut.cxx:887
 TQCut.cxx:888
 TQCut.cxx:889
 TQCut.cxx:890
 TQCut.cxx:891
 TQCut.cxx:892
 TQCut.cxx:893
 TQCut.cxx:894
 TQCut.cxx:895
 TQCut.cxx:896
 TQCut.cxx:897
 TQCut.cxx:898
 TQCut.cxx:899
 TQCut.cxx:900
 TQCut.cxx:901
 TQCut.cxx:902
 TQCut.cxx:903
 TQCut.cxx:904
 TQCut.cxx:905
 TQCut.cxx:906
 TQCut.cxx:907
 TQCut.cxx:908
 TQCut.cxx:909
 TQCut.cxx:910
 TQCut.cxx:911
 TQCut.cxx:912
 TQCut.cxx:913
 TQCut.cxx:914
 TQCut.cxx:915
 TQCut.cxx:916
 TQCut.cxx:917
 TQCut.cxx:918
 TQCut.cxx:919
 TQCut.cxx:920
 TQCut.cxx:921
 TQCut.cxx:922
 TQCut.cxx:923
 TQCut.cxx:924
 TQCut.cxx:925
 TQCut.cxx:926
 TQCut.cxx:927
 TQCut.cxx:928
 TQCut.cxx:929
 TQCut.cxx:930
 TQCut.cxx:931
 TQCut.cxx:932
 TQCut.cxx:933
 TQCut.cxx:934
 TQCut.cxx:935
 TQCut.cxx:936
 TQCut.cxx:937
 TQCut.cxx:938
 TQCut.cxx:939
 TQCut.cxx:940
 TQCut.cxx:941
 TQCut.cxx:942
 TQCut.cxx:943
 TQCut.cxx:944
 TQCut.cxx:945
 TQCut.cxx:946
 TQCut.cxx:947
 TQCut.cxx:948
 TQCut.cxx:949
 TQCut.cxx:950
 TQCut.cxx:951
 TQCut.cxx:952
 TQCut.cxx:953
 TQCut.cxx:954
 TQCut.cxx:955
 TQCut.cxx:956
 TQCut.cxx:957
 TQCut.cxx:958
 TQCut.cxx:959
 TQCut.cxx:960
 TQCut.cxx:961
 TQCut.cxx:962
 TQCut.cxx:963
 TQCut.cxx:964
 TQCut.cxx:965
 TQCut.cxx:966
 TQCut.cxx:967
 TQCut.cxx:968
 TQCut.cxx:969
 TQCut.cxx:970
 TQCut.cxx:971
 TQCut.cxx:972
 TQCut.cxx:973
 TQCut.cxx:974
 TQCut.cxx:975
 TQCut.cxx:976
 TQCut.cxx:977
 TQCut.cxx:978
 TQCut.cxx:979
 TQCut.cxx:980
 TQCut.cxx:981
 TQCut.cxx:982
 TQCut.cxx:983
 TQCut.cxx:984
 TQCut.cxx:985
 TQCut.cxx:986
 TQCut.cxx:987
 TQCut.cxx:988
 TQCut.cxx:989
 TQCut.cxx:990
 TQCut.cxx:991
 TQCut.cxx:992
 TQCut.cxx:993
 TQCut.cxx:994
 TQCut.cxx:995
 TQCut.cxx:996
 TQCut.cxx:997
 TQCut.cxx:998
 TQCut.cxx:999
 TQCut.cxx:1000
 TQCut.cxx:1001
 TQCut.cxx:1002
 TQCut.cxx:1003
 TQCut.cxx:1004
 TQCut.cxx:1005
 TQCut.cxx:1006
 TQCut.cxx:1007
 TQCut.cxx:1008
 TQCut.cxx:1009
 TQCut.cxx:1010
 TQCut.cxx:1011
 TQCut.cxx:1012
 TQCut.cxx:1013
 TQCut.cxx:1014
 TQCut.cxx:1015
 TQCut.cxx:1016
 TQCut.cxx:1017
 TQCut.cxx:1018
 TQCut.cxx:1019
 TQCut.cxx:1020
 TQCut.cxx:1021
 TQCut.cxx:1022
 TQCut.cxx:1023
 TQCut.cxx:1024
 TQCut.cxx:1025
 TQCut.cxx:1026
 TQCut.cxx:1027
 TQCut.cxx:1028
 TQCut.cxx:1029
 TQCut.cxx:1030
 TQCut.cxx:1031
 TQCut.cxx:1032
 TQCut.cxx:1033
 TQCut.cxx:1034
 TQCut.cxx:1035
 TQCut.cxx:1036
 TQCut.cxx:1037
 TQCut.cxx:1038
 TQCut.cxx:1039
 TQCut.cxx:1040
 TQCut.cxx:1041
 TQCut.cxx:1042
 TQCut.cxx:1043
 TQCut.cxx:1044
 TQCut.cxx:1045
 TQCut.cxx:1046
 TQCut.cxx:1047
 TQCut.cxx:1048
 TQCut.cxx:1049
 TQCut.cxx:1050
 TQCut.cxx:1051
 TQCut.cxx:1052
 TQCut.cxx:1053
 TQCut.cxx:1054
 TQCut.cxx:1055
 TQCut.cxx:1056
 TQCut.cxx:1057
 TQCut.cxx:1058
 TQCut.cxx:1059
 TQCut.cxx:1060
 TQCut.cxx:1061
 TQCut.cxx:1062
 TQCut.cxx:1063
 TQCut.cxx:1064
 TQCut.cxx:1065
 TQCut.cxx:1066
 TQCut.cxx:1067
 TQCut.cxx:1068
 TQCut.cxx:1069
 TQCut.cxx:1070
 TQCut.cxx:1071
 TQCut.cxx:1072
 TQCut.cxx:1073
 TQCut.cxx:1074
 TQCut.cxx:1075
 TQCut.cxx:1076
 TQCut.cxx:1077
 TQCut.cxx:1078
 TQCut.cxx:1079
 TQCut.cxx:1080
 TQCut.cxx:1081
 TQCut.cxx:1082
 TQCut.cxx:1083
 TQCut.cxx:1084
 TQCut.cxx:1085
 TQCut.cxx:1086
 TQCut.cxx:1087
 TQCut.cxx:1088
 TQCut.cxx:1089
 TQCut.cxx:1090
 TQCut.cxx:1091
 TQCut.cxx:1092
 TQCut.cxx:1093
 TQCut.cxx:1094
 TQCut.cxx:1095
 TQCut.cxx:1096
 TQCut.cxx:1097
 TQCut.cxx:1098
 TQCut.cxx:1099
 TQCut.cxx:1100
 TQCut.cxx:1101
 TQCut.cxx:1102
 TQCut.cxx:1103
 TQCut.cxx:1104
 TQCut.cxx:1105
 TQCut.cxx:1106
 TQCut.cxx:1107
 TQCut.cxx:1108
 TQCut.cxx:1109
 TQCut.cxx:1110
 TQCut.cxx:1111
 TQCut.cxx:1112
 TQCut.cxx:1113
 TQCut.cxx:1114
 TQCut.cxx:1115
 TQCut.cxx:1116
 TQCut.cxx:1117
 TQCut.cxx:1118
 TQCut.cxx:1119
 TQCut.cxx:1120
 TQCut.cxx:1121
 TQCut.cxx:1122
 TQCut.cxx:1123
 TQCut.cxx:1124
 TQCut.cxx:1125
 TQCut.cxx:1126
 TQCut.cxx:1127
 TQCut.cxx:1128
 TQCut.cxx:1129
 TQCut.cxx:1130
 TQCut.cxx:1131
 TQCut.cxx:1132
 TQCut.cxx:1133
 TQCut.cxx:1134
 TQCut.cxx:1135
 TQCut.cxx:1136
 TQCut.cxx:1137
 TQCut.cxx:1138
 TQCut.cxx:1139
 TQCut.cxx:1140
 TQCut.cxx:1141
 TQCut.cxx:1142
 TQCut.cxx:1143
 TQCut.cxx:1144
 TQCut.cxx:1145
 TQCut.cxx:1146
 TQCut.cxx:1147
 TQCut.cxx:1148
 TQCut.cxx:1149
 TQCut.cxx:1150
 TQCut.cxx:1151
 TQCut.cxx:1152
 TQCut.cxx:1153
 TQCut.cxx:1154
 TQCut.cxx:1155
 TQCut.cxx:1156
 TQCut.cxx:1157
 TQCut.cxx:1158
 TQCut.cxx:1159
 TQCut.cxx:1160
 TQCut.cxx:1161
 TQCut.cxx:1162
 TQCut.cxx:1163
 TQCut.cxx:1164
 TQCut.cxx:1165
 TQCut.cxx:1166
 TQCut.cxx:1167
 TQCut.cxx:1168
 TQCut.cxx:1169
 TQCut.cxx:1170
 TQCut.cxx:1171
 TQCut.cxx:1172
 TQCut.cxx:1173
 TQCut.cxx:1174
 TQCut.cxx:1175
 TQCut.cxx:1176
 TQCut.cxx:1177
 TQCut.cxx:1178
 TQCut.cxx:1179
 TQCut.cxx:1180
 TQCut.cxx:1181
 TQCut.cxx:1182
 TQCut.cxx:1183
 TQCut.cxx:1184
 TQCut.cxx:1185
 TQCut.cxx:1186
 TQCut.cxx:1187
 TQCut.cxx:1188
 TQCut.cxx:1189
 TQCut.cxx:1190
 TQCut.cxx:1191
 TQCut.cxx:1192
 TQCut.cxx:1193
 TQCut.cxx:1194
 TQCut.cxx:1195
 TQCut.cxx:1196
 TQCut.cxx:1197
 TQCut.cxx:1198
 TQCut.cxx:1199
 TQCut.cxx:1200
 TQCut.cxx:1201
 TQCut.cxx:1202
 TQCut.cxx:1203
 TQCut.cxx:1204
 TQCut.cxx:1205
 TQCut.cxx:1206
 TQCut.cxx:1207
 TQCut.cxx:1208
 TQCut.cxx:1209
 TQCut.cxx:1210
 TQCut.cxx:1211
 TQCut.cxx:1212
 TQCut.cxx:1213
 TQCut.cxx:1214
 TQCut.cxx:1215
 TQCut.cxx:1216
 TQCut.cxx:1217
 TQCut.cxx:1218
 TQCut.cxx:1219
 TQCut.cxx:1220
 TQCut.cxx:1221
 TQCut.cxx:1222
 TQCut.cxx:1223
 TQCut.cxx:1224
 TQCut.cxx:1225
 TQCut.cxx:1226
 TQCut.cxx:1227
 TQCut.cxx:1228
 TQCut.cxx:1229
 TQCut.cxx:1230
 TQCut.cxx:1231
 TQCut.cxx:1232
 TQCut.cxx:1233
 TQCut.cxx:1234
 TQCut.cxx:1235
 TQCut.cxx:1236
 TQCut.cxx:1237
 TQCut.cxx:1238
 TQCut.cxx:1239
 TQCut.cxx:1240
 TQCut.cxx:1241
 TQCut.cxx:1242
 TQCut.cxx:1243
 TQCut.cxx:1244
 TQCut.cxx:1245
 TQCut.cxx:1246
 TQCut.cxx:1247
 TQCut.cxx:1248
 TQCut.cxx:1249
 TQCut.cxx:1250
 TQCut.cxx:1251
 TQCut.cxx:1252
 TQCut.cxx:1253
 TQCut.cxx:1254
 TQCut.cxx:1255
 TQCut.cxx:1256
 TQCut.cxx:1257
 TQCut.cxx:1258
 TQCut.cxx:1259
 TQCut.cxx:1260
 TQCut.cxx:1261
 TQCut.cxx:1262
 TQCut.cxx:1263
 TQCut.cxx:1264
 TQCut.cxx:1265
 TQCut.cxx:1266
 TQCut.cxx:1267
 TQCut.cxx:1268
 TQCut.cxx:1269
 TQCut.cxx:1270
 TQCut.cxx:1271
 TQCut.cxx:1272
 TQCut.cxx:1273
 TQCut.cxx:1274
 TQCut.cxx:1275
 TQCut.cxx:1276
 TQCut.cxx:1277
 TQCut.cxx:1278
 TQCut.cxx:1279
 TQCut.cxx:1280
 TQCut.cxx:1281
 TQCut.cxx:1282
 TQCut.cxx:1283
 TQCut.cxx:1284
 TQCut.cxx:1285
 TQCut.cxx:1286
 TQCut.cxx:1287
 TQCut.cxx:1288
 TQCut.cxx:1289
 TQCut.cxx:1290
 TQCut.cxx:1291
 TQCut.cxx:1292
 TQCut.cxx:1293
 TQCut.cxx:1294
 TQCut.cxx:1295
 TQCut.cxx:1296
 TQCut.cxx:1297
 TQCut.cxx:1298
 TQCut.cxx:1299
 TQCut.cxx:1300
 TQCut.cxx:1301
 TQCut.cxx:1302
 TQCut.cxx:1303
 TQCut.cxx:1304
 TQCut.cxx:1305
 TQCut.cxx:1306
 TQCut.cxx:1307
 TQCut.cxx:1308
 TQCut.cxx:1309
 TQCut.cxx:1310
 TQCut.cxx:1311
 TQCut.cxx:1312
 TQCut.cxx:1313
 TQCut.cxx:1314
 TQCut.cxx:1315
 TQCut.cxx:1316
 TQCut.cxx:1317
 TQCut.cxx:1318
 TQCut.cxx:1319
 TQCut.cxx:1320
 TQCut.cxx:1321
 TQCut.cxx:1322
 TQCut.cxx:1323
 TQCut.cxx:1324
 TQCut.cxx:1325
 TQCut.cxx:1326
 TQCut.cxx:1327
 TQCut.cxx:1328
 TQCut.cxx:1329
 TQCut.cxx:1330
 TQCut.cxx:1331
 TQCut.cxx:1332
 TQCut.cxx:1333
 TQCut.cxx:1334
 TQCut.cxx:1335
 TQCut.cxx:1336
 TQCut.cxx:1337
 TQCut.cxx:1338
 TQCut.cxx:1339
 TQCut.cxx:1340
 TQCut.cxx:1341
 TQCut.cxx:1342
 TQCut.cxx:1343
 TQCut.cxx:1344
 TQCut.cxx:1345
 TQCut.cxx:1346
 TQCut.cxx:1347
 TQCut.cxx:1348
 TQCut.cxx:1349
 TQCut.cxx:1350
 TQCut.cxx:1351
 TQCut.cxx:1352
 TQCut.cxx:1353
 TQCut.cxx:1354
 TQCut.cxx:1355
 TQCut.cxx:1356
 TQCut.cxx:1357
 TQCut.cxx:1358
 TQCut.cxx:1359
 TQCut.cxx:1360
 TQCut.cxx:1361
 TQCut.cxx:1362
 TQCut.cxx:1363
 TQCut.cxx:1364
 TQCut.cxx:1365
 TQCut.cxx:1366
 TQCut.cxx:1367
 TQCut.cxx:1368
 TQCut.cxx:1369
 TQCut.cxx:1370
 TQCut.cxx:1371
 TQCut.cxx:1372
 TQCut.cxx:1373
 TQCut.cxx:1374
 TQCut.cxx:1375
 TQCut.cxx:1376
 TQCut.cxx:1377
 TQCut.cxx:1378
 TQCut.cxx:1379
 TQCut.cxx:1380
 TQCut.cxx:1381
 TQCut.cxx:1382
 TQCut.cxx:1383
 TQCut.cxx:1384
 TQCut.cxx:1385
 TQCut.cxx:1386
 TQCut.cxx:1387
 TQCut.cxx:1388
 TQCut.cxx:1389
 TQCut.cxx:1390
 TQCut.cxx:1391
 TQCut.cxx:1392
 TQCut.cxx:1393
 TQCut.cxx:1394
 TQCut.cxx:1395
 TQCut.cxx:1396
 TQCut.cxx:1397
 TQCut.cxx:1398
 TQCut.cxx:1399
 TQCut.cxx:1400
 TQCut.cxx:1401
 TQCut.cxx:1402
 TQCut.cxx:1403
 TQCut.cxx:1404
 TQCut.cxx:1405
 TQCut.cxx:1406
 TQCut.cxx:1407
 TQCut.cxx:1408
 TQCut.cxx:1409
 TQCut.cxx:1410
 TQCut.cxx:1411
 TQCut.cxx:1412
 TQCut.cxx:1413
 TQCut.cxx:1414
 TQCut.cxx:1415
 TQCut.cxx:1416
 TQCut.cxx:1417
 TQCut.cxx:1418
 TQCut.cxx:1419
 TQCut.cxx:1420
 TQCut.cxx:1421
 TQCut.cxx:1422
 TQCut.cxx:1423
 TQCut.cxx:1424
 TQCut.cxx:1425
 TQCut.cxx:1426
 TQCut.cxx:1427
 TQCut.cxx:1428
 TQCut.cxx:1429
 TQCut.cxx:1430
 TQCut.cxx:1431
 TQCut.cxx:1432
 TQCut.cxx:1433
 TQCut.cxx:1434
 TQCut.cxx:1435
 TQCut.cxx:1436
 TQCut.cxx:1437
 TQCut.cxx:1438
 TQCut.cxx:1439
 TQCut.cxx:1440
 TQCut.cxx:1441
 TQCut.cxx:1442
 TQCut.cxx:1443
 TQCut.cxx:1444
 TQCut.cxx:1445
 TQCut.cxx:1446
 TQCut.cxx:1447
 TQCut.cxx:1448
 TQCut.cxx:1449
 TQCut.cxx:1450
 TQCut.cxx:1451
 TQCut.cxx:1452
 TQCut.cxx:1453
 TQCut.cxx:1454
 TQCut.cxx:1455
 TQCut.cxx:1456
 TQCut.cxx:1457
 TQCut.cxx:1458
 TQCut.cxx:1459
 TQCut.cxx:1460
 TQCut.cxx:1461
 TQCut.cxx:1462
 TQCut.cxx:1463
 TQCut.cxx:1464
 TQCut.cxx:1465
 TQCut.cxx:1466
 TQCut.cxx:1467
 TQCut.cxx:1468
 TQCut.cxx:1469
 TQCut.cxx:1470
 TQCut.cxx:1471
 TQCut.cxx:1472
 TQCut.cxx:1473
 TQCut.cxx:1474
 TQCut.cxx:1475
 TQCut.cxx:1476
 TQCut.cxx:1477
 TQCut.cxx:1478
 TQCut.cxx:1479
 TQCut.cxx:1480
 TQCut.cxx:1481
 TQCut.cxx:1482
 TQCut.cxx:1483
 TQCut.cxx:1484
 TQCut.cxx:1485
 TQCut.cxx:1486
 TQCut.cxx:1487
 TQCut.cxx:1488
 TQCut.cxx:1489
 TQCut.cxx:1490
 TQCut.cxx:1491
 TQCut.cxx:1492
 TQCut.cxx:1493
 TQCut.cxx:1494
 TQCut.cxx:1495
 TQCut.cxx:1496
 TQCut.cxx:1497
 TQCut.cxx:1498
 TQCut.cxx:1499
 TQCut.cxx:1500
 TQCut.cxx:1501
 TQCut.cxx:1502
 TQCut.cxx:1503
 TQCut.cxx:1504
 TQCut.cxx:1505
 TQCut.cxx:1506
 TQCut.cxx:1507
 TQCut.cxx:1508
 TQCut.cxx:1509
 TQCut.cxx:1510
 TQCut.cxx:1511
 TQCut.cxx:1512
 TQCut.cxx:1513
 TQCut.cxx:1514
 TQCut.cxx:1515
 TQCut.cxx:1516
 TQCut.cxx:1517
 TQCut.cxx:1518
 TQCut.cxx:1519
 TQCut.cxx:1520
 TQCut.cxx:1521
 TQCut.cxx:1522
 TQCut.cxx:1523
 TQCut.cxx:1524
 TQCut.cxx:1525
 TQCut.cxx:1526
 TQCut.cxx:1527
 TQCut.cxx:1528
 TQCut.cxx:1529
 TQCut.cxx:1530
 TQCut.cxx:1531
 TQCut.cxx:1532
 TQCut.cxx:1533
 TQCut.cxx:1534
 TQCut.cxx:1535
 TQCut.cxx:1536
 TQCut.cxx:1537
 TQCut.cxx:1538
 TQCut.cxx:1539
 TQCut.cxx:1540
 TQCut.cxx:1541
 TQCut.cxx:1542
 TQCut.cxx:1543
 TQCut.cxx:1544
 TQCut.cxx:1545
 TQCut.cxx:1546
 TQCut.cxx:1547
 TQCut.cxx:1548
 TQCut.cxx:1549
 TQCut.cxx:1550
 TQCut.cxx:1551
 TQCut.cxx:1552
 TQCut.cxx:1553
 TQCut.cxx:1554
 TQCut.cxx:1555
 TQCut.cxx:1556
 TQCut.cxx:1557
 TQCut.cxx:1558
 TQCut.cxx:1559
 TQCut.cxx:1560
 TQCut.cxx:1561
 TQCut.cxx:1562
 TQCut.cxx:1563
 TQCut.cxx:1564
 TQCut.cxx:1565
 TQCut.cxx:1566
 TQCut.cxx:1567
 TQCut.cxx:1568
 TQCut.cxx:1569
 TQCut.cxx:1570
 TQCut.cxx:1571
 TQCut.cxx:1572
 TQCut.cxx:1573
 TQCut.cxx:1574
 TQCut.cxx:1575
 TQCut.cxx:1576
 TQCut.cxx:1577
 TQCut.cxx:1578
 TQCut.cxx:1579
 TQCut.cxx:1580
 TQCut.cxx:1581
 TQCut.cxx:1582
 TQCut.cxx:1583
 TQCut.cxx:1584
 TQCut.cxx:1585
 TQCut.cxx:1586
 TQCut.cxx:1587
 TQCut.cxx:1588
 TQCut.cxx:1589
 TQCut.cxx:1590
 TQCut.cxx:1591
 TQCut.cxx:1592
 TQCut.cxx:1593
 TQCut.cxx:1594
 TQCut.cxx:1595
 TQCut.cxx:1596
 TQCut.cxx:1597
 TQCut.cxx:1598
 TQCut.cxx:1599
 TQCut.cxx:1600
 TQCut.cxx:1601
 TQCut.cxx:1602
 TQCut.cxx:1603
 TQCut.cxx:1604
 TQCut.cxx:1605
 TQCut.cxx:1606
 TQCut.cxx:1607
 TQCut.cxx:1608
 TQCut.cxx:1609
 TQCut.cxx:1610
 TQCut.cxx:1611
 TQCut.cxx:1612
 TQCut.cxx:1613
 TQCut.cxx:1614
 TQCut.cxx:1615
 TQCut.cxx:1616
 TQCut.cxx:1617
 TQCut.cxx:1618
 TQCut.cxx:1619
 TQCut.cxx:1620
 TQCut.cxx:1621
 TQCut.cxx:1622
 TQCut.cxx:1623
 TQCut.cxx:1624
 TQCut.cxx:1625
 TQCut.cxx:1626
 TQCut.cxx:1627
 TQCut.cxx:1628
 TQCut.cxx:1629
 TQCut.cxx:1630
 TQCut.cxx:1631
 TQCut.cxx:1632
 TQCut.cxx:1633
 TQCut.cxx:1634
 TQCut.cxx:1635
 TQCut.cxx:1636
 TQCut.cxx:1637
 TQCut.cxx:1638
 TQCut.cxx:1639
 TQCut.cxx:1640
 TQCut.cxx:1641
 TQCut.cxx:1642
 TQCut.cxx:1643
 TQCut.cxx:1644
 TQCut.cxx:1645
 TQCut.cxx:1646
 TQCut.cxx:1647
 TQCut.cxx:1648
 TQCut.cxx:1649
 TQCut.cxx:1650
 TQCut.cxx:1651
 TQCut.cxx:1652
 TQCut.cxx:1653
 TQCut.cxx:1654
 TQCut.cxx:1655
 TQCut.cxx:1656
 TQCut.cxx:1657
 TQCut.cxx:1658
 TQCut.cxx:1659
 TQCut.cxx:1660
 TQCut.cxx:1661
 TQCut.cxx:1662
 TQCut.cxx:1663
 TQCut.cxx:1664
 TQCut.cxx:1665
 TQCut.cxx:1666
 TQCut.cxx:1667
 TQCut.cxx:1668
 TQCut.cxx:1669
 TQCut.cxx:1670
 TQCut.cxx:1671
 TQCut.cxx:1672
 TQCut.cxx:1673
 TQCut.cxx:1674
 TQCut.cxx:1675
 TQCut.cxx:1676
 TQCut.cxx:1677
 TQCut.cxx:1678
 TQCut.cxx:1679
 TQCut.cxx:1680
 TQCut.cxx:1681
 TQCut.cxx:1682
 TQCut.cxx:1683
 TQCut.cxx:1684
 TQCut.cxx:1685
 TQCut.cxx:1686
 TQCut.cxx:1687
 TQCut.cxx:1688
 TQCut.cxx:1689
 TQCut.cxx:1690
 TQCut.cxx:1691
 TQCut.cxx:1692
 TQCut.cxx:1693
 TQCut.cxx:1694
 TQCut.cxx:1695
 TQCut.cxx:1696
 TQCut.cxx:1697
 TQCut.cxx:1698
 TQCut.cxx:1699
 TQCut.cxx:1700
 TQCut.cxx:1701
 TQCut.cxx:1702
 TQCut.cxx:1703
 TQCut.cxx:1704
 TQCut.cxx:1705
 TQCut.cxx:1706
 TQCut.cxx:1707
 TQCut.cxx:1708
 TQCut.cxx:1709
 TQCut.cxx:1710
 TQCut.cxx:1711
 TQCut.cxx:1712
 TQCut.cxx:1713
 TQCut.cxx:1714
 TQCut.cxx:1715
 TQCut.cxx:1716
 TQCut.cxx:1717
 TQCut.cxx:1718
 TQCut.cxx:1719
 TQCut.cxx:1720
 TQCut.cxx:1721
 TQCut.cxx:1722
 TQCut.cxx:1723
 TQCut.cxx:1724
 TQCut.cxx:1725
 TQCut.cxx:1726
 TQCut.cxx:1727
 TQCut.cxx:1728
 TQCut.cxx:1729
 TQCut.cxx:1730
 TQCut.cxx:1731
 TQCut.cxx:1732
 TQCut.cxx:1733
 TQCut.cxx:1734
 TQCut.cxx:1735
 TQCut.cxx:1736
 TQCut.cxx:1737
 TQCut.cxx:1738
 TQCut.cxx:1739
 TQCut.cxx:1740
 TQCut.cxx:1741
 TQCut.cxx:1742
 TQCut.cxx:1743
 TQCut.cxx:1744
 TQCut.cxx:1745
 TQCut.cxx:1746
 TQCut.cxx:1747
 TQCut.cxx:1748
 TQCut.cxx:1749
 TQCut.cxx:1750
 TQCut.cxx:1751
 TQCut.cxx:1752
 TQCut.cxx:1753
 TQCut.cxx:1754
 TQCut.cxx:1755
 TQCut.cxx:1756
 TQCut.cxx:1757
 TQCut.cxx:1758
 TQCut.cxx:1759
 TQCut.cxx:1760
 TQCut.cxx:1761
 TQCut.cxx:1762
 TQCut.cxx:1763
 TQCut.cxx:1764
 TQCut.cxx:1765
 TQCut.cxx:1766
 TQCut.cxx:1767
 TQCut.cxx:1768
 TQCut.cxx:1769
 TQCut.cxx:1770
 TQCut.cxx:1771
 TQCut.cxx:1772
 TQCut.cxx:1773
 TQCut.cxx:1774
 TQCut.cxx:1775
 TQCut.cxx:1776
 TQCut.cxx:1777
 TQCut.cxx:1778
 TQCut.cxx:1779
 TQCut.cxx:1780
 TQCut.cxx:1781
 TQCut.cxx:1782
 TQCut.cxx:1783
 TQCut.cxx:1784
 TQCut.cxx:1785
 TQCut.cxx:1786
 TQCut.cxx:1787
 TQCut.cxx:1788
 TQCut.cxx:1789
 TQCut.cxx:1790
 TQCut.cxx:1791
 TQCut.cxx:1792
 TQCut.cxx:1793
 TQCut.cxx:1794
 TQCut.cxx:1795
 TQCut.cxx:1796
 TQCut.cxx:1797
 TQCut.cxx:1798
 TQCut.cxx:1799
 TQCut.cxx:1800
 TQCut.cxx:1801
 TQCut.cxx:1802
 TQCut.cxx:1803
 TQCut.cxx:1804
 TQCut.cxx:1805
 TQCut.cxx:1806
 TQCut.cxx:1807
 TQCut.cxx:1808
 TQCut.cxx:1809
 TQCut.cxx:1810
 TQCut.cxx:1811
 TQCut.cxx:1812
 TQCut.cxx:1813
 TQCut.cxx:1814
 TQCut.cxx:1815
 TQCut.cxx:1816
 TQCut.cxx:1817
 TQCut.cxx:1818
 TQCut.cxx:1819
 TQCut.cxx:1820
 TQCut.cxx:1821
 TQCut.cxx:1822
 TQCut.cxx:1823
 TQCut.cxx:1824
 TQCut.cxx:1825
 TQCut.cxx:1826
 TQCut.cxx:1827
 TQCut.cxx:1828
 TQCut.cxx:1829
 TQCut.cxx:1830
 TQCut.cxx:1831
 TQCut.cxx:1832
 TQCut.cxx:1833
 TQCut.cxx:1834
 TQCut.cxx:1835
 TQCut.cxx:1836
 TQCut.cxx:1837
 TQCut.cxx:1838
 TQCut.cxx:1839
 TQCut.cxx:1840
 TQCut.cxx:1841
 TQCut.cxx:1842
 TQCut.cxx:1843
 TQCut.cxx:1844
 TQCut.cxx:1845
 TQCut.cxx:1846
 TQCut.cxx:1847
 TQCut.cxx:1848
 TQCut.cxx:1849
 TQCut.cxx:1850
 TQCut.cxx:1851
 TQCut.cxx:1852
 TQCut.cxx:1853
 TQCut.cxx:1854
 TQCut.cxx:1855
 TQCut.cxx:1856
 TQCut.cxx:1857
 TQCut.cxx:1858
 TQCut.cxx:1859
 TQCut.cxx:1860
 TQCut.cxx:1861
 TQCut.cxx:1862
 TQCut.cxx:1863
 TQCut.cxx:1864
 TQCut.cxx:1865
 TQCut.cxx:1866
 TQCut.cxx:1867
 TQCut.cxx:1868
 TQCut.cxx:1869
 TQCut.cxx:1870
 TQCut.cxx:1871
 TQCut.cxx:1872
 TQCut.cxx:1873
 TQCut.cxx:1874
 TQCut.cxx:1875
 TQCut.cxx:1876
 TQCut.cxx:1877
 TQCut.cxx:1878
 TQCut.cxx:1879
 TQCut.cxx:1880
 TQCut.cxx:1881
 TQCut.cxx:1882
 TQCut.cxx:1883
 TQCut.cxx:1884
 TQCut.cxx:1885
 TQCut.cxx:1886
 TQCut.cxx:1887
 TQCut.cxx:1888
 TQCut.cxx:1889
 TQCut.cxx:1890
 TQCut.cxx:1891
 TQCut.cxx:1892
 TQCut.cxx:1893
 TQCut.cxx:1894
 TQCut.cxx:1895
 TQCut.cxx:1896
 TQCut.cxx:1897
 TQCut.cxx:1898
 TQCut.cxx:1899
 TQCut.cxx:1900
 TQCut.cxx:1901
 TQCut.cxx:1902
 TQCut.cxx:1903
 TQCut.cxx:1904
 TQCut.cxx:1905
 TQCut.cxx:1906
 TQCut.cxx:1907
 TQCut.cxx:1908
 TQCut.cxx:1909
 TQCut.cxx:1910
 TQCut.cxx:1911
 TQCut.cxx:1912
 TQCut.cxx:1913
 TQCut.cxx:1914
 TQCut.cxx:1915
 TQCut.cxx:1916
 TQCut.cxx:1917
 TQCut.cxx:1918
 TQCut.cxx:1919
 TQCut.cxx:1920
 TQCut.cxx:1921
 TQCut.cxx:1922
 TQCut.cxx:1923
 TQCut.cxx:1924
 TQCut.cxx:1925
 TQCut.cxx:1926
 TQCut.cxx:1927
 TQCut.cxx:1928
 TQCut.cxx:1929
 TQCut.cxx:1930
 TQCut.cxx:1931
 TQCut.cxx:1932
 TQCut.cxx:1933
 TQCut.cxx:1934
 TQCut.cxx:1935
 TQCut.cxx:1936
 TQCut.cxx:1937
 TQCut.cxx:1938
 TQCut.cxx:1939
 TQCut.cxx:1940
 TQCut.cxx:1941
 TQCut.cxx:1942
 TQCut.cxx:1943
 TQCut.cxx:1944
 TQCut.cxx:1945
 TQCut.cxx:1946
 TQCut.cxx:1947
 TQCut.cxx:1948
 TQCut.cxx:1949
 TQCut.cxx:1950
 TQCut.cxx:1951
 TQCut.cxx:1952
 TQCut.cxx:1953
 TQCut.cxx:1954
 TQCut.cxx:1955
 TQCut.cxx:1956
 TQCut.cxx:1957
 TQCut.cxx:1958
 TQCut.cxx:1959
 TQCut.cxx:1960
 TQCut.cxx:1961
 TQCut.cxx:1962
 TQCut.cxx:1963
 TQCut.cxx:1964
 TQCut.cxx:1965
 TQCut.cxx:1966
 TQCut.cxx:1967
 TQCut.cxx:1968
 TQCut.cxx:1969
 TQCut.cxx:1970
 TQCut.cxx:1971
 TQCut.cxx:1972
 TQCut.cxx:1973
 TQCut.cxx:1974
 TQCut.cxx:1975
 TQCut.cxx:1976
 TQCut.cxx:1977
 TQCut.cxx:1978
 TQCut.cxx:1979
 TQCut.cxx:1980
 TQCut.cxx:1981
 TQCut.cxx:1982
 TQCut.cxx:1983
 TQCut.cxx:1984
 TQCut.cxx:1985
 TQCut.cxx:1986
 TQCut.cxx:1987
 TQCut.cxx:1988
 TQCut.cxx:1989
 TQCut.cxx:1990
 TQCut.cxx:1991
 TQCut.cxx:1992
 TQCut.cxx:1993
 TQCut.cxx:1994
 TQCut.cxx:1995
 TQCut.cxx:1996
 TQCut.cxx:1997
 TQCut.cxx:1998
 TQCut.cxx:1999
 TQCut.cxx:2000
 TQCut.cxx:2001
 TQCut.cxx:2002
 TQCut.cxx:2003
 TQCut.cxx:2004
 TQCut.cxx:2005
 TQCut.cxx:2006
 TQCut.cxx:2007
 TQCut.cxx:2008
 TQCut.cxx:2009
 TQCut.cxx:2010
 TQCut.cxx:2011
 TQCut.cxx:2012
 TQCut.cxx:2013
 TQCut.cxx:2014
 TQCut.cxx:2015
 TQCut.cxx:2016
 TQCut.cxx:2017
 TQCut.cxx:2018
 TQCut.cxx:2019
 TQCut.cxx:2020
 TQCut.cxx:2021
 TQCut.cxx:2022
 TQCut.cxx:2023
 TQCut.cxx:2024
 TQCut.cxx:2025
 TQCut.cxx:2026
 TQCut.cxx:2027
 TQCut.cxx:2028
 TQCut.cxx:2029
 TQCut.cxx:2030
 TQCut.cxx:2031
 TQCut.cxx:2032
 TQCut.cxx:2033
 TQCut.cxx:2034
 TQCut.cxx:2035
 TQCut.cxx:2036
 TQCut.cxx:2037
 TQCut.cxx:2038
 TQCut.cxx:2039
 TQCut.cxx:2040
 TQCut.cxx:2041
 TQCut.cxx:2042
 TQCut.cxx:2043
 TQCut.cxx:2044
 TQCut.cxx:2045
 TQCut.cxx:2046
 TQCut.cxx:2047
 TQCut.cxx:2048
 TQCut.cxx:2049
 TQCut.cxx:2050
 TQCut.cxx:2051
 TQCut.cxx:2052
 TQCut.cxx:2053
 TQCut.cxx:2054
 TQCut.cxx:2055
 TQCut.cxx:2056
 TQCut.cxx:2057
 TQCut.cxx:2058
 TQCut.cxx:2059
 TQCut.cxx:2060
 TQCut.cxx:2061
 TQCut.cxx:2062
 TQCut.cxx:2063
 TQCut.cxx:2064
 TQCut.cxx:2065
 TQCut.cxx:2066
 TQCut.cxx:2067
 TQCut.cxx:2068
 TQCut.cxx:2069
 TQCut.cxx:2070
 TQCut.cxx:2071
 TQCut.cxx:2072
 TQCut.cxx:2073
 TQCut.cxx:2074
 TQCut.cxx:2075
 TQCut.cxx:2076
 TQCut.cxx:2077
 TQCut.cxx:2078
 TQCut.cxx:2079
 TQCut.cxx:2080
 TQCut.cxx:2081
 TQCut.cxx:2082
 TQCut.cxx:2083
 TQCut.cxx:2084
 TQCut.cxx:2085
 TQCut.cxx:2086
 TQCut.cxx:2087
 TQCut.cxx:2088
 TQCut.cxx:2089
 TQCut.cxx:2090
 TQCut.cxx:2091
 TQCut.cxx:2092
 TQCut.cxx:2093
 TQCut.cxx:2094
 TQCut.cxx:2095
 TQCut.cxx:2096
 TQCut.cxx:2097
 TQCut.cxx:2098
 TQCut.cxx:2099
 TQCut.cxx:2100
 TQCut.cxx:2101
 TQCut.cxx:2102
 TQCut.cxx:2103
 TQCut.cxx:2104
 TQCut.cxx:2105
 TQCut.cxx:2106
 TQCut.cxx:2107
 TQCut.cxx:2108
 TQCut.cxx:2109
 TQCut.cxx:2110
 TQCut.cxx:2111
 TQCut.cxx:2112
 TQCut.cxx:2113
 TQCut.cxx:2114
 TQCut.cxx:2115
 TQCut.cxx:2116
 TQCut.cxx:2117
 TQCut.cxx:2118
 TQCut.cxx:2119
 TQCut.cxx:2120
 TQCut.cxx:2121
 TQCut.cxx:2122
 TQCut.cxx:2123
 TQCut.cxx:2124
 TQCut.cxx:2125
 TQCut.cxx:2126
 TQCut.cxx:2127
 TQCut.cxx:2128
 TQCut.cxx:2129
 TQCut.cxx:2130
 TQCut.cxx:2131
 TQCut.cxx:2132
 TQCut.cxx:2133
 TQCut.cxx:2134
 TQCut.cxx:2135
 TQCut.cxx:2136
 TQCut.cxx:2137
 TQCut.cxx:2138
 TQCut.cxx:2139
 TQCut.cxx:2140
 TQCut.cxx:2141
 TQCut.cxx:2142
 TQCut.cxx:2143
 TQCut.cxx:2144
 TQCut.cxx:2145
 TQCut.cxx:2146
 TQCut.cxx:2147
 TQCut.cxx:2148
 TQCut.cxx:2149
 TQCut.cxx:2150
 TQCut.cxx:2151
 TQCut.cxx:2152
 TQCut.cxx:2153
 TQCut.cxx:2154
 TQCut.cxx:2155
 TQCut.cxx:2156
 TQCut.cxx:2157
 TQCut.cxx:2158
 TQCut.cxx:2159
 TQCut.cxx:2160
 TQCut.cxx:2161
 TQCut.cxx:2162
 TQCut.cxx:2163
 TQCut.cxx:2164
 TQCut.cxx:2165
 TQCut.cxx:2166
 TQCut.cxx:2167
 TQCut.cxx:2168
 TQCut.cxx:2169
 TQCut.cxx:2170
 TQCut.cxx:2171
 TQCut.cxx:2172
 TQCut.cxx:2173
 TQCut.cxx:2174
 TQCut.cxx:2175
 TQCut.cxx:2176
 TQCut.cxx:2177
 TQCut.cxx:2178
 TQCut.cxx:2179
 TQCut.cxx:2180
 TQCut.cxx:2181
 TQCut.cxx:2182
 TQCut.cxx:2183
 TQCut.cxx:2184
 TQCut.cxx:2185
 TQCut.cxx:2186
 TQCut.cxx:2187
 TQCut.cxx:2188
 TQCut.cxx:2189
 TQCut.cxx:2190
 TQCut.cxx:2191
 TQCut.cxx:2192
 TQCut.cxx:2193
 TQCut.cxx:2194
 TQCut.cxx:2195
 TQCut.cxx:2196
 TQCut.cxx:2197
 TQCut.cxx:2198
 TQCut.cxx:2199
 TQCut.cxx:2200
 TQCut.cxx:2201
 TQCut.cxx:2202
 TQCut.cxx:2203
 TQCut.cxx:2204
 TQCut.cxx:2205
 TQCut.cxx:2206
 TQCut.cxx:2207
 TQCut.cxx:2208
 TQCut.cxx:2209
 TQCut.cxx:2210
 TQCut.cxx:2211
 TQCut.cxx:2212
 TQCut.cxx:2213
 TQCut.cxx:2214
 TQCut.cxx:2215
 TQCut.cxx:2216
 TQCut.cxx:2217
 TQCut.cxx:2218
 TQCut.cxx:2219
 TQCut.cxx:2220
 TQCut.cxx:2221
 TQCut.cxx:2222
 TQCut.cxx:2223
 TQCut.cxx:2224
 TQCut.cxx:2225
 TQCut.cxx:2226
 TQCut.cxx:2227
 TQCut.cxx:2228
 TQCut.cxx:2229
 TQCut.cxx:2230
 TQCut.cxx:2231
 TQCut.cxx:2232
 TQCut.cxx:2233
 TQCut.cxx:2234
 TQCut.cxx:2235
 TQCut.cxx:2236
 TQCut.cxx:2237
 TQCut.cxx:2238
 TQCut.cxx:2239
 TQCut.cxx:2240
 TQCut.cxx:2241
 TQCut.cxx:2242
 TQCut.cxx:2243
 TQCut.cxx:2244
 TQCut.cxx:2245
 TQCut.cxx:2246
 TQCut.cxx:2247
 TQCut.cxx:2248
 TQCut.cxx:2249
 TQCut.cxx:2250
 TQCut.cxx:2251
 TQCut.cxx:2252
 TQCut.cxx:2253
 TQCut.cxx:2254
 TQCut.cxx:2255
 TQCut.cxx:2256
 TQCut.cxx:2257
 TQCut.cxx:2258
 TQCut.cxx:2259
 TQCut.cxx:2260
 TQCut.cxx:2261
 TQCut.cxx:2262
 TQCut.cxx:2263
 TQCut.cxx:2264
 TQCut.cxx:2265
 TQCut.cxx:2266
 TQCut.cxx:2267
 TQCut.cxx:2268
 TQCut.cxx:2269
 TQCut.cxx:2270
 TQCut.cxx:2271
 TQCut.cxx:2272
 TQCut.cxx:2273
 TQCut.cxx:2274
 TQCut.cxx:2275
 TQCut.cxx:2276
 TQCut.cxx:2277
 TQCut.cxx:2278
 TQCut.cxx:2279
 TQCut.cxx:2280
 TQCut.cxx:2281
 TQCut.cxx:2282
 TQCut.cxx:2283
 TQCut.cxx:2284
 TQCut.cxx:2285
 TQCut.cxx:2286
 TQCut.cxx:2287
 TQCut.cxx:2288
 TQCut.cxx:2289
 TQCut.cxx:2290
 TQCut.cxx:2291
 TQCut.cxx:2292
 TQCut.cxx:2293
 TQCut.cxx:2294
 TQCut.cxx:2295
 TQCut.cxx:2296
 TQCut.cxx:2297
 TQCut.cxx:2298
 TQCut.cxx:2299
 TQCut.cxx:2300
 TQCut.cxx:2301
 TQCut.cxx:2302
 TQCut.cxx:2303
 TQCut.cxx:2304
 TQCut.cxx:2305
 TQCut.cxx:2306
 TQCut.cxx:2307
 TQCut.cxx:2308
 TQCut.cxx:2309
 TQCut.cxx:2310
 TQCut.cxx:2311
 TQCut.cxx:2312
 TQCut.cxx:2313
 TQCut.cxx:2314
 TQCut.cxx:2315
 TQCut.cxx:2316
 TQCut.cxx:2317
 TQCut.cxx:2318
 TQCut.cxx:2319
 TQCut.cxx:2320
 TQCut.cxx:2321
 TQCut.cxx:2322
 TQCut.cxx:2323
 TQCut.cxx:2324
 TQCut.cxx:2325
 TQCut.cxx:2326
 TQCut.cxx:2327
 TQCut.cxx:2328
 TQCut.cxx:2329
 TQCut.cxx:2330
 TQCut.cxx:2331
 TQCut.cxx:2332
 TQCut.cxx:2333
 TQCut.cxx:2334
 TQCut.cxx:2335
 TQCut.cxx:2336
 TQCut.cxx:2337
 TQCut.cxx:2338
 TQCut.cxx:2339
 TQCut.cxx:2340
 TQCut.cxx:2341
 TQCut.cxx:2342
 TQCut.cxx:2343
 TQCut.cxx:2344
 TQCut.cxx:2345
 TQCut.cxx:2346
 TQCut.cxx:2347
 TQCut.cxx:2348
 TQCut.cxx:2349
 TQCut.cxx:2350
 TQCut.cxx:2351
 TQCut.cxx:2352
 TQCut.cxx:2353
 TQCut.cxx:2354
 TQCut.cxx:2355
 TQCut.cxx:2356
 TQCut.cxx:2357
 TQCut.cxx:2358
 TQCut.cxx:2359
 TQCut.cxx:2360
 TQCut.cxx:2361
 TQCut.cxx:2362
 TQCut.cxx:2363
 TQCut.cxx:2364
 TQCut.cxx:2365
 TQCut.cxx:2366
 TQCut.cxx:2367
 TQCut.cxx:2368
 TQCut.cxx:2369
 TQCut.cxx:2370
 TQCut.cxx:2371
 TQCut.cxx:2372
 TQCut.cxx:2373
 TQCut.cxx:2374
 TQCut.cxx:2375
 TQCut.cxx:2376
 TQCut.cxx:2377
 TQCut.cxx:2378
 TQCut.cxx:2379
 TQCut.cxx:2380
 TQCut.cxx:2381
 TQCut.cxx:2382
 TQCut.cxx:2383
 TQCut.cxx:2384
 TQCut.cxx:2385
 TQCut.cxx:2386
 TQCut.cxx:2387
 TQCut.cxx:2388
 TQCut.cxx:2389
 TQCut.cxx:2390
 TQCut.cxx:2391
 TQCut.cxx:2392
 TQCut.cxx:2393
 TQCut.cxx:2394
 TQCut.cxx:2395
 TQCut.cxx:2396
 TQCut.cxx:2397
 TQCut.cxx:2398
 TQCut.cxx:2399
 TQCut.cxx:2400
 TQCut.cxx:2401
 TQCut.cxx:2402
 TQCut.cxx:2403
 TQCut.cxx:2404
 TQCut.cxx:2405
 TQCut.cxx:2406
 TQCut.cxx:2407
 TQCut.cxx:2408
 TQCut.cxx:2409
 TQCut.cxx:2410
 TQCut.cxx:2411
 TQCut.cxx:2412
 TQCut.cxx:2413
 TQCut.cxx:2414
 TQCut.cxx:2415
 TQCut.cxx:2416
 TQCut.cxx:2417
 TQCut.cxx:2418
 TQCut.cxx:2419
 TQCut.cxx:2420
 TQCut.cxx:2421
 TQCut.cxx:2422
 TQCut.cxx:2423
 TQCut.cxx:2424
 TQCut.cxx:2425
 TQCut.cxx:2426
 TQCut.cxx:2427
 TQCut.cxx:2428
 TQCut.cxx:2429
 TQCut.cxx:2430
 TQCut.cxx:2431
 TQCut.cxx:2432
 TQCut.cxx:2433
 TQCut.cxx:2434
 TQCut.cxx:2435
 TQCut.cxx:2436
 TQCut.cxx:2437
 TQCut.cxx:2438
 TQCut.cxx:2439
 TQCut.cxx:2440
 TQCut.cxx:2441
 TQCut.cxx:2442
 TQCut.cxx:2443
 TQCut.cxx:2444
 TQCut.cxx:2445
 TQCut.cxx:2446
 TQCut.cxx:2447
 TQCut.cxx:2448
 TQCut.cxx:2449
 TQCut.cxx:2450
 TQCut.cxx:2451
 TQCut.cxx:2452
 TQCut.cxx:2453
 TQCut.cxx:2454
 TQCut.cxx:2455
 TQCut.cxx:2456
 TQCut.cxx:2457
 TQCut.cxx:2458
 TQCut.cxx:2459
 TQCut.cxx:2460
 TQCut.cxx:2461
 TQCut.cxx:2462
 TQCut.cxx:2463
 TQCut.cxx:2464
 TQCut.cxx:2465
 TQCut.cxx:2466
 TQCut.cxx:2467
 TQCut.cxx:2468
 TQCut.cxx:2469
 TQCut.cxx:2470
 TQCut.cxx:2471
 TQCut.cxx:2472
 TQCut.cxx:2473
 TQCut.cxx:2474
 TQCut.cxx:2475
 TQCut.cxx:2476
 TQCut.cxx:2477
 TQCut.cxx:2478
 TQCut.cxx:2479
 TQCut.cxx:2480
 TQCut.cxx:2481
 TQCut.cxx:2482
 TQCut.cxx:2483
 TQCut.cxx:2484
 TQCut.cxx:2485
 TQCut.cxx:2486
 TQCut.cxx:2487
 TQCut.cxx:2488
 TQCut.cxx:2489
 TQCut.cxx:2490
 TQCut.cxx:2491
 TQCut.cxx:2492
 TQCut.cxx:2493
 TQCut.cxx:2494
 TQCut.cxx:2495
 TQCut.cxx:2496
 TQCut.cxx:2497
 TQCut.cxx:2498
 TQCut.cxx:2499
 TQCut.cxx:2500
 TQCut.cxx:2501
 TQCut.cxx:2502
 TQCut.cxx:2503
 TQCut.cxx:2504
 TQCut.cxx:2505
 TQCut.cxx:2506
 TQCut.cxx:2507
 TQCut.cxx:2508
 TQCut.cxx:2509
 TQCut.cxx:2510
 TQCut.cxx:2511
 TQCut.cxx:2512
 TQCut.cxx:2513
 TQCut.cxx:2514
 TQCut.cxx:2515
 TQCut.cxx:2516
 TQCut.cxx:2517
 TQCut.cxx:2518
 TQCut.cxx:2519
 TQCut.cxx:2520
 TQCut.cxx:2521
 TQCut.cxx:2522
 TQCut.cxx:2523
 TQCut.cxx:2524
 TQCut.cxx:2525
 TQCut.cxx:2526
 TQCut.cxx:2527
 TQCut.cxx:2528
 TQCut.cxx:2529
 TQCut.cxx:2530
 TQCut.cxx:2531
 TQCut.cxx:2532
 TQCut.cxx:2533
 TQCut.cxx:2534
 TQCut.cxx:2535
 TQCut.cxx:2536
 TQCut.cxx:2537
 TQCut.cxx:2538
 TQCut.cxx:2539
 TQCut.cxx:2540
 TQCut.cxx:2541
 TQCut.cxx:2542
 TQCut.cxx:2543
 TQCut.cxx:2544
 TQCut.cxx:2545
 TQCut.cxx:2546
 TQCut.cxx:2547
 TQCut.cxx:2548
 TQCut.cxx:2549
 TQCut.cxx:2550
 TQCut.cxx:2551
 TQCut.cxx:2552
 TQCut.cxx:2553
 TQCut.cxx:2554
 TQCut.cxx:2555
 TQCut.cxx:2556
 TQCut.cxx:2557
 TQCut.cxx:2558
 TQCut.cxx:2559
 TQCut.cxx:2560
 TQCut.cxx:2561
 TQCut.cxx:2562
 TQCut.cxx:2563
 TQCut.cxx:2564
 TQCut.cxx:2565
 TQCut.cxx:2566
 TQCut.cxx:2567
 TQCut.cxx:2568
 TQCut.cxx:2569
 TQCut.cxx:2570
 TQCut.cxx:2571
 TQCut.cxx:2572
 TQCut.cxx:2573
 TQCut.cxx:2574
 TQCut.cxx:2575
 TQCut.cxx:2576
 TQCut.cxx:2577
 TQCut.cxx:2578
 TQCut.cxx:2579
 TQCut.cxx:2580
 TQCut.cxx:2581
 TQCut.cxx:2582
 TQCut.cxx:2583
 TQCut.cxx:2584
 TQCut.cxx:2585
 TQCut.cxx:2586
 TQCut.cxx:2587
 TQCut.cxx:2588
 TQCut.cxx:2589
 TQCut.cxx:2590
 TQCut.cxx:2591
 TQCut.cxx:2592
 TQCut.cxx:2593
 TQCut.cxx:2594
 TQCut.cxx:2595
 TQCut.cxx:2596
 TQCut.cxx:2597
 TQCut.cxx:2598
 TQCut.cxx:2599
 TQCut.cxx:2600
 TQCut.cxx:2601
 TQCut.cxx:2602
 TQCut.cxx:2603
 TQCut.cxx:2604
 TQCut.cxx:2605
 TQCut.cxx:2606
 TQCut.cxx:2607
 TQCut.cxx:2608
 TQCut.cxx:2609
 TQCut.cxx:2610
 TQCut.cxx:2611
 TQCut.cxx:2612
 TQCut.cxx:2613
 TQCut.cxx:2614
 TQCut.cxx:2615
 TQCut.cxx:2616
 TQCut.cxx:2617
 TQCut.cxx:2618
 TQCut.cxx:2619
 TQCut.cxx:2620
 TQCut.cxx:2621
 TQCut.cxx:2622
 TQCut.cxx:2623
 TQCut.cxx:2624
 TQCut.cxx:2625
 TQCut.cxx:2626
 TQCut.cxx:2627
 TQCut.cxx:2628
 TQCut.cxx:2629
 TQCut.cxx:2630
 TQCut.cxx:2631
 TQCut.cxx:2632
 TQCut.cxx:2633
 TQCut.cxx:2634
 TQCut.cxx:2635
 TQCut.cxx:2636
 TQCut.cxx:2637
 TQCut.cxx:2638
 TQCut.cxx:2639
 TQCut.cxx:2640
 TQCut.cxx:2641
 TQCut.cxx:2642
 TQCut.cxx:2643
 TQCut.cxx:2644
 TQCut.cxx:2645
 TQCut.cxx:2646
 TQCut.cxx:2647
 TQCut.cxx:2648
 TQCut.cxx:2649
 TQCut.cxx:2650
 TQCut.cxx:2651
 TQCut.cxx:2652
 TQCut.cxx:2653
 TQCut.cxx:2654
 TQCut.cxx:2655
 TQCut.cxx:2656
 TQCut.cxx:2657
 TQCut.cxx:2658
 TQCut.cxx:2659
 TQCut.cxx:2660
 TQCut.cxx:2661
 TQCut.cxx:2662
 TQCut.cxx:2663
 TQCut.cxx:2664
 TQCut.cxx:2665
 TQCut.cxx:2666
 TQCut.cxx:2667
 TQCut.cxx:2668
 TQCut.cxx:2669
 TQCut.cxx:2670
 TQCut.cxx:2671
 TQCut.cxx:2672
 TQCut.cxx:2673
 TQCut.cxx:2674
 TQCut.cxx:2675
 TQCut.cxx:2676
 TQCut.cxx:2677
 TQCut.cxx:2678
 TQCut.cxx:2679
 TQCut.cxx:2680
 TQCut.cxx:2681
 TQCut.cxx:2682
 TQCut.cxx:2683
 TQCut.cxx:2684
 TQCut.cxx:2685
 TQCut.cxx:2686
 TQCut.cxx:2687
 TQCut.cxx:2688
 TQCut.cxx:2689
 TQCut.cxx:2690
 TQCut.cxx:2691
 TQCut.cxx:2692
 TQCut.cxx:2693
 TQCut.cxx:2694
 TQCut.cxx:2695
 TQCut.cxx:2696
 TQCut.cxx:2697
 TQCut.cxx:2698
 TQCut.cxx:2699
 TQCut.cxx:2700
 TQCut.cxx:2701
 TQCut.cxx:2702
 TQCut.cxx:2703
 TQCut.cxx:2704
 TQCut.cxx:2705
 TQCut.cxx:2706
 TQCut.cxx:2707
 TQCut.cxx:2708
 TQCut.cxx:2709
 TQCut.cxx:2710
 TQCut.cxx:2711
 TQCut.cxx:2712
 TQCut.cxx:2713
 TQCut.cxx:2714
 TQCut.cxx:2715
 TQCut.cxx:2716
 TQCut.cxx:2717
 TQCut.cxx:2718
 TQCut.cxx:2719
 TQCut.cxx:2720
 TQCut.cxx:2721
 TQCut.cxx:2722
 TQCut.cxx:2723
 TQCut.cxx:2724
 TQCut.cxx:2725
 TQCut.cxx:2726
 TQCut.cxx:2727
 TQCut.cxx:2728
 TQCut.cxx:2729
 TQCut.cxx:2730
 TQCut.cxx:2731
 TQCut.cxx:2732
 TQCut.cxx:2733
 TQCut.cxx:2734
 TQCut.cxx:2735
 TQCut.cxx:2736
 TQCut.cxx:2737
 TQCut.cxx:2738
 TQCut.cxx:2739
 TQCut.cxx:2740
 TQCut.cxx:2741
 TQCut.cxx:2742
 TQCut.cxx:2743
 TQCut.cxx:2744
 TQCut.cxx:2745
 TQCut.cxx:2746
 TQCut.cxx:2747
 TQCut.cxx:2748
 TQCut.cxx:2749
 TQCut.cxx:2750
 TQCut.cxx:2751
 TQCut.cxx:2752
 TQCut.cxx:2753
 TQCut.cxx:2754
 TQCut.cxx:2755
 TQCut.cxx:2756
 TQCut.cxx:2757
 TQCut.cxx:2758
 TQCut.cxx:2759
 TQCut.cxx:2760
 TQCut.cxx:2761
 TQCut.cxx:2762
 TQCut.cxx:2763
 TQCut.cxx:2764
 TQCut.cxx:2765
 TQCut.cxx:2766
 TQCut.cxx:2767
 TQCut.cxx:2768
 TQCut.cxx:2769
 TQCut.cxx:2770
 TQCut.cxx:2771
 TQCut.cxx:2772
 TQCut.cxx:2773
 TQCut.cxx:2774
 TQCut.cxx:2775
 TQCut.cxx:2776
 TQCut.cxx:2777
 TQCut.cxx:2778
 TQCut.cxx:2779
 TQCut.cxx:2780
 TQCut.cxx:2781
 TQCut.cxx:2782
 TQCut.cxx:2783
 TQCut.cxx:2784
 TQCut.cxx:2785
 TQCut.cxx:2786
 TQCut.cxx:2787
 TQCut.cxx:2788
 TQCut.cxx:2789
 TQCut.cxx:2790
 TQCut.cxx:2791
 TQCut.cxx:2792
 TQCut.cxx:2793
 TQCut.cxx:2794
 TQCut.cxx:2795
 TQCut.cxx:2796
 TQCut.cxx:2797
 TQCut.cxx:2798
 TQCut.cxx:2799
 TQCut.cxx:2800
 TQCut.cxx:2801
 TQCut.cxx:2802
 TQCut.cxx:2803
 TQCut.cxx:2804
 TQCut.cxx:2805
 TQCut.cxx:2806
 TQCut.cxx:2807
 TQCut.cxx:2808
 TQCut.cxx:2809
 TQCut.cxx:2810
 TQCut.cxx:2811
 TQCut.cxx:2812
 TQCut.cxx:2813
 TQCut.cxx:2814
 TQCut.cxx:2815
 TQCut.cxx:2816
 TQCut.cxx:2817
 TQCut.cxx:2818
 TQCut.cxx:2819
 TQCut.cxx:2820
 TQCut.cxx:2821
 TQCut.cxx:2822
 TQCut.cxx:2823
 TQCut.cxx:2824
 TQCut.cxx:2825
 TQCut.cxx:2826
 TQCut.cxx:2827
 TQCut.cxx:2828
 TQCut.cxx:2829
 TQCut.cxx:2830
 TQCut.cxx:2831
 TQCut.cxx:2832
 TQCut.cxx:2833
 TQCut.cxx:2834
 TQCut.cxx:2835
 TQCut.cxx:2836
 TQCut.cxx:2837
 TQCut.cxx:2838
 TQCut.cxx:2839
 TQCut.cxx:2840
 TQCut.cxx:2841
 TQCut.cxx:2842
 TQCut.cxx:2843
 TQCut.cxx:2844
 TQCut.cxx:2845
 TQCut.cxx:2846
 TQCut.cxx:2847
 TQCut.cxx:2848
 TQCut.cxx:2849
 TQCut.cxx:2850
 TQCut.cxx:2851
 TQCut.cxx:2852
 TQCut.cxx:2853
 TQCut.cxx:2854
 TQCut.cxx:2855
 TQCut.cxx:2856
 TQCut.cxx:2857
 TQCut.cxx:2858
 TQCut.cxx:2859
 TQCut.cxx:2860
 TQCut.cxx:2861
 TQCut.cxx:2862
 TQCut.cxx:2863
 TQCut.cxx:2864
 TQCut.cxx:2865
 TQCut.cxx:2866
 TQCut.cxx:2867
 TQCut.cxx:2868
 TQCut.cxx:2869
 TQCut.cxx:2870
 TQCut.cxx:2871
 TQCut.cxx:2872
 TQCut.cxx:2873
 TQCut.cxx:2874
 TQCut.cxx:2875
 TQCut.cxx:2876
 TQCut.cxx:2877
 TQCut.cxx:2878
 TQCut.cxx:2879
 TQCut.cxx:2880
 TQCut.cxx:2881
 TQCut.cxx:2882
 TQCut.cxx:2883
 TQCut.cxx:2884
 TQCut.cxx:2885
 TQCut.cxx:2886
 TQCut.cxx:2887
 TQCut.cxx:2888
 TQCut.cxx:2889
 TQCut.cxx:2890
 TQCut.cxx:2891
 TQCut.cxx:2892
 TQCut.cxx:2893
 TQCut.cxx:2894
 TQCut.cxx:2895
 TQCut.cxx:2896
 TQCut.cxx:2897
 TQCut.cxx:2898
 TQCut.cxx:2899
 TQCut.cxx:2900
 TQCut.cxx:2901
 TQCut.cxx:2902
 TQCut.cxx:2903
 TQCut.cxx:2904
 TQCut.cxx:2905
 TQCut.cxx:2906
 TQCut.cxx:2907
 TQCut.cxx:2908
 TQCut.cxx:2909
 TQCut.cxx:2910
 TQCut.cxx:2911
 TQCut.cxx:2912
 TQCut.cxx:2913
 TQCut.cxx:2914
 TQCut.cxx:2915
 TQCut.cxx:2916
 TQCut.cxx:2917
 TQCut.cxx:2918
 TQCut.cxx:2919
 TQCut.cxx:2920
 TQCut.cxx:2921
 TQCut.cxx:2922
 TQCut.cxx:2923
 TQCut.cxx:2924
 TQCut.cxx:2925
 TQCut.cxx:2926
 TQCut.cxx:2927
 TQCut.cxx:2928
 TQCut.cxx:2929
 TQCut.cxx:2930
 TQCut.cxx:2931
 TQCut.cxx:2932
 TQCut.cxx:2933
 TQCut.cxx:2934
 TQCut.cxx:2935
 TQCut.cxx:2936
 TQCut.cxx:2937
 TQCut.cxx:2938
 TQCut.cxx:2939
 TQCut.cxx:2940
 TQCut.cxx:2941
 TQCut.cxx:2942
 TQCut.cxx:2943
 TQCut.cxx:2944
 TQCut.cxx:2945
 TQCut.cxx:2946
 TQCut.cxx:2947
 TQCut.cxx:2948
 TQCut.cxx:2949
 TQCut.cxx:2950
 TQCut.cxx:2951
 TQCut.cxx:2952
 TQCut.cxx:2953
 TQCut.cxx:2954
 TQCut.cxx:2955
 TQCut.cxx:2956
 TQCut.cxx:2957
 TQCut.cxx:2958
 TQCut.cxx:2959