#include "RooAbsReal.h"
#include "RooWorkspace.h"

#include "SFramework/TSUtils.h"
#include "QFramework/TQFolder.h"
#include "QFramework/TQUtils.h"
#include "QFramework/TQIterator.h"
#include "QFramework/TQStringUtils.h"

#include "RooRealVar.h"
#include "RooRealSumPdf.h"
#include "RooProdPdf.h"
#include "RooProduct.h"
#include "RooMultiVarGaussian.h"

#include "RooCategory.h"
#include "RooFitResult.h"
#include "RooConstVar.h"
#include "RooSimultaneous.h"
#include "RooDataSet.h"
#include "RooLinkedList.h"
#include "RooStats/ModelConfig.h"
#include "RooAbsDataStore.h"

#include "Fit/FitConfig.h"

#include "RooHistFunc.h"
#include "RooDataHist.h"
#include "RooDataSet.h"
#include "RooSimultaneous.h"
#if ROOT_VERSION_CODE < ROOT_VERSION(6,28,0)      
#include "RooMinimizerFcn.h"
#endif
#include "RooStats/HistFactory/PiecewiseInterpolation.h"
//#include "RooStats/HistFactory/FlexibleInterpVar.h" //already included in the header (reason: ROOT/Cling/dictionaries)

#include "TH2.h"
#include "TH2F.h"
#include "TH1.h"

#include "TMath.h"
#include "TCanvas.h"
#include "TMatrixD.h"
#include "TDecompLU.h"
#include "TMatrixDSym.h"

#include <assert.h>
#include <utility>
#include <limits>

#include "RooStats/HypoTestInverter.h"
#include "RooStats/HypoTestInverterResult.h"
#include "RooStats/HypoTestInverterPlot.h"

// #define _DEBUG_

#include "QFramework/TQLibrary.h"

#include "SFramework/TSIterator.h"
#include "SFramework/TSStatisticsManager.h"

// typedef helpers for older ROOT versions
#if ROOT_VERSION_CODE < ROOT_VERSION(6,25,0)
typedef RooMinimizerFcn RooAbsMinimizerFcn;
#endif

// iterator helpers for older ROOT versions
#if ROOT_VERSION_CODE < ROOT_VERSION(6,18,0)
RooAbsCollection_IteratorHelper::RooAbsCollection_IteratorHelper(const RooAbsCollection& c, bool end) : itr(c.fwdIterator()), nextItem(end ? NULL : itr.next()) {}
RooAbsArg* RooAbsCollection_IteratorHelper::operator++(){ nextItem = itr.next(); return nextItem; }
bool RooAbsCollection_IteratorHelper::operator!=(const RooAbsCollection_IteratorHelper& other){ return this->nextItem != other.nextItem; }
bool RooAbsCollection_IteratorHelper::operator!=(const RooAbsArg* other){  return this->nextItem != other; }
RooAbsArg* RooAbsCollection_IteratorHelper::operator*(){ return nextItem; }
RooAbsCollection_IteratorHelper begin(const RooAbsCollection& c){
  return RooAbsCollection_IteratorHelper(c,false);
}
RooAbsCollection_IteratorHelper end(const RooAbsCollection& c){
  return RooAbsCollection_IteratorHelper(c,true);
}
#endif
#if ROOT_VERSION_CODE < ROOT_VERSION(6,30,0)
RooLinkedList_IteratorHelper::RooLinkedList_IteratorHelper(const RooLinkedList& c, bool end) : itr(c.fwdIterator()), nextItem(end ? NULL : itr.next()) {}
RooAbsArg* RooLinkedList_IteratorHelper::operator++(){ nextItem = itr.next(); return nextItem; }
bool RooLinkedList_IteratorHelper::operator!=(const RooLinkedList_IteratorHelper& other){ return this->nextItem != other.nextItem; }
bool RooLinkedList_IteratorHelper::operator!=(const RooAbsArg* other){  return this->nextItem != other; }
RooAbsArg* RooLinkedList_IteratorHelper::operator*(){ return nextItem; }
RooLinkedList_IteratorHelper begin(const RooLinkedList& c){
  return RooLinkedList_IteratorHelper(c,false);
}
RooLinkedList_IteratorHelper end(const RooLinkedList& c){
  return RooLinkedList_IteratorHelper(c,true);
}
RooFIter_IteratorHelper::RooFIter_IteratorHelper(RooFIter& it, bool end) : itr(&it), nextItem(end ? NULL : itr->next()) {}
RooAbsArg* RooFIter_IteratorHelper::operator++(){ nextItem = itr->next(); return nextItem; }
bool RooFIter_IteratorHelper::operator!=(const RooFIter_IteratorHelper& other){ return this->nextItem != other.nextItem; }
bool RooFIter_IteratorHelper::operator!=(const RooAbsArg* other){  return this->nextItem != other; }
RooAbsArg* RooFIter_IteratorHelper::operator*(){ return nextItem; }
RooFIter_IteratorHelper begin(RooFIter& it){
  return RooFIter_IteratorHelper(it,false);
}
RooFIter_IteratorHelper end(RooFIter& it){
  return RooFIter_IteratorHelper(it,true);
}
TIterator_IteratorHelper::TIterator_IteratorHelper(TIterator* it, bool end) : itr(it), nextItem(end ? NULL : itr->Next()) {}
TObject* TIterator_IteratorHelper::operator++(){ nextItem = itr->Next(); return nextItem; }
bool TIterator_IteratorHelper::operator!=(const TIterator_IteratorHelper& other){ return this->nextItem != other.nextItem; }
bool TIterator_IteratorHelper::operator!=(const TObject* other){  return this->nextItem != other; }
TObject* TIterator_IteratorHelper::operator*(){ return nextItem; }
TIterator_IteratorHelper begin(TIterator* it){
  return TIterator_IteratorHelper(it,false);
}
TIterator_IteratorHelper end(TIterator* it){
  return TIterator_IteratorHelper(it,true);
}
#endif



//we need to free some members from their private/protected prison since there are no getters implemented for them:
//RooAbsReal::_plotMin
//RooAbsReal::_plotBins
//RooWorkspace::_snapshots
//RooFitResult::_CM

#define nan std::numeric_limits<double>::quiet_NaN()
#define inf std::numeric_limits<double>::infinity()

namespace {
  //c++ standard conform alternative to a public-private hack:
  //freeing members from RooAbsReal:
  template <typename RooAbsRealTag>
  struct RooAbsRealHackResult {
    typedef typename RooAbsRealTag::type type;
    static type ptr;
  };

  template <typename RooAbsRealTag>
  typename RooAbsRealHackResult<RooAbsRealTag>::type RooAbsRealHackResult<RooAbsRealTag>::ptr;

  template<typename RooAbsRealTag, typename RooAbsRealTag::type p>
  struct RooAbsRealRob : RooAbsRealHackResult<RooAbsRealTag> {
    struct RooAbsRealFiller {
      RooAbsRealFiller() {RooAbsRealHackResult<RooAbsRealTag>::ptr = p;}
    };
    static RooAbsRealFiller rooabsrealfiller_obj;
  };

  template<typename RooAbsRealTag, typename RooAbsRealTag::type p>
  typename RooAbsRealRob<RooAbsRealTag, p>::RooAbsRealFiller RooAbsRealRob<RooAbsRealTag, p>::rooabsrealfiller_obj;

  //now expose some members of RooAbsReal that we need to access
  struct RooAbsReal_plotMin { typedef Double_t(RooAbsReal::*type); };
  template class RooAbsRealRob<RooAbsReal_plotMin, &RooAbsReal::_plotMin>;

  struct RooAbsReal_plotMax { typedef Double_t(RooAbsReal::*type); };
  template class RooAbsRealRob<RooAbsReal_plotMax, &RooAbsReal::_plotMax>;

  struct RooAbsReal_plotBins { typedef Int_t(RooAbsReal::*type); };
  template class RooAbsRealRob<RooAbsReal_plotBins, &RooAbsReal::_plotBins>;

  //freeing members from RooWorkspace:
  template <typename RooWorkspaceTag>
  struct RooWorkspaceHackResult {
    typedef typename RooWorkspaceTag::type type;
    static type ptr;
  };

  template <typename RooWorkspaceTag>
  typename RooWorkspaceHackResult<RooWorkspaceTag>::type RooWorkspaceHackResult<RooWorkspaceTag>::ptr;

  template<typename RooWorkspaceTag, typename RooWorkspaceTag::type p>
  struct RooWorkspaceRob : RooWorkspaceHackResult<RooWorkspaceTag> {
    struct RooWorkspaceFiller {
      RooWorkspaceFiller() {RooWorkspaceHackResult<RooWorkspaceTag>::ptr = p;}
    };
    static RooWorkspaceFiller rooworkspacefiller_obj;
  };

  template<typename RooWorkspaceTag, typename RooWorkspaceTag::type p>
  typename RooWorkspaceRob<RooWorkspaceTag, p>::RooWorkspaceFiller RooWorkspaceRob<RooWorkspaceTag, p>::rooworkspacefiller_obj;

  //now expose some members of TAxis that we need to access
  struct RooWorkspace_snapshots { typedef RooLinkedList(RooWorkspace::*type); };
  template class RooWorkspaceRob<RooWorkspace_snapshots, &RooWorkspace::_snapshots>;
  struct RooWorkspace_namedSets { typedef std::map<std::string, RooArgSet>(RooWorkspace::*type); };
  template class RooWorkspaceRob<RooWorkspace_namedSets, &RooWorkspace::_namedSets>;



  // hack to get access to RooFitResult::_CM
  template <typename RooFitResultTag>
  struct RooFitResultHackResult {
    typedef typename RooFitResultTag::type type;
    static type ptr;
  };

  template <typename RooFitResultTag>
  typename RooFitResultHackResult<RooFitResultTag>::type RooFitResultHackResult<RooFitResultTag>::ptr;

  template<typename RooFitResultTag, typename RooFitResultTag::type p>
  struct RooFitResultRob : RooFitResultHackResult<RooFitResultTag> {
    struct RooFitResultFiller {
      RooFitResultFiller() {RooFitResultHackResult<RooFitResultTag>::ptr = p;}
    };
    static RooFitResultFiller roofitresultfiller_obj;
  };

  template<typename RooFitResultTag, typename RooFitResultTag::type p>
  typename RooFitResultRob<RooFitResultTag, p>::RooFitResultFiller RooFitResultRob<RooFitResultTag, p>::roofitresultfiller_obj;

  //now expose some members of RooFitResult that we need to access
  struct RooFitResultCM { typedef TMatrixDSym*(RooFitResult::*type); };
  template class RooFitResultRob<RooFitResultCM, &RooFitResult::_CM>;
  struct RooFitResultVM { typedef TMatrixDSym*(RooFitResult::*type); };
  template class RooFitResultRob<RooFitResultVM, &RooFitResult::_VM>;
}


namespace {
  //somewhat complex but apparently standard conform hack to access
  template <typename RooMinimizerTag>
  struct RooMinimizerHackResult {
    typedef typename RooMinimizerTag::type type;
    static type ptr;
  };

  template <typename RooMinimizerTag>
  typename RooMinimizerHackResult<RooMinimizerTag>::type RooMinimizerHackResult<RooMinimizerTag>::ptr;

  template<typename RooMinimizerTag, typename RooMinimizerTag::type p>
  struct RooMinimizerRob : RooMinimizerHackResult<RooMinimizerTag> {
    struct RooMinimizerFiller {
      RooMinimizerFiller() {RooMinimizerHackResult<RooMinimizerTag>::ptr = p;}
    };
    static RooMinimizerFiller RooMinimizerfiller_obj;
  };

  template<typename RooMinimizerTag, typename RooMinimizerTag::type p>
  typename RooMinimizerRob<RooMinimizerTag, p>::RooMinimizerFiller RooMinimizerRob<RooMinimizerTag, p>::RooMinimizerfiller_obj;

  //now expose some members of RooMinimizer that we need to access
  struct RooMinimizer_getNPar      { typedef Int_t           (RooMinimizer::*type)() const; };
  template class RooMinimizerRob<RooMinimizer_getNPar,      &RooMinimizer::getNPar  >;
}

namespace {
  //somewhat complex but apparently standard conform hack to access
  template <typename RooProdPdfTag>
  struct RooProdPdfHackResult {
    typedef typename RooProdPdfTag::type type;
    static type ptr;
  };

  template <typename RooProdPdfTag>
  typename RooProdPdfHackResult<RooProdPdfTag>::type RooProdPdfHackResult<RooProdPdfTag>::ptr;

  template<typename RooProdPdfTag, typename RooProdPdfTag::type p>
  struct RooProdPdfRob : RooProdPdfHackResult<RooProdPdfTag> {
    struct RooProdPdfFiller {
      RooProdPdfFiller() {RooProdPdfHackResult<RooProdPdfTag>::ptr = p;}
    };
    static RooProdPdfFiller RooProdPdffiller_obj;
  };

  template<typename RooProdPdfTag, typename RooProdPdfTag::type p>
  typename RooProdPdfRob<RooProdPdfTag, p>::RooProdPdfFiller RooProdPdfRob<RooProdPdfTag, p>::RooProdPdffiller_obj;

  //now expose some members of RooProdPdf that we need to access
  struct RooProdPdf_pdfList { typedef RooListProxy (RooProdPdf::*type); };
  template class RooProdPdfRob<RooProdPdf_pdfList, &RooProdPdf::_pdfList>;

  struct RooProdPdf_extendedIndex { typedef int (RooProdPdf::*type); };
  template class RooProdPdfRob<RooProdPdf_extendedIndex, &RooProdPdf::_extendedIndex>;
}



//__________________________________________________________________________________|___________

int TSUtils::nParameters(const RooMinimizer& minimizer){
  return (minimizer.*RooMinimizerHackResult<RooMinimizer_getNPar>::ptr)();
}

//__________________________________________________________________________________|___________

#if ROOT_VERSION_CODE < ROOT_VERSION(6,25,0)  
RooMinimizerFcn* TSUtils::getFunction(RooMinimizer& minimizer){
  return (RooAbsMinimizerFcn*) minimizer.fitter()->GetFCN();
}
#else
RooAbsMinimizerFcn* TSUtils::getFunction(RooMinimizer& minimizer){
  return (RooAbsMinimizerFcn*) minimizer.fitter()->GetFCN();
}
#endif

//__________________________________________________________________________________|___________

class PiecewiseInterpolationHelper : public ::PiecewiseInterpolation {
  struct Components {
    size_t index;
    RooAbsArg *low,*high,*param;
    Components(size_t index_, RooAbsArg* low_, RooAbsArg* high_, RooAbsArg* param_) : index(index_), low(low_), high(high_), param(param_) {}
  };
  public:

  static RooAbsArg* getNominalMember(const PiecewiseInterpolation* pw_) {
    if (!pw_) return nullptr;
    PiecewiseInterpolationHelper* pw = (PiecewiseInterpolationHelper*) pw_;
    return pw->_nominal.absArg();
  }
  static RooListProxy* getParamSetMember(const PiecewiseInterpolation* pw_) {
    if (!pw_) return nullptr;
    PiecewiseInterpolationHelper* pw = (PiecewiseInterpolationHelper*) pw_;
    return &(pw->_paramSet);
  }
  static RooListProxy* getHighSetMember(const PiecewiseInterpolation* pw_) {
    if (!pw_) return nullptr;
    PiecewiseInterpolationHelper* pw = (PiecewiseInterpolationHelper*) pw_;
    return &(pw->_highSet);
  }
  static RooListProxy* getLowSetMember(const PiecewiseInterpolation* pw_) {
    if (!pw_) return nullptr;
    PiecewiseInterpolationHelper* pw = (PiecewiseInterpolationHelper*) pw_;
    return &(pw->_lowSet);
  }
  static void removeConstituents(PiecewiseInterpolation* pw_, const TString& filter) {
    if (!pw_) return;
    PiecewiseInterpolationHelper* pw = (PiecewiseInterpolationHelper*) pw_;
    //members modified/considered in the following:
    //_nominal //don't remove, this wouldn't make sense
    //_normSet //seems to be unused in entire PiecewiseInterpolation class...

    //_ownedList //only for cleanup, no active searching

    //_lowSet
    //_highSet
    //_paramSet
    //_interpCode
    auto paramIter(TSUtils::toVector<RooAbsReal*>(pw->_paramSet));
    auto highIter(TSUtils::toVector<RooAbsReal*>(pw->_highSet));
    auto lowIter(TSUtils::toVector<RooAbsReal*>(pw->_lowSet));

    std::vector<Components> toRemove;
    for(size_t index = 0; index<paramIter.size(); ++index){
      if (TQStringUtils::matchesFilter(paramIter[index]->GetName(),filter,",")
          || TQStringUtils::matchesFilter(highIter[index]->GetName(),filter,",")
          || TQStringUtils::matchesFilter(lowIter[index]->GetName(),filter,",")  ) {
        Components comp(index, lowIter[index], highIter[index], paramIter[index]);
        toRemove.push_back(comp);
      }
      ++index;
    }
    int indexOffset = 0;
    for (Components& comp : toRemove) {
      pw->_paramSet.remove(*(comp.param));
      pw->_highSet.remove(*(comp.high));
      pw->_lowSet.remove(*(comp.low));
      pw->_ownedList.remove(*(comp.param), true);
      pw->_ownedList.remove(*(comp.high), true);
      pw->_ownedList.remove(*(comp.low), true);
      pw->_interpCode.erase(pw->_interpCode.begin() + (comp.index - indexOffset));
      ++indexOffset;
    }

  }


};
//expose to the outer world:
RooAbsArg* TSUtils::getNominalMember(const PiecewiseInterpolation* _interp) {
  return PiecewiseInterpolationHelper::getNominalMember(_interp);
}
RooListProxy* TSUtils::getParamSetMember(const PiecewiseInterpolation* _interp) {
  return PiecewiseInterpolationHelper::getParamSetMember(_interp);
}
RooListProxy* TSUtils::getHighSetMember(const PiecewiseInterpolation* _interp) {
  return PiecewiseInterpolationHelper::getHighSetMember(_interp);
}
RooListProxy* TSUtils::getLowSetMember(const PiecewiseInterpolation* _interp) {
  return PiecewiseInterpolationHelper::getLowSetMember(_interp);
}
void TSUtils::removeConstituentsFromPiecewiseInterpolation(PiecewiseInterpolation* interp, const TString& filter) {
  PiecewiseInterpolationHelper::removeConstituents(interp,filter);
}

//__________________________________________________________________________________|___________

class FlexibleInterpVarHelper : RooStats::HistFactory::FlexibleInterpVar {
  public:
  static Double_t* getNominalMemberPtr(const RooStats::HistFactory::FlexibleInterpVar* interp_) {
    //exposing as pointer in case we need to modify it
    FlexibleInterpVarHelper* interp = (FlexibleInterpVarHelper*) interp_;
    if (!interp) return nullptr;
    return &(interp->_nominal);
  }

  static Double_t getNominalMember(const RooStats::HistFactory::FlexibleInterpVar* interp_) {
    //convenience wrapper to only get the plain value
    Double_t* ptr = getNominalMemberPtr(interp_);
    if (!ptr) return std::numeric_limits<double>::quiet_NaN();
    return *ptr;
  }

  static std::vector<double>* getHighMember(const RooStats::HistFactory::FlexibleInterpVar* interp_) {
    FlexibleInterpVarHelper* interp = (FlexibleInterpVarHelper*) interp_;
    if (!interp) return nullptr;
    return &(interp->_high);
  }

  static std::vector<double>* getLowMember(const RooStats::HistFactory::FlexibleInterpVar* interp_) {
    FlexibleInterpVarHelper* interp = (FlexibleInterpVarHelper*) interp_;
    if (!interp) return nullptr;
    return &(interp->_low);
  }

  static RooListProxy* getParamListMember(const RooStats::HistFactory::FlexibleInterpVar* interp_) {
    FlexibleInterpVarHelper* interp = (FlexibleInterpVarHelper*) interp_;
    if (!interp) return nullptr;
    return &(interp->_paramList);
  }

  static void removeConstituents(RooStats::HistFactory::FlexibleInterpVar* interp_, const TString& filter) {
    if (!interp_) return;
    FlexibleInterpVarHelper* interp = (FlexibleInterpVarHelper*) interp_;
    //members to modify:
    //_paramList
    //_low
    //_high
    //_interpCode
    std::vector<std::pair<size_t,RooAbsArg*>> toRemove;
    size_t index = 0;
    ROOFIT_ITERATE(interp->_paramList,auto,buff){
      if (buff && (TQStringUtils::matchesFilter(buff->GetName(),filter,","))) {
        std::pair<size_t,RooAbsArg*> rem(index,dynamic_cast<RooAbsArg*>(buff));
        toRemove.push_back(rem);
      }
      ++index;
    }
    int indexOffset = 0;
    for (auto& rem : toRemove) {
      interp->_interpCode.erase(interp->_interpCode.begin() + (rem.first - indexOffset));
      interp->_low.erase(interp->_low.begin() + (rem.first - indexOffset));
      interp->_high.erase(interp->_high.begin() + (rem.first - indexOffset));
      interp->_paramList.remove(*(rem.second));
      ++indexOffset; //increment index offset
    }

  }
};
  //expose to outside world:
Double_t* TSUtils::getNominalMemberPtr(const RooStats::HistFactory::FlexibleInterpVar* interp) {
  return FlexibleInterpVarHelper::getNominalMemberPtr(interp);
}
Double_t TSUtils::getNominalMember(const RooStats::HistFactory::FlexibleInterpVar* interp) {
  return FlexibleInterpVarHelper::getNominalMember(interp);
}
std::vector<double>* TSUtils::getHighMember(const RooStats::HistFactory::FlexibleInterpVar* interp) {
  return FlexibleInterpVarHelper::getHighMember(interp);
}
std::vector<double>* TSUtils::getLowMember(const RooStats::HistFactory::FlexibleInterpVar* interp) {
  return FlexibleInterpVarHelper::getLowMember(interp);
}
RooListProxy* TSUtils::getParamListMember(const RooStats::HistFactory::FlexibleInterpVar* interp) {
  return FlexibleInterpVarHelper::getParamListMember(interp);
}
void TSUtils::removeConstituentsFromFlexibleInterpVar(RooStats::HistFactory::FlexibleInterpVar* interp, const TString& filter) {
  FlexibleInterpVarHelper::removeConstituents(interp, filter);
}


//__________________________________________________________________________________|___________

class RooDataSetHelper : public ::RooDataSet {
  public:
  static void printInfo(RooDataSet* _ds) {
    RooDataSetHelper* ds = (RooDataSetHelper*) _ds;
    if (!ds) return;
    for(auto* arg:ds->_varsNoWgt){
      std::cout<<arg->GetName()<<", type: "<<arg->IsA()->GetName()<<std::endl;
      arg->Print();
    }
    ds->store()->Print();
  }
};

class RooAbsDataHelper : public ::RooAbsData {
  public:
  static const RooArgSet& getVars(const RooAbsData* _ds){
    const RooAbsDataHelper* ds = (const RooAbsDataHelper*) _ds;
    if (!ds) throw std::runtime_error("unable to obtain dataset!");
    return ds->_vars;
  }
};

void TSUtils::printInfo(RooDataSet* _ds) {
  RooDataSetHelper::printInfo(_ds);
}

const RooArgSet& TSUtils::getVariables(const RooAbsData* _ds) {
  return RooAbsDataHelper::getVars(_ds);
}


//__________________________________________________________________________________|___________

class RooDataHistHelper : public ::RooDataHist {
  public:
  static void printBins(RooDataHist* _dh) {
    RooDataHistHelper* dh = (RooDataHistHelper*) _dh;
    if (!dh) return;
    std::cout<<"DH '"<<dh->GetName()<<"':"<<std::endl;
    for (Int_t i = 0; i<dh->_arrSize; ++i) {
      std::cout<<"  bin "<<i<<": "<< dh->_wgt[i] <<" / errLo = "<< dh->_errLo[i] <<" / errHi = "<< dh->_errHi[i] <<" / sumw2 = "<< dh->_sumw2[i] <<" / binv = "<< dh->_binv[i]<<std::endl;
    }
  }
  static void scaleHist(RooDataHist* _dh, double scale) {
    RooDataHistHelper* dh = (RooDataHistHelper*) _dh;
    if (!dh) return;
    for (Int_t i = 0; i<dh->_arrSize; ++i) {
      dh->_wgt[i] *= scale;
      //dh->_errLo[i] // does not seem to be relevant
      //dh->_errHi[i] // does not seem to be relevant
      dh->_sumw2[i] *= scale*scale; //quadratic scaling
      //invalidate cache
      //dh->_curIndex = -1;
      //dh->_cache_sum_valid = false;
    }
  }
  static void scaleDifferenceToNominal(RooDataHist* _var, const RooDataHist* _nom, double scale) {
    if (!_var || !_nom) return;

    RooDataHistHelper* var = (RooDataHistHelper*) _var;
    const RooDataHistHelper* nom = (const RooDataHistHelper*) _nom;
    if (var->_arrSize != nom->_arrSize) {
      std::cout<<"Inconsistent array size between variation and nominal DataHist found, will not modify them!"<<std::endl;
    }
    for (Int_t i = 0; i<nom->_arrSize; ++i) {
      double newWeight = nom->_wgt[i] + scale * (var->_wgt[i] - nom->_wgt[i]);
      double ratio = var->_wgt[i]!= 0 ? newWeight / var->_wgt[i] : std::numeric_limits<double>::quiet_NaN();
      var->_wgt[i] = newWeight;
      //dh->_errLo[i] // does not seem to be relevant
      //dh->_errHi[i] // does not seem to be relevant
      var->_sumw2[i] *= ratio==ratio ? pow(ratio,2) : 1.; //quadratic scaling, assuming the reduction is flat accros individual weights (most likely irrelavant anyways)
      //invalidate cache
      //dh->_curIndex = -1;
      //dh->_cache_sum_valid = false;
    }

  }
};

void TSUtils::printBins(RooDataHist* _dh) {
  RooDataHistHelper::printBins(_dh);
}
void TSUtils::scaleHist(RooDataHist* _dh, double scale) {
  RooDataHistHelper::scaleHist(_dh,scale);
}
void TSUtils::scaleDifferenceToNominal(RooDataHist* _var, const RooDataHist* _nom, double scale) {
  RooDataHistHelper::scaleDifferenceToNominal(_var, _nom, scale);
}

//__________________________________________________________________________________|___________

class RooSimultaneousHelper : public ::RooSimultaneous {
  public:
  static std::vector<const RooAbsArg*>* getConstituents(const RooSimultaneous* sim) {
    if (!sim) return nullptr;
    std::vector<const RooAbsArg*>* retVec = new std::vector<const RooAbsArg*>();
    for (TObject *obj : ((const RooSimultaneousHelper*)sim)->_pdfProxyList) {
      RooRealProxy* prox = dynamic_cast<RooRealProxy*>(obj);
      if (!prox) continue;

      const RooAbsArg* p =  &(prox->arg());
      if (!p) continue;

      retVec->push_back(p);
    }
    return retVec;
  }
  static void removeConstituents(RooSimultaneous* sim, const TString& filter) {
    std::vector<RooRealProxy*> parts;
    RooSimultaneousHelper* sh = (RooSimultaneousHelper*) sim;
    for (TObject *obj : sh->_pdfProxyList) {
      RooRealProxy* prox = dynamic_cast<RooRealProxy*>(obj);
      if (!prox) continue;
      if (!TQStringUtils::matchesFilter(prox->arg().GetName(),filter,",")) continue;
      parts.push_back(prox);
    }
    for (RooRealProxy* const& part: parts) {
      sh->_pdfProxyList.Remove(part);
    }
  }
};

//std::vector<const RooAbsArg*>* TSUtils::getConstituents(const RooSimultaneous* sim) {
//  return RooSimultaneousHelper::getConstituents(sim);
//}

void TSUtils::removeConstituentsFromRooSimultaneous(RooSimultaneous* sim, const TString& filter) {
  RooSimultaneousHelper::removeConstituents(sim,filter);
}
//__________________________________________________________________________________|___________

class RooHistFuncHelper : public RooHistFunc {
  public:
  static RooDataHist* getDataHist(const RooHistFunc* h) {
    if (!h) return nullptr;
    return ((const RooHistFuncHelper*)h)->_dataHist;
  }
};

RooDataHist* TSUtils::getDataHist(const RooHistFunc* h) {
  return RooHistFuncHelper::getDataHist(h);
}

//__________________________________________________________________________________|___________

class RooRealSumPdfHelper : public RooRealSumPdf {
  public:
  static void removeConstituents(RooRealSumPdf* pdf, const TString& filter) {
    if (!pdf) return;
    std::vector<RooAbsArg*> parts;
    RooRealSumPdfHelper* helper = (RooRealSumPdfHelper*) pdf;
    ROOFIT_ITERATE(helper->_funcList,auto,arg){
      if (!arg) continue;
      if (!TQStringUtils::matchesFilter(arg->GetName(),filter,",")) continue;
      parts.push_back(arg);
    }

    for (RooAbsArg* const& part: parts) {
      helper->_funcList.RecursiveRemove(part);
    }
  }

};

void TSUtils::removeConstituentsFromRooRealSumPdf(RooRealSumPdf* pdf, const TString& filter) {
  RooRealSumPdfHelper::removeConstituents(pdf,filter);
}

//__________________________________________________________________________________|___________

namespace {
  void removeConstituents(RooProdPdf* pdf, const TString& filter) {
    if (!pdf) return;
    std::vector<RooAbsArg*> parts;
    for(auto* arg:(*pdf).*RooProdPdfHackResult<RooProdPdf_pdfList>::ptr){
      if (!arg) continue;
      if (!TQStringUtils::matchesFilter(arg->GetName(),filter,",")) continue;
      parts.push_back(arg);
    }
    
    for (RooAbsArg* const& part: parts) {
      int index = ((*pdf).*RooProdPdfHackResult<RooProdPdf_pdfList>::ptr).index(part);
      if (((*pdf).*RooProdPdfHackResult<RooProdPdf_extendedIndex>::ptr) == index) { //if this element was the "extendible" sub-component we need to invalidate this index to prevent segfaults
        //std::cout<<"Modifying extendedIndex"<<std::endl;
        (((*pdf).*RooProdPdfHackResult<RooProdPdf_extendedIndex>::ptr)) = -1;
      } else if (((*pdf).*RooProdPdfHackResult<RooProdPdf_extendedIndex>::ptr) > index) {//reduce the index by 1 if we remove an element which is at a lower position
        --((*pdf).*RooProdPdfHackResult<RooProdPdf_extendedIndex>::ptr);
        //std::cout<<"ExtendedIndex="<<helper->_extendedIndex<<", listIndex="<<helper->_pdfList.index(part)<<std::endl;
      }
      ((*pdf).*RooProdPdfHackResult<RooProdPdf_pdfList>::ptr).RecursiveRemove(part);
    }
  }
  
}

void TSUtils::removeConstituentsFromRooProdPdf(RooProdPdf* pdf, const TString& filter) {
  ::removeConstituents(pdf,filter);
}

//__________________________________________________________________________________|___________

class RooProductHelper : public RooProduct {
  public:
  static void removeConstituents(RooProduct* prod, const TString& filter) {
    if (!prod) return;
    std::vector<RooAbsArg*> parts;
    RooProductHelper* helper = (RooProductHelper*) prod;
    for(auto arg:helper->_compRSet){
      if (!arg) continue;
      if (!TQStringUtils::matchesFilter(arg->GetName(),filter,",")) continue;
      parts.push_back(arg);
    }
    for (RooAbsArg* const& part: parts) {
      helper->_compRSet.RecursiveRemove(part);
    }
    
    for(auto* arg: helper->_compCSet){
      if (!arg) continue;
      if (!TQStringUtils::matchesFilter(arg->GetName(),filter,",")) continue;
      parts.push_back(arg);
    }
    for (auto* part: parts) {
      helper->_compCSet.RecursiveRemove(part);
    }
    
  }

};

void TSUtils::removeConstituentsFromRooProduct(RooProduct* prod, const TString& filter) {
  RooProductHelper::removeConstituents(prod,filter);
}





//__________________________________________________________________________________|___________

namespace {
  void info(const TString& message) {
    std::cout << "SFramework/TSUtils: " << message.Data() << std::endl;
  }
  void error(const TString& message) {
    info(TQStringUtils::makeBoldRed(TString("ERROR: ") + message));
  }
  void warn(const TString& message) {
    info(TQStringUtils::makeBoldYellow(TString("WARNING: ") + message));
  }

}

//__________________________________________________________________________________|___________


TQFolder * TSUtils::convertParameterList(const RooAbsCollection * list, const TString& filter) {
  // convert a parameter list into a TQFolder
  if (!list) {
    return NULL;
  }

  TQFolder * result_list = TQFolder::newFolder("parameterList");

  convertParameterList(list,result_list,filter);

  return result_list;
}

//__________________________________________________________________________________|___________

void TSUtils::removeConstantParameters(RooAbsCollection& set){
  RooArgSet constSet;
  ROOFIT_ITERATE(set,RooAbsArg,myarg){
    RooRealVar* var = dynamic_cast<RooRealVar*>(myarg);
    if(!var) continue;
    if(var->isConstant()) constSet.add(*var);
  }
  set.remove(constSet);
}

//__________________________________________________________________________________|___________

void TSUtils::removeFloatingParameters(RooAbsCollection& set){
  RooArgSet floatSet;
  ROOFIT_ITERATE(set,RooAbsArg,myarg){
    RooRealVar* var = dynamic_cast<RooRealVar*>(myarg);
    if(!var) continue;  
    if(!var->isConstant()) floatSet.add(*myarg);
  }
  set.remove(floatSet);
}

//__________________________________________________________________________________|___________

int TSUtils::convertParameterList(const RooAbsCollection * list, TQFolder* result_list, const TString& filter) {
  int n = 0;

  // iterate of parameters in list
  ROOFIT_ITERATE(*list,RooAbsArg,arg){
    RooRealVar* var = dynamic_cast<RooRealVar*>(arg);
    if(!var) continue;
    
    if(!TQStringUtils::matchesFilter(var->GetName(),filter)) continue;

    TString name = TQFolder::makeValidIdentifier(var->GetName());
    TQFolder * result_arg = result_list->getFolder(name + "+");
    n++;

    // value
    result_arg->setTagDouble("val", var->getVal());

    // std::cout << var->GetName() << " = " << var->getVal() << " + " << var->getAsymErrorHi() << " - " << var->getAsymErrorLo() << std::endl;

    // errors
    if (var->hasError() && !var->hasAsymError()) {
      result_arg->setTagDouble("err", var->getError());
    } else if (var->hasAsymError()) {
      result_arg->setTagDouble("errLow", var->getAsymErrorLo());
      result_arg->setTagDouble("errHigh", var->getAsymErrorHi());
    }

    // is constant?
    result_arg->setTagBool("const", var->isConstant());

    // fit limits
    if (var->hasMin()) {
      result_arg->setTagDouble("min", var->getMin());
    }
    if (var->hasMax()) {
      result_arg->setTagDouble("max", var->getMax());
    }

    // title (if different from name)
    TString title = var->GetTitle();
    if (name.CompareTo(title) != 0) {
      result_arg->setTagString("title", var->GetTitle());
    }
  }
  return n;
}

//__________________________________________________________________________________|___________

RooArgList* TSUtils::convertParameterList(TQFolder* folder, RooAbsCollection * params) {
  if(!folder) return NULL;
  TQFolderIterator itr(folder->getListOfFolders("?"),true);
  RooArgList* retval = new RooArgList();
  while(itr.hasNext()){
    TQFolder* f = itr.readNext();
    if(!f) continue;
    RooRealVar* var = params ? dynamic_cast<RooRealVar*>(params->find(f->GetName())) : new RooRealVar(f->GetName(),f->GetName(),f->getTagDoubleDefault("val",0.));
    if(!var) continue;
    double max;
    if(f->getTagDouble("max",max)){
      var->setMax(max);
    }
    double min;
    if(f->getTagDouble("min",min)){
      var->setMin(min);
    }
    double val;
    if(f->getTagDouble("val",val)){
      var->setVal(val);
    }
    //    std::cout<<TString::Format("Setting parameter '%s' to %s",var->GetName(), f->getTagBoolDefault("const",false)? "constant" : "floating").Data()<<std::endl;
    var->setConstant(f->getTagBoolDefault("const",false));
    double err,errLow,errHigh;
    if(f->getTagDouble("errLow",errLow) && f->getTagDouble("errHigh",errHigh)){
      var->setError(0.5*(fabs(errLow)+fabs(errHigh)));      
      var->setAsymError(errLow,errHigh);
    } else if(f->getTagDouble("err",err)){
      var->setError(err);
    }
    retval->add(*var);
  }
  retval->sort();
  return retval;
}

//__________________________________________________________________________________|___________

namespace {
  TH2* makeHist(const TMatrixDSym* mat, const std::vector<TString>& names, const RooAbsCollection& parameters, const char* name, bool normalize){
    std::vector<RooRealVar*> params;
    std::map<TString,int> indices;
    ROOFIT_ITERATE(parameters,RooAbsArg,arg){
      RooRealVar* v = dynamic_cast<RooRealVar*>(arg);    
      TString name(v->GetName());
      int index = -1;
      for(size_t i=0; i<names.size(); ++i){
        if(names[i] == name) index = i;
      }
      if(index<0) continue;
      params.push_back(v);
      indices[name] = index;
    }

    int n = params.size();
    TH2D* hh = new TH2D(name,name,n,0,n,n,0,n) ;
    hh->SetDirectory(NULL);
    double min = 0;
    double max = 0;
    for (Int_t i = 0 ; i<n ; i++) {
      int ii = indices.at(params[i]->GetName());
      for (Int_t j = 0 ; j<n; j++) {
        int ij = indices.at(params[j]->GetName());
        double val = (*mat)(ii,ij);
        double vii = (*mat)(ii,ii);
        double vij = (*mat)(ij,ij);
        min = std::min(min,val);
        max = std::max(max,val);
        if(normalize){
          hh->SetBinContent(i+1,n-j,val / sqrt(vii * vij));
        } else {
          hh->SetBinContent(i+1,n-j,val);
        }
      }
      hh->GetXaxis()->SetBinLabel(i+1,params[i]->GetName()) ;
      hh->GetYaxis()->SetBinLabel(n-i,params[i]->GetName()) ;
    }
    if(normalize){
      hh->SetMinimum(-1.) ;
      hh->SetMaximum(1.) ;
    } else {
      hh->SetMinimum(min) ;
      hh->SetMaximum(max) ;
    }

    return hh ;
  }

  TMatrixDSym reduce(const TMatrixDSym& mat){
    std::vector<int> keepRows;
    for(int i=0; i<mat.GetNcols(); ++i){
      if(fabs(mat(i,i)) > 1e-14){
        keepRows.push_back(i);
      }
    }
    TMatrixDSym reduced(keepRows.size());
    for(size_t i=0; i<keepRows.size(); ++i){
      for(size_t j=0; j<keepRows.size(); ++j){
        reduced(i,j) = mat(keepRows[i],keepRows[j]);
      }
    }

    return reduced;
  }
}
//__________________________________________________________________________________|___________

RooAbsPdf* TSUtils::stripConstraints(RooProdPdf* product, const RooArgSet& observables, RooArgSet& constraints){
  //! strip the constraints from a product pdf
  RooAbsPdf* pdf = NULL;
  RooArgSet components(*product->getComponents());
  for(auto comp:components){
    if(!comp->InheritsFrom(RooAbsPdf::Class())) continue;
    RooAbsPdf* subpdf = NULL;
    if(comp == product) continue;
    if(comp->InheritsFrom(RooProdPdf::Class())){
      subpdf = stripConstraints((RooProdPdf*)comp,observables,constraints);
    } else if(comp->dependsOn(observables)){
      subpdf = (RooAbsPdf*)comp;
    } else {
      constraints.add(*comp);
    }
    if(subpdf){
      if(!pdf) pdf = subpdf;
      else {
        throw std::runtime_error("found several non-constraint like pdfs in a single product!");
      }
    }
  }
  return pdf;
}

//__________________________________________________________________________________|___________


TMatrixDSym TSUtils::retrieveCovariances(RooArgList* parameters, const RooFitResult* fitResult){
  return fitResult->reducedCovarianceMatrix(*parameters);
}

//__________________________________________________________________________________|___________

bool TSUtils::checkCovarianceHist(TH2* hCovariance, const RooArgSet& parameters, const RooFitResult* fitResult, TQTaggable* options){
  // some checks
  if(hCovariance->GetNbinsX() != hCovariance->GetNbinsY()){
    throw std::runtime_error("internal consistency check failed, covariance matrix is not square!");
  }
  bool ok = true;
  for(size_t i=0; i<(unsigned) hCovariance->GetNbinsX(); ++i){
    TString xlabel(hCovariance->GetXaxis()->GetBinLabel(i+1));
    int j = hCovariance->GetYaxis()->GetNbins()-i-1;
    TString ylabel(hCovariance->GetYaxis()->GetBinLabel(j+1));
    if(xlabel != ylabel) throw std::runtime_error(TString::Format("internal consistency check failed, labeling is inconsistent: %lu='%s' vs. %d='%s'!",i,xlabel.Data(),j,ylabel.Data()).Data());
    RooRealVar* par = dynamic_cast<RooRealVar*>(parameters.find(xlabel));
    if(!par) throw std::runtime_error("internal consistency check failed, parameter listed in covariance matrix not found in fit result!");
    double err = par->getError();
    double cov = hCovariance->GetBinContent(i+1,j+1);
    if(options && options->getTagBoolDefault("runHesse",false) && fitResult && fitResult->covQual() > 2){
      if(!TMath::AreEqualRel(cov,err*err,0.025)){
        warn(TString::Format("internal consistency check failed, error on parameter %lu %s=%.3f+/-%.3f does not agree with entry in covariance matrix %.3f (sqrt = %.3f)!",
                             i,par->GetName(),par->getVal(),err,cov,sqrt(cov)).Data());
        ok = false;
      }
    }
  }
  
  return ok;
}

//__________________________________________________________________________________|___________

bool TSUtils::checkCovarianceMatrix(const RooFitResult* fitResult, double relThreshold){
  // some checks
  TMatrixDSym covMat(*TSUtils::getCovarianceMatrix(fitResult));
  TMatrixDSym corrMat(*TSUtils::getCorrelationMatrix(fitResult));

  bool ok = true;
  int n = covMat.GetNrows();
  for(int i=0; i<n; ++i){
    if( covMat(i,i) <= 0){
      throw std::runtime_error("internal error in correlation matrix!");
    }
    if( corrMat(i,i) <= 0){
      throw std::runtime_error("internal error in covariance matrix!");
    }
    
    RooRealVar* var = dynamic_cast<RooRealVar*>(fitResult->floatParsFinal().at(i));
    if(!var){
      throw std::runtime_error("internal inconsistency detected, invalid parameter encountered!");
    }
    double err = var->getError();
    double errHi = var->getErrorHi();
    double errLo = var->getErrorLo();
    double cov = covMat(i,i);
    if(!TMath::AreEqualRel(cov,err*err,relThreshold) && !TMath::AreEqualRel(cov,errHi*errHi,relThreshold) && !TMath::AreEqualRel(cov,errLo*errLo,relThreshold)){
      ::warn(TString::Format("internal consistency check failed for parameter %d '%s': pow(err,2)=%g, pow(errHi,2)=%g, pow(errLo,2)=%g,  cov(i,i)=%g!",i,var->GetName(),err*err,errHi*errHi,errLo*errLo,cov).Data());
      ok = false;
    }
  }

  double minVar = 1;
  double maxVar = 1;
  for(int i=0; i<n; ++i){
    minVar = std::min(minVar,covMat(i,i));
    maxVar = std::max(maxVar,covMat(i,i));
    for(int j=0; j<n; ++j){
      double cov = covMat(i,j);
      double vari = covMat(i,i);
      double varj = covMat(j,j);
      double corrval = cov / sqrt(vari * varj);
      double corr = corrMat(i,j);
      if(!TQHistogramUtils::areEqualRel(corrval,corr,relThreshold) && !(fabs(corrval) + fabs(corr) < 1e-6)){
        ::warn(TString::Format("correlation embedded in covariance matrix does not match correlation matrix values for parameters '%s' and '%s': corr(i,j)=%g, but cov(i,j)=%g => corr(i,j)=%g with var(i)=%g and var(j)=%g!",
                               fitResult->floatParsFinal().at(i)->GetName(),
                               fitResult->floatParsFinal().at(j)->GetName(),                               
                               corr,cov,corrval,vari,varj).Data());
        ok = false;
      }
    }
  }
  if(minVar == maxVar){
    ::warn("covariance matrix is identical to correlation matrix, all variances are unity - are you sure your fit result is correct?");
    ok = false;
  }
  return ok;
}

//__________________________________________________________________________________|___________

TQFolder * TSUtils::convertFitResults(RooFitResult * fitResult, TQTaggable* options, ROOT::Fit::FitConfig* fitConfig) {
  // convert a RooFitResult into a TQFolder
  if (!fitResult) {
    return NULL;
  }

  TString name = TQFolder::makeValidIdentifier(fitResult->GetName());
  TQFolder * result = TQFolder::newFolder(name);

  // set title if different from name
  if (name.CompareTo(fitResult->GetTitle()) != 0) {
    result->setTagString("title", fitResult->GetTitle());
  }

  // minimized -log(L) value
  result->setTagDouble("minNll", fitResult->minNll());
  // estimated distance to minimum
  result->setTagDouble("edm", fitResult->edm());
  // status
  result->setTagInteger("status", fitResult->status());
  for (UInt_t i = 0; i < fitResult->numStatusHistory(); i++) {
    result->setTagInteger(TString::Format("status.%s", fitResult->statusLabelHistory(i)),
                          fitResult->statusCodeHistory(i));
  }
  // MINUIT quality code of covariance matrix
  result->setTagInteger("covQual", fitResult->covQual()); // for meanings of these codes, see https://root.cern.ch/root/html/ROOT__Minuit2__Minuit2Minimizer.html#ROOT__Minuit2__Minuit2Minimizer:CovMatrixStatus
  // number of NLL evaluations with problems
  result->setTagInteger("numInvalidNLL", fitResult->numInvalidNLL());

  // parameters
  TQFolder* constPars = convertParameterList(&fitResult->constPars());
  TQFolder* floatParsInit = convertParameterList(&fitResult->floatParsInit());
  TQFolder* floatParsFinal = convertParameterList(&fitResult->floatParsFinal());

  int floatPars = floatParsFinal->getNElements(false,TQFolder::Class());

  std::vector<TString> paramNames;
  if(fitConfig){
    for(auto p:fitConfig->ParamsSettings()){
      paramNames.push_back(p.Name());
    }
  } else {
    TQFolderIterator itr(floatParsFinal->getListOfFolders("?"),true);
    while(itr.hasNext()){
      TQFolder* f = itr.readNext();
      paramNames.push_back(f->GetName());
    }
  }

  result->addObject(constPars,"::constPars");
  result->addObject(floatParsInit,"::floatParsInit");
  result->addObject(floatParsFinal,"::floatParsFinal");

  if(fitResult->covQual() > 0){
    Double_t determ = 0;
    // these use a hack to access the fitResults internal member. We need this to check if this member isn't a nullptr as RooFit doesn't check this in some calls...
    const TMatrixDSym* covMatptr = TSUtils::getCovarianceMatrix(fitResult);
    const TMatrixDSym* corMatptr = TSUtils::getCorrelationMatrix(fitResult);
    if(corMatptr && covMatptr && covMatptr->GetNcols()>1 && corMatptr->GetNcols()>1){
      TMatrixDSym covMat(::reduce(*covMatptr));
      TMatrixDSym corMat(::reduce(*corMatptr));

      TH2* hCovariance = ::makeHist(covMatptr,paramNames,fitResult->floatParsFinal(),"covariance",false);
      if (hCovariance) {
        result->addObject(hCovariance);
      }

      checkCovarianceHist(hCovariance,fitResult->floatParsFinal(),fitResult,options);

      TH2* hCorrelation = ::makeHist(corMatptr,paramNames,fitResult->floatParsFinal(),"correlation",true);
      if (hCorrelation) {
        result->addObject(hCorrelation);
      }

      if(hCovariance->GetNbinsX()  != floatPars) throw std::runtime_error(TString::Format( "covariance matrix size %d inconsistent with float parameter list length %d!",hCovariance->GetNbinsX(),floatPars).Data());
      if(hCorrelation->GetNbinsX() != floatPars) throw std::runtime_error(TString::Format("correlation matrix size %d inconsistent with float parameter list length %d!",hCorrelation->GetNbinsX(),floatPars).Data());

      TMatrixDSym G = covMat.Invert(&determ);
      result->setTagDouble("hesse.determinant",determ);
      TH2* hist = TQHistogramUtils::convertMatrixToHistogram(&G,"hesse");
      if(hist){
        int i = 1;
	ROOFIT_ITERATE(fitResult->floatParsFinal(),RooAbsArg,arg){
	  RooRealVar* var = dynamic_cast<RooRealVar*>(arg);    
          if(!var) continue;
          const TString name(var->GetName());
          hist          ->GetXaxis()->SetBinLabel(i,name);
          hist          ->GetYaxis()->SetBinLabel(i,name);
          i++;
        }
        if(!result->addObject(hist)){
          ERRORfunc("unable to add histogram to folder");
        }
      } else {
        ERRORfunc("histogram conversion of hesse matrix failed!");
      }
    }
  }

  return result;
}

namespace {
  struct MyFitResult : public RooFitResult {
    MyFitResult(const RooFitResult* other) : RooFitResult(*other) {}
    MyFitResult(const RooFitResult& other) : RooFitResult(other) {}
    MyFitResult(RooAbsCollection* paramList) :
      RooFitResult("prefitResult","prefitResult")
    {
      RooArgList constPars("constPars");
      RooArgList floatPars("floatPars");
      
      for(auto* obj:*paramList){
        RooRealVar* arg = dynamic_cast<RooRealVar*>(obj);
        if(!arg) continue;
        if (arg->isConstant()) {
          constPars.addClone(*arg);
        } else {
          if(arg->getError() == 0) arg->setError(1);
          floatPars.addClone(*arg);
        }
      }

      TMatrixDSym mat(floatPars.getSize());
      for(int i=0; i<floatPars.getSize(); ++i){
        mat(i,i) = 1;
      }

      this->setConstParList(constPars);
      this->setInitParList(floatPars);
      this->setFinalParList(floatPars);
      this->setMinNLL(0);
      this->setEDM(0);
      this->setCovQual(0);
      this->setStatus(0);

      this->_CM = new TMatrixDSym(mat);

      int i = 0;
      for(auto obj:floatPars){
        RooRealVar* roorealVar = dynamic_cast<RooRealVar*>(obj);
        double err = roorealVar->getError();
        if(err > 0){
          mat(i,i) = mat(i,i) * err * err;
        }
        i++;
      }

      this->_VM = new TMatrixDSym(mat);
    }


    MyFitResult(TQFolder* fitResult, RooAbsCollection* params) :
      RooFitResult(fitResult->GetName(),fitResult->GetTitle())
    {
      // minimized -log(L) value
      this->setMinNLL(fitResult->getTagDoubleDefault("minNll",nan));
      // estimated distance to minimum
      this->setEDM(fitResult->getTagDoubleDefault("edm",nan));
      // status
      this->setStatus(fitResult->getTagIntegerDefault("status",-1));
      // MINUIT quality code of covariance matrix
      this->setCovQual(fitResult->getTagIntegerDefault("covQual",0));

      RooArgList* floatParsInit  = TSUtils::convertParameterList(fitResult->getFolder("floatParsInit"),params);
      RooArgList* floatParsFinal = TSUtils::convertParameterList(fitResult->getFolder("floatParsFinal"),params);
      RooArgList* constPars      = TSUtils::convertParameterList(fitResult->getFolder("constPars"),     params);

      if(floatParsInit && floatParsFinal &&floatParsInit->getSize() != floatParsFinal->getSize()){
        throw std::runtime_error("found inconsistent number of parameters before and after fit while constructing fit result");
      }

      if(floatParsInit) floatParsInit->sort();
      if(floatParsFinal)floatParsFinal->sort();
      if(constPars) constPars->sort();

      std::vector<TString> names;
      TSUtils::getParameterNames(floatParsFinal,names);

      if(floatParsInit)  this->setInitParList (*floatParsInit);
      if(floatParsFinal) this->setFinalParList(*floatParsFinal);
      if(constPars)      this->setConstParList(*constPars);

      const double checkThreshold = 1e-2;      
      const double relThreshold = 1e-4;
      const double absThreshold = 1e-6;

      this->_VM = TQHistogramUtils::convertHistogramToSymMatrix((TH2*)fitResult->getObject("covariance"), names,relThreshold,absThreshold);
      this->_CM = TQHistogramUtils::convertHistogramToSymMatrix((TH2*)fitResult->getObject("correlation"),names,relThreshold,absThreshold);

      // sanity checks      
      if(!this->_CM){
        throw std::runtime_error("unable to obtain correlation matrix!");
      }
      if(!this->_VM){
        throw std::runtime_error("unable to obtain covariance matrix!");
      }      
      if((int)this->_CM->GetNcols() != (int)this->_VM->GetNcols()){
        throw std::runtime_error("correlation and covariance matrices have different size!");
      }
      if((int)this->_CM->GetNcols() != (int)names.size()){
        throw std::runtime_error("matrix dimensions doesn't match number of floating parameters!");
      }

      if(TSUtils::checkCovarianceMatrix(this,checkThreshold)){
        warn("covariance matrix invalid, recovering from correlation matrix!");
        for(size_t i=0; i<names.size(); ++i){
          for(size_t j=0; j<names.size(); ++j){
            RooRealVar* par = (RooRealVar*)(floatParsFinal->find(names[i]));
            (*this->_VM)(i,j) = par->getError()*par->getError()*(*this->_CM)(i,j);
          }
        }
      }
      
    }
    virtual ~MyFitResult(){};

    ////////////////////////////////////////////////////////////////////////////////
    /// Return a p.d.f that represents the fit result as a multi-variate probability densisty
    /// function on the floating fit parameters, including correlations

    RooAbsPdf* robustCreateHessePdf(const RooAbsCollection* params) const {
      TMatrixDSym V(covarianceMatrix()) ;

      int check = gMatrixCheck;
      gMatrixCheck = 0;
      
      TDecompLU lu(V);
      Double_t d1,d2;
      lu.Det(d1,d2);
      double det = d1*TMath::Power(2.,d2);
      int nOffDiag = 0;
      for(int i=0; i<V.GetNcols(); ++i){
        for(int j=0; j<V.GetNcols(); ++j){
          if(i==j) continue;
          if(V(i,j)!=0.) nOffDiag++;
        }
      }

      if(det<=0){
        std::stringstream ss;
        ss << TString::Format("cannot create hessian Pdf, covariance matrix is not pos. def., determinant is %g (d1=%g, d2=%g), condition is %g, tolerance is %g!",det,d1,d2,lu.Condition(),lu.GetTol()) << "\n";
        for(int i=0; i<V.GetNcols(); ++i){
          if(!(V(i,i)>0)){
            ss << TString::Format("  entry (%d,%d) = %g!",i,i,V(i,i)) << "\n";
          }
          for(int j=0; j<V.GetNcols(); ++j){
            if(i==j) continue;
            if(V(i,j)!=0.) nOffDiag++;
            if(V(i,i) <= V(i,j)){
              ss << TString::Format("  entry (%d,%d) = %g is greather than corresponding diagonal entry (%d,%d) = %g!",i,j,V(i,j),i,i,V(i,i)) << "\n";
            }
          }
        }
        ss << TString::Format("  total number of off-diagonal entries is %d!",nOffDiag) << "\n";
        if(nOffDiag>0){
          throw std::runtime_error(ss.str());
        }
      }

      // Make sure that all given params were floating parameters in the represented fit
      RooArgList params2 ;
      for(RooAbsArg* arg:*params){
        if (_finalPars->find(arg->GetName())) {
          params2.add(*arg) ;
        } else {
          std::stringstream ss;
          ss  << "RooFitResult::createHessePdf(" << GetName() << ") WARNING input variable "
              << arg->GetName() << " was not a floating parameters in fit result and is ignored" << std::endl ;
          warn(ss.str());
        }
      }
      
      // Need to order params in vector in same order as in covariance matrix
      RooArgList params3 ;
      for(auto* obj:*_finalPars){
        RooAbsReal* arg = dynamic_cast<RooAbsReal*>(obj);
        if (params2.find(arg->GetName())) {
          params3.add(*arg) ;
        }
      }


      // Handle special case of representing full covariance matrix here
      if (params3.getSize()==_finalPars->getSize()) {

        RooArgList mu ;
        for (Int_t i=0 ; i<_finalPars->getSize() ; i++) {
          RooRealVar* parclone = (RooRealVar*) _finalPars->at(i)->Clone(Form("%s_centralvalue",_finalPars->at(i)->GetName())) ;
          parclone->setConstant(kTRUE) ;
          mu.add(*parclone) ;
        }

        std::string name  = Form("pdf_%s",GetName()) ;
        std::string title = Form("P.d.f of %s",GetTitle()) ;

        // Create p.d.f.
        RooAbsPdf* mvg = new RooMultiVarGaussian(name.c_str(),title.c_str(),params3,mu,V) ;
        mvg->addOwnedComponents(mu) ;
        return  mvg ;
      }

      //                                       -> ->
      // Handle case of conditional p.d.f. MVG(p1|p2) here

      // Find (subset) of parameters that are stored in the covariance matrix
      std::vector<int> map1, map2 ;
      for (int i=0 ; i<_finalPars->getSize() ; i++) {
        if (params3.find(_finalPars->at(i)->GetName())) {
          map1.push_back(i) ;
        } else {
          map2.push_back(i) ;
        }
      }

      // Calculate offset vectors mu1 and mu2
      RooArgList mu1 ;
      for (UInt_t i=0 ; i<map1.size() ; i++) {
        RooRealVar* parclone = (RooRealVar*) _finalPars->at(map1[i])->Clone(Form("%s_centralvalue",_finalPars->at(map1[i])->GetName())) ;
        parclone->setConstant(kTRUE) ;
        mu1.add(*parclone) ;
      }

      TMatrixDSym Vred;
      if(nOffDiag>0){
        // Rearrange matrix in block form with 'params' first and 'others' last
        // (preserving relative order)
        TMatrixDSym S11, S22 ;
        TMatrixD S12, S21 ;
        DEBUG("block-decomposing");
        RooMultiVarGaussian::blockDecompose(V,map1,map2,S11,S12,S21,S22) ;

        // Constructed conditional matrix form         -1
        // F(X1|X2) --> CovI --> S22bar = S11 - S12 S22  S21

        DEBUG("decomposing eigenvalues");        
        // Do eigenvalue decomposition
        TMatrixD S22Inv(TMatrixD::kInverted,S22) ;
        TMatrixD S22bar =  S11 - S12 * (S22Inv * S21) ;

        DEBUG("converting to symmetric form");                
        // Convert explicitly to symmetric form
        Vred.ResizeTo(S22bar.GetNcols(),S22bar.GetNcols()) ;
        for (int i=0 ; i<Vred.GetNcols() ; i++) {
          for (int j=i ; j<Vred.GetNcols() ; j++) {
            Vred(i,j) = (S22bar(i,j) + S22bar(j,i))/2 ;
            Vred(j,i) = Vred(i,j) ;
          }
        }
      } else {
        Vred.ResizeTo(params3.getSize(),params3.getSize());
        for (int i=0 ; i<Vred.GetNcols() ; i++) {
          int j = map1.at(i);
          Vred(i,i) = V(j,j);
        }
      }
      std::string name  = Form("pdf_%s",GetName()) ;
      std::string title = Form("P.d.f of %s",GetTitle()) ;

      // Create p.d.f.
      RooAbsPdf* ret =  new RooMultiVarGaussian(name.c_str(),title.c_str(),params3,mu1,Vred) ;
      ret->addOwnedComponents(mu1) ;
      gMatrixCheck = check;      
      return ret ;
    }
  };
}

//__________________________________________________________________________________|___________

template<class T> RooFitResult * TSUtils::convertFitResults(TQFolder* fitResult, const std::vector<T>& params) {
  RooArgList l;
  for(auto p:params) l.add(*p);
  return convertFitResults(fitResult,&l);
}
namespace TSUtils {
  template<>  RooFitResult * convertFitResults<RooAbsArg*> (TQFolder* fitResult, const std::vector<RooAbsArg*>&  params);
  template<>  RooFitResult * convertFitResults<RooRealVar*>(TQFolder* fitResult, const std::vector<RooRealVar*>& params);
  template<>  RooFitResult * convertFitResults<RooAbsPdf*> (TQFolder* fitResult, const std::vector<RooAbsPdf*>&  params);
}

//__________________________________________________________________________________|___________

RooFitResult * TSUtils::convertFitResults(TQFolder* fitResult, RooAbsCollection* params) {

  // convert a RooFitResult into a TQFolder
  if (!fitResult) {
    return NULL;
  }

  MyFitResult result(fitResult,params);
  RooFitResult* r = new RooFitResult(result);

  return r;
}

//__________________________________________________________________________________|___________

TQFolder* TSUtils::modifyFitResults(TQFolder* fitResults, TQFolder* changes){
  TQFolder* newResult = new TQFolder(fitResults->getName());
  newResult->importTags(fitResults);

  std::vector<TString> constParList = changes->getTagVString("constPars");

  TQFolder* oldfloatParsFinal = fitResults->getFolder("floatParsFinal");
  TQFolder* oldfloatParsInit  = fitResults->getFolder("floatParsInit");
  TQFolder* oldconstPars      = fitResults->getFolder("constPars");
  TQFolder* newfloatParsFinal = newResult->getFolder("floatParsFinal+");
  TQFolder* newfloatParsInit  = newResult->getFolder("floatParsInit+");
  TQFolder* newconstPars      = oldconstPars->copy();
  newResult->addFolder(newconstPars);

  std::vector<TString> removeBins;

  TQFolderIterator itr(oldfloatParsInit->getListOfFolders("?"),true);
  while(itr.hasNext()){
    TQFolder* par = itr.readNext();
    if(!par) continue;
    bool setConst = false;
    for(const auto& p:constParList){
      if(TQStringUtils::matches(par->getName(),p)){
        setConst = true;
      }
    }
    TQFolder* finalpar = oldfloatParsFinal->getFolder(par->getName());
    if(!finalpar) continue;
    if(setConst){
      TQFolder* copy = finalpar->copy();
      copy->setTagBool("const",true);
      newconstPars->addFolder(copy);
      removeBins.push_back(finalpar->GetName());
    } else {
      newfloatParsInit ->addFolder(par->copy());
      newfloatParsFinal->addFolder(finalpar->copy());
    }
  }

  TH2* corMat  = dynamic_cast<TH2*>(fitResults->getObject("correlation"));
  TH2* covMat  = dynamic_cast<TH2*>(fitResults->getObject("covariance"));
  TH2* hesse  = dynamic_cast<TH2*>(fitResults->getObject("hesse"));
  newResult->addObject(TQHistogramUtils::removeBins(corMat,removeBins));
  newResult->addObject(TQHistogramUtils::removeBins(covMat,removeBins));
  newResult->addObject(TQHistogramUtils::removeBins(hesse ,removeBins));

  return newResult;
}


//__________________________________________________________________________________|___________

TQFolder* TSUtils::applyFitResult(RooAbsCollection* vars, TQFolder* fitResults){
  TQFolder* newResult = new TQFolder(fitResults->getName());
  newResult->importTags(fitResults);

  TQFolder* oldfloatParsFinal = fitResults->getFolder("floatParsFinal");
  TQFolder* oldfloatParsInit  = fitResults->getFolder("floatParsInit");
  TQFolder* oldconstPars      = fitResults->getFolder("constPars");
  TQFolder* newfloatParsFinal = newResult->getFolder("floatParsFinal+");
  TQFolder* newfloatParsInit  = newResult->getFolder("floatParsInit+");
  TQFolder* newconstPars      = newResult->getFolder("constPars+");

  std::vector<TString> removeBins;
  TQFolderIterator float_itr(oldfloatParsFinal->getListOfFolders("?"),true);
  while(float_itr.hasNext()){
    TQFolder* p_float = float_itr.readNext();
    RooRealVar* v_float = dynamic_cast<RooRealVar*>(vars->find(p_float->GetName()));
    if(!v_float) {
      info(TString::Format("unable to find parameter '%s' in workspace!",p_float->GetName()));
      removeBins.push_back(p_float->GetName());
      continue;
    }
    v_float->setVal(p_float->getTagDoubleDefault("val",0.));
    double err;
    if(p_float->getTagDouble("err",err)) v_float->setError(err);
    double errLo=-1;  // will be set to sensible values later
    double errHi=-1;
    if(p_float->getTagDouble("errHigh",errHi) && p_float->getTagDouble("errLow",err)) v_float->setAsymError(errLo,errHi);
    v_float->setConstant(false);
    newfloatParsFinal->addFolder(p_float->copy());
   }
  TQFolderIterator floatInit_itr(oldfloatParsInit->getListOfFolders("?"),true);
  while(floatInit_itr.hasNext()){
    TQFolder* p_floatInit = floatInit_itr.readNext();
    RooRealVar* v_floatInit = dynamic_cast<RooRealVar*>(vars->find(p_floatInit->GetName()));
    if(!v_floatInit) {
      info(TString::Format("unable to find parameter '%s' in workspace!",p_floatInit->GetName()));
      removeBins.push_back(p_floatInit->GetName());
      continue;
    }
    v_floatInit->setVal(p_floatInit->getTagDoubleDefault("val",0.));
    double err;
    if(p_floatInit->getTagDouble("err",err)) v_floatInit->setError(err);
    double errLo=-1;  // will be set to sensible values later
    double errHi=-1;
    if(p_floatInit->getTagDouble("errHigh",errHi) && p_floatInit->getTagDouble("errLow",err)) v_floatInit->setAsymError(errLo,errHi);
    v_floatInit->setConstant(false);
    newfloatParsInit->addFolder(p_floatInit->copy());
   }
  TQFolderIterator const_itr(oldconstPars->getListOfFolders("?"),true);
  while(const_itr.hasNext()){
    TQFolder* p_const = const_itr.readNext();
    RooRealVar* v_const = dynamic_cast<RooRealVar*>(vars->find(p_const->GetName()));
    if(!v_const) {
      info(TString::Format("unable to find parameter '%s' in workspace!",p_const->GetName()));
      removeBins.push_back(p_const->GetName());
      continue;
    }
    v_const->setVal(p_const->getTagDoubleDefault("val",0.));
    double err;
    if(p_const->getTagDouble("err",err)) v_const->setError(err);
    double errLo=-1;  // will be set to sensible values later
    double errHi=-1;
    if(p_const->getTagDouble("errHigh",errHi) && p_const->getTagDouble("errLow",err)) v_const->setAsymError(errLo,errHi);
    v_const->setConstant(false);
    newconstPars->addFolder(p_const->copy());
   }
  TH2* corMat  = dynamic_cast<TH2*>(fitResults->getObject("correlation"));
  TH2* covMat  = dynamic_cast<TH2*>(fitResults->getObject("covariance"));
  TH2* hesse  = dynamic_cast<TH2*>(fitResults->getObject("hesse"));
  newResult->addObject(TQHistogramUtils::removeBins(corMat,removeBins));
  newResult->addObject(TQHistogramUtils::removeBins(covMat,removeBins));
  newResult->addObject(TQHistogramUtils::removeBins(hesse ,removeBins));

  return newResult;
}

//__________________________________________________________________________________|___________

RooFitResult * TSUtils::prefitResults(RooAbsCollection* params) {
  // create an empty RooFitResult
  MyFitResult result(params);
  return new RooFitResult(result);
}

//__________________________________________________________________________________|___________

RooAbsPdf * TSUtils::createHessePdf(const RooFitResult* fr, const RooAbsCollection* params) {
  // create an empty RooFitResult
  MyFitResult result(*fr);
  RooAbsPdf* hesse = result.robustCreateHessePdf(params);
  hesse->recursiveRedirectServers(fr->floatParsFinal(),false);
  return hesse;
}

//__________________________________________________________________________________|___________

const TMatrixDSym* TSUtils::getCovarianceMatrix(const RooFitResult* fitResult){
  // get a (const) pointer to the covariance matrix of a fit result
  return fitResult->*RooFitResultHackResult<RooFitResultVM>::ptr;
}

//__________________________________________________________________________________|___________

const TMatrixDSym* TSUtils::getCorrelationMatrix(const RooFitResult* fitResult){
  // get a (const) pointer to the covariance matrix of a fit result
  return fitResult->*RooFitResultHackResult<RooFitResultCM>::ptr;
}

//__________________________________________________________________________________|___________

void TSUtils::getPlotRange(RooAbsReal* rv, double& min, double& max, int& nbins){
  // return the range set for plotting in a RooAbsReal
  if(!rv) return;
  //the following lines are nothing but fancy ways to do what the comments above each line do. This is required in order to avoid a public-private hack (this variant should be way less compiler dependent or ideally compiler independent)
  //min = rv->_plotMin;
  min = (*rv).*RooAbsRealHackResult<RooAbsReal_plotMin>::ptr;
  //max = rv->_plotMin;
  max = (*rv).*RooAbsRealHackResult<RooAbsReal_plotMax>::ptr;

  //nbins = rv->_plotBins;
  nbins = (*rv).*RooAbsRealHackResult<RooAbsReal_plotBins>::ptr;
}

//__________________________________________________________________________________|___________

TQFolder* TSUtils::convertGraph(TGraph* g){
  // convert an instance of TGraph into an instance of TQFolder such that the TSStatisticsPlotter can handle it
  int i=0;
  TQFolder* retval = TQFolder::newFolder(g->GetName());
  double x,y;
  while(g->GetPoint(i,x,y) > 0){
    TQFolder* p = retval->getFolder(TString::Format("p.%d+",i));
    p->setTag("x",x);
    p->setTag("y",x);
    i++;
  }
  return retval;
}

//__________________________________________________________________________________|___________

TQFolder* TSUtils::makeGraphFolder(const char* name,const std::map<double,double>& values){
  // convert a map<double,double> into an instance of TQFolder such that the TSStatisticsPlotter can handle it
  int i=0;
  TQFolder* retval = TQFolder::newFolder(name);
  for(auto it:values){
    TQFolder* p = retval->getFolder(TString::Format("p.%d+",i));
    p->setTag("x",it.first);
    p->setTag("y",it.second);
    i++;
  }
  return retval;
}

//__________________________________________________________________________________|___________

void TSUtils::setParametersConstant(const RooAbsCollection* params, bool constVal){
  // set a list of parameters to const/non-const
  if(!params) return;
  ROOFIT_ITERATE(*params,TObject,arg){  
    RooRealVar * poi = dynamic_cast<RooRealVar*>(arg);
    if (poi) {
      std::cout<<TString::Format("Setting parameter '%s' to %s",poi->GetName(),constVal? "constant" : "floating" ).Data()<<std::endl;
      poi->setConstant(constVal);
    }
  }
}
//__________________________________________________________________________________|___________

int TSUtils::countConstParameters(const RooAbsCollection& params){
  return countConstParameters(&params);
}

//__________________________________________________________________________________|___________

int TSUtils::countConstParameters(const RooAbsCollection* params){
  // count how many parameters are constant
  if(!params) return -1;
  int n = 0;
  ROOFIT_ITERATE(*params,RooAbsArg,arg){    
    RooRealVar * var = dynamic_cast<RooRealVar*>(arg);
    if (!var) continue;
		if(var->isConstant()) n++;
	}
	return n;
}

//__________________________________________________________________________________|___________

int TSUtils::countFloatParameters(const RooAbsCollection& params){
  return countFloatParameters(&params);
}

//__________________________________________________________________________________|___________

int TSUtils::countFloatParameters(const RooAbsCollection* params){
  // count how many parameters are floating
  if(!params) return -1;
  int n = 0;
  ROOFIT_ITERATE(*params,RooAbsArg,arg){    
    RooRealVar * var = dynamic_cast<RooRealVar*>(arg);
    if (!var) continue;
    if(!var->isConstant()) n++;
  }
  return n;
}

//__________________________________________________________________________________|___________


template<class stringT>
void TSUtils::getParameterNames(const RooAbsCollection& l,std::vector<stringT>& names){
  for(auto* obj:l){
    names.push_back(obj->GetName());
  }
}
template<class stringT>
void TSUtils::getParameterNames(const RooAbsCollection* l,std::vector<stringT>& names){
  // extract the parameter names from a list
  if(!l) return;
  TSUtils::getParameterNames(*l,names);
}
template void TSUtils::getParameterNames<TString>    (const RooAbsCollection* l,std::vector<TString>& names);
template void TSUtils::getParameterNames<std::string>(const RooAbsCollection* l,std::vector<std::string>& names);
template void TSUtils::getParameterNames<TString>    (const RooAbsCollection& l,std::vector<TString>& names);
template void TSUtils::getParameterNames<std::string>(const RooAbsCollection& l,std::vector<std::string>& names);

//__________________________________________________________________________________|___________

namespace {
  void getArgs(RooWorkspace* ws, const std::vector<TString>& names, RooArgSet& args){
    for(const auto& p:names){
      RooAbsArg* v =(RooAbsArg*) ws->obj(p);
      if(v){
        args.add(*v);
      }
    }
  }
  void getArgs(RooWorkspace* ws, const std::vector<std::string>& names, RooArgSet& args){
    for(const auto& p:names){
      RooRealVar* v = ws->var(p.c_str());
      if(v){
        args.add(*v);
      }
      RooAbsCategory* c = ws->cat(p.c_str());
      if(c){
        args.add(*c);
      }
    }
  }
  const char* name(const TString& s){
    return s.Data();
  }
  const char* name(const TObject* o){
    return o->GetName();
  }  
  bool samename(const char* a, const char*  b){
    return strcmp(a,b)==0;
  }    
  template<class ListT1,class ListT2> void myAssertList(const ListT1& n1, const ListT2& n2, const char* msg, bool throwCatch){
    if(n1.size() != n2.size()){
      TString message = msg;
      message += TString::Format(": %d -> %d",(int)n1.size(),(int)n2.size());
      for(const auto& item1:n1){
        bool found = false;
        for(const auto& item2:n2){
          if(samename(name(item1),name(item2))){
            found = true;
            break;
          }
        }
        if(!found){
          message += TString::Format("\n  missing: %s",name(item1));
        }
      }
      for(const auto& item1:n2){
        bool found = false;
        for(const auto& item2:n1){
          if(samename(name(item1),name(item2))){          
            found = true;
            break;
          }
        }
        if(!found){
          message += TString::Format("\n  added: %s",name(item1));
        }
      }      
      if(throwCatch) throw std::runtime_error((TString("error: ")+message).Data());
      else warn(message);
    }
  }
  template<class ListT1,class ListT2> void myAssertList(const ListT1* n1, const ListT2* n2, const char* msg, bool throwCatch){
    myAssertList(*n1,*n2,msg,throwCatch);
  }
  template<class ListT1,class ListT2> void myAssertList(const ListT1* n1, const ListT2& n2, const char* msg, bool throwCatch){
    myAssertList(*n1,n2,msg,throwCatch);
  }
  template<class ListT1,class ListT2> void myAssertList(const ListT1& n1, const ListT2* n2, const char* msg, bool throwCatch){
    myAssertList(n1,*n2,msg,throwCatch);
  }
    
  
}

bool TSUtils::importObjectToWorkspace(RooWorkspace* ws, RooAbsArg* obj){
  // wrapper for RooWorkspace::import
  if(!ws || !obj) return false;
  return !ws->import(*obj);
}

bool TSUtils::importObjectToWorkspace(RooWorkspace* ws, RooAbsData* obj){
  // wrapper for RooWorkspace::import
  if(!ws || !obj) return false;
  return !ws->import(*obj);
}


RooWorkspace* TSUtils::makeCleanWorkspace(RooWorkspace* oldWS, const char* newName, const char* mcname, bool copySnapshots, bool catchUnaccountedParameters){
  // clone a workspace, copying all needed components and discarding all others

  // butcher the old workspace
  auto objects = oldWS->allGenericObjects();
  RooStats::ModelConfig* oldMC = dynamic_cast<RooStats::ModelConfig*>(oldWS->obj(mcname));
  RooAbsPdf* pdf = NULL;
  auto data = oldWS->allData();
  for(auto it:objects){
    if(!oldMC){
      oldMC = dynamic_cast<RooStats::ModelConfig*>(it);
    }
    pdf = dynamic_cast<RooSimultaneous*>(it);
  }

  // butcher the old modelconfig
  std::vector<TString> poilist;
  std::vector<TString> nplist;
  std::vector<TString> obslist;
  std::vector<TString> globobslist;
  if(oldMC){
    pdf = oldMC->GetPdf();
    TSUtils::getParameterNames(oldMC->GetParametersOfInterest(),poilist);
    TSUtils::getParameterNames(oldMC->GetNuisanceParameters(),nplist);
    TSUtils::getParameterNames(oldMC->GetObservables(),obslist);
    TSUtils::getParameterNames(oldMC->GetGlobalObservables(),globobslist);
    myAssertList(oldMC->GetParametersOfInterest(),poilist,"exporting POI list",catchUnaccountedParameters);
    myAssertList(oldMC->GetNuisanceParameters(),nplist,"exporting NP list!",catchUnaccountedParameters);
    myAssertList(oldMC->GetObservables(),obslist,"exporting Obs list",catchUnaccountedParameters);
    myAssertList(oldMC->GetGlobalObservables(),globobslist,"exporting Globs list",catchUnaccountedParameters);
  } else if(!pdf){
    pdf = oldWS->pdf(mcname);
  }

  if(!pdf){
    return NULL;
  }

  // create them anew
  RooWorkspace* newWS = new RooWorkspace(newName);
  newWS->autoImportClassCode(true);
  RooStats::ModelConfig* newMC = new RooStats::ModelConfig("ModelConfig", newWS);

  newWS->import(*pdf, RooFit::RecycleConflictNodes());
  RooAbsPdf* newPdf = newWS->pdf(pdf->GetName());
  newMC->SetPdf(*newPdf);

  for(auto d:data){
    newWS->import(*d);
  }

  RooArgSet poiset; getArgs(newWS,poilist,poiset);
  RooArgSet npset; getArgs(newWS,nplist,npset);
  RooArgSet obsset; getArgs(newWS,obslist,obsset);
  RooArgSet globobsset; getArgs(newWS,globobslist,globobsset);

  myAssertList(poilist,poiset,"setting POI list",catchUnaccountedParameters);
  myAssertList(nplist,npset,"setting NP list",catchUnaccountedParameters);
  myAssertList(obslist,obsset,"setting Obs list",catchUnaccountedParameters);
  myAssertList(globobslist,globobsset,"setting Globs list",catchUnaccountedParameters);
  
  newMC->SetParametersOfInterest(poiset);
  newMC->SetNuisanceParameters  (npset);
  newMC->SetObservables         (obsset);
  newMC->SetGlobalObservables   (globobsset);

  myAssertList(poiset,newMC->GetParametersOfInterest(),"setting POI list",catchUnaccountedParameters);
  myAssertList(npset,newMC->GetNuisanceParameters(),"setting NP list",catchUnaccountedParameters);
  myAssertList(obsset,newMC->GetObservables(),"setting Obs list",catchUnaccountedParameters);
  myAssertList(globobsset,newMC->GetGlobalObservables(),"setting Globs list",catchUnaccountedParameters);

  newWS->import(*newMC);

  RooStats::ModelConfig* importedMC = (RooStats::ModelConfig*)(newWS->obj(newMC->GetName()));

  myAssertList(newMC->GetParametersOfInterest(),importedMC->GetParametersOfInterest(),"importing POI list",catchUnaccountedParameters);
  myAssertList(newMC->GetNuisanceParameters()  ,importedMC->GetNuisanceParameters()  ,"importing NP list",catchUnaccountedParameters);
  myAssertList(newMC->GetObservables()         ,importedMC->GetObservables()         ,"importing Obs list",catchUnaccountedParameters);
  myAssertList(newMC->GetGlobalObservables()   ,importedMC->GetGlobalObservables()   ,"importing Globs list",catchUnaccountedParameters);


  if(copySnapshots){
    // Copy snapshots
    // Fancy ways to avoid public-private hack used in the following, simplified version in comments above the respective lines
    auto snapshots(TSUtils::getListOfSnapshots(oldWS));
    for(size_t i=0; i<(size_t)(snapshots.GetSize()); ++i){
      RooArgSet* snap = dynamic_cast<RooArgSet*>(snapshots.At(i));
      newWS->saveSnapshot(snap->GetName(),*snap,true);
    }
  }

  return newWS;
}

//__________________________________________________________________________________|___________

RooLinkedList& TSUtils::getListOfSnapshots(RooWorkspace* ws){
  if (!ws) {
    throw std::runtime_error("invalid workspace pointer passed!");
  }
  return ws->*RooWorkspaceHackResult<RooWorkspace_snapshots>::ptr;
}


//__________________________________________________________________________________|___________

std::vector<TString> TSUtils::getListOfSnapshotNames(RooWorkspace* ws){
  // retrieve the list of snapshots
  std::vector<TString> names;
  if(!ws) return names;
  ROOFIT_ITERATE(getListOfSnapshots(ws),auto,snap){      
    names.push_back(snap->GetName());
  }
  return names;
}

//__________________________________________________________________________________|___________

bool TSUtils::takeSnapshot(RooWorkspace* workspace, const TString& snShName, TQTaggable* config, TSStatisticsManager* manager) {

  if (!workspace) return false;
  //create a dummy config object if none was provided (-> always using default values)
  bool transientConfig = !config;
  if (transientConfig) config = new TQTaggable();

  //local method definition to print infos with or without a manager
  void (*printInfo)(TSStatisticsManager*, const TString&) = [](TSStatisticsManager* manager, const TString& msg) {
    if (manager) manager->info(msg);
    else std::cout<<"[INFO] "<<msg.Data()<<std::endl;
  };

  RooStats::ModelConfig* mc = dynamic_cast<RooStats::ModelConfig*>(workspace->obj(config->getTagStringDefault("~modelConfig","ModelConfig")));
  RooArgSet allVars(workspace->allVars());

  bool all    = config->getTagBoolDefault("all",false);
  bool pois   = config->getTagBoolDefault("POIs",true);
  bool nps    = config->getTagBoolDefault("NPs",true);
  bool obs    = config->getTagBoolDefault("obs",false);
  bool globs  = config->getTagBoolDefault("globs",true);
  RooArgSet vars;
  if(all){
    vars.add(allVars);
    printInfo(manager, TString::Format("taking snapshot '%s' of configuration, including all variables",snShName.Data()));
  } else if(mc){
    if(pois ) vars.add(*(mc->GetParametersOfInterest()));
    if(nps  ) vars.add(*(mc->GetNuisanceParameters()));
    if(obs  ) vars.add(*(mc->GetObservables()));
    if(globs) vars.add(*(mc->GetGlobalObservables()));
    int npars = vars.getSize();
    TSUtils::addParameters(&allVars,config->getTagVString("constPars"),vars);
    TSUtils::addParameters(&allVars,config->getTagVString("floatPars"),vars);
    TSUtils::addParameters(&allVars,config->getTagVString("addPars"),vars);    
    TSUtils::addParameters(&allVars,TSUtils::getParameterKeys(config,"setPars"),vars);
    int addpars = vars.getSize() - npars;

    printInfo(manager,TString::Format("taking snapshot '%s' of configuration, including POIs (%s), NPs (%s), Observables (%s) and Global Observables (%s), plus %d additional parameters",snShName.Data(),
                                  pois ? "yes" : "no",
                                  nps ? "yes" : "no",
                                  obs ? "yes" : "no",
                                  globs ? "yes" : "no",
                                  addpars));
  }

  if(vars.getSize() > 0){
    workspace->saveSnapshot(snShName,vars);
    if (transientConfig) delete config;
    return true;
  } else {
    //single occurance, so no convenience function defined
    if (manager) manager->warn("skipping snapshot creation, no variables listed...");
    else std::cout<<"[WARN] skipping snapshot creation, no variables listed..."<<std::endl;
  }

  if (transientConfig) delete config;
  return false;

}

//__________________________________________________________________________________|___________

std::vector<TString> TSUtils::expandNames(const RooAbsCollection* nuis, const TString& filter, const TString& exception) {
  // expand a filter
  std::vector<TString> parnames;
  ROOFIT_ITERATE(*nuis,RooAbsArg,obj){    
    RooRealVar * var = dynamic_cast<RooRealVar*>(obj);
    if (!var) continue;
    TString varName = var->GetName();
    if (TQStringUtils::matchesFilter(varName, filter, ",", true) && !TQStringUtils::matchesFilter(varName, exception, ",", true)) {
      parnames.push_back(varName);
    }
  }
  return parnames;
}

//__________________________________________________________________________________|___________

void TSUtils::expandKeys(const RooAbsCollection* nuis, TQFolder * options) {
  // convert singles into groups
  TQIterator itrSingles(options->getListOfKeys("singles.*"), true);
  while (itrSingles.hasNext()) {
    TString name = itrSingles.readNext()->GetName();
    TString filter = options->getTagStringDefault(name, "!*");
    TQStringUtils::removeLeadingText(name, "singles.");

    ROOFIT_ITERATE(*nuis,RooAbsArg,obj){    
      RooRealVar * var = dynamic_cast<RooRealVar*>(obj);
      if (!var) continue;
      TString varName = var->GetName();
      if (TQStringUtils::matchesFilter(varName, filter, ",", true)) {
        // add as group with one element
        TString groupName = TString("group.") + varName;
        if (!options->hasTag(groupName)) {
          options->setTagString(groupName, varName);
        }
      }
    }
  }
}


//__________________________________________________________________________________|___________

std::map<TString,double> TSUtils::getParameterValues(const RooAbsCollection& parameters){
  // obtain the values of parameters
  return getParameterValues(&parameters);
}

//__________________________________________________________________________________|___________

std::map<TString,double> TSUtils::getParameterValues(const RooAbsCollection* parameters){
  // obtain the values of parameters
  std::map<TString,double> values;
  for(auto* obj:*parameters){
    RooRealVar* poi = dynamic_cast<RooRealVar*>(obj);
    values[obj->GetName()] = poi->getVal();
  }
  return values;
}

//__________________________________________________________________________________|___________

void TSUtils::setParameterValues(const RooAbsCollection* parameters, double val){
  // set a set of parameters all to the same value
  for(auto* obj:*parameters){
    RooRealVar* poi = dynamic_cast<RooRealVar*>(obj);
    poi->setVal(val);
  }
}

//__________________________________________________________________________________|___________

void TSUtils::setParameterValues(const RooAbsCollection& parameters, const RooAbsCollection& values){
  // set a set of parameters all to the same value
  TSUtils::setParameterValues(&parameters,&values);
}

//__________________________________________________________________________________|___________

void TSUtils::setParameterValues(const RooAbsCollection& parameters, const RooAbsCollection* values){
  // set a set of parameters all to the same value
  TSUtils::setParameterValues(&parameters,values);
}

//__________________________________________________________________________________|___________

void TSUtils::setParameterValues(const RooAbsCollection* parameters, const RooAbsCollection& values){
  // set a set of parameters all to the same value
  TSUtils::setParameterValues(parameters,&values);
}

//__________________________________________________________________________________|___________

void TSUtils::setParameterValues(const RooAbsCollection* parameters, const RooAbsCollection* values){
  // set a set of parameters all to the same value
  if(!values || !parameters) return;
  for(auto* obj:*parameters){
    RooRealVar* poi = dynamic_cast<RooRealVar*>(obj);
    if(!poi) continue;
    RooAbsReal* val = dynamic_cast<RooAbsReal*>(values->find(poi->GetName()));
    if(!val) continue;
    poi->setVal(val->getVal());
  }
}

//__________________________________________________________________________________|___________

void TSUtils::setParameterValues(const RooAbsCollection* parameters, const std::map<TString,double>& values){
  // set a set of parameters all to the same value
  if(!parameters) return;
  TSUtils::setParameterValues(*parameters,values);
}

//__________________________________________________________________________________|___________

void TSUtils::setParameterValues(const RooAbsCollection& parameters, const std::map<TString,double>& values){
  for(auto* obj:parameters){
    RooRealVar* poi = dynamic_cast<RooRealVar*>(obj);
    if(!poi) continue;
    auto val = values.find(poi->GetName());
    if(val == values.end()) continue;
    poi->setVal(val->second);
  }
}

//__________________________________________________________________________________|___________

void TSUtils::setParametersConstFloat(const RooAbsCollection& parameters, const RooAbsCollection& values){
  // set a set of parameters all to the same value
  TSUtils::setParametersConstFloat(&parameters,&values);
}

//__________________________________________________________________________________|___________

void TSUtils::setParametersConstFloat(const RooAbsCollection& parameters, const RooAbsCollection* values){
  // set a set of parameters all to the same value
  TSUtils::setParametersConstFloat(&parameters,values);
}

//__________________________________________________________________________________|___________

void TSUtils::setParametersConstFloat(const RooAbsCollection* parameters, const RooAbsCollection& values){
  // set a set of parameters all to the same value
  TSUtils::setParametersConstFloat(parameters,&values);
}

//__________________________________________________________________________________|___________

void TSUtils::setParametersConstFloat(const RooAbsCollection* parameters, const RooAbsCollection* values){
  // set a set of parameters all to the same value
  if(!values || !parameters) return;
  for(auto* obj:*parameters){
    RooRealVar* poi = dynamic_cast<RooRealVar*>(obj);
    if(!poi) continue;
    RooAbsReal* val = dynamic_cast<RooAbsReal*>(values->find(poi->GetName()));
    if(!val) continue;
    poi->setConstant(val->isConstant());
  }
}

//__________________________________________________________________________________|___________

std::vector<TString> TSUtils::getParameterKeys(TQTaggable* tags, const TString& prefix){
  TQIterator params(tags->getListOfKeys(prefix+".*"),true);
  std::vector<TString> retval;
  while(params.hasNext()){
    TObject* key = params.readNext();
    if(!key) continue;
    TString name(key->GetName());
    TQStringUtils::removeLeadingText(name,prefix+".");
    retval.push_back(name);
  }
  return retval;
}

//__________________________________________________________________________________|___________

void TSUtils::setParameterValues(const RooAbsCollection* parameters, TQTaggable* options, const TString& prefix, bool forceSetConst){
  // the parameters in the workspace to the values given by the tags
  DEBUGfunc("entering function");

  TQIterator params(options->getListOfKeys(prefix+".*"),true);
  while(params.hasNext()){
    TObject* key = params.readNext();
    if(!key) continue;
    TString name(key->GetName());
    TQStringUtils::removeLeadingText(name,prefix+".");
    RooRealVar* var = dynamic_cast<RooRealVar*>(parameters->find(name));
    double val;
    if(!var){
      error(TString::Format("unable to initialize parameter '%s' - not found!",name.Data()));
    } else if(!options->getTagDouble(key->GetName(),val)){
      error(TString::Format("internal error - no value set for parameter '%s'",name.Data()));
    } else if(var->isConstant() && !forceSetConst){
      warn(TString::Format("skipping constant parameter '%s'",name.Data()));
    } else {
      if(val > var->getMax()){
        var->setMax(val);
      } else if(val < var->getMin()){
        var->setMin(val);
      }
      var->setVal(val);
      if(val == var->getVal()){
        info(TString::Format("initializing parameter '%s' to '%g'",name.Data(),val));
      } else {
        info(TString::Format("failed to initialize parameter '%s' to '%g'",name.Data(),val));
      }
    }
  }
}

void TSUtils::setParameterErrors(const RooAbsCollection* parameters, TQTaggable* options, const TString& prefix, bool forceSetConst){
  // the parameters in the workspace to the values given by the tags
  DEBUGfunc("entering function");
  TQIterator params(options->getListOfKeys(prefix+".*"),true);
  while(params.hasNext()){
    TObject* key = params.readNext();
    if(!key) continue;
    TString name(key->GetName());
    TQStringUtils::removeLeadingText(name,prefix+".");
    RooRealVar* var = dynamic_cast<RooRealVar*>(parameters->find(name));
    double val;
    if(!var){
      error(TString::Format("unable to initialize parameter error '%s' - not found!",name.Data()));
    } else if(!options->getTagDouble(key->GetName(),val)){
      error(TString::Format("internal error - no value set for parameter '%s'",name.Data()));
    } else if(var->isConstant() && !forceSetConst){
      DEBUGfunc("skipping constant parameter");
      continue;
    } else {
      info(TString::Format("initializing parameter error '%s' to '%g'",name.Data(),val));
      var->setError(val);
    }
  }
}

void TSUtils::setParameterRanges(const RooAbsCollection* parameters, TQTaggable* options, const TString& prefix){
  // the parameters in the workspace to the values given by the tags
  DEBUGfunc("entering function");
  TQIterator params(options->getListOfKeys(prefix+".*"),true);
  while(params.hasNext()){
    TObject* key = params.readNext();
    if(!key) continue;
    TString name(key->GetName());
    TQStringUtils::removeLeadingText(name,prefix+".");
    RooRealVar* var = dynamic_cast<RooRealVar*>(parameters->find(name));
    std::vector<double> range = options->getTagVDouble(key->GetName());
    if(!var){
      error(TString::Format("unable to initialize parameter error '%s' - not found!",name.Data()));
    } else if(range.size() != 2){
      error(TString::Format("internal error - range for parameter '%s' needs to be set to have exactly 2 values {lowEdge,upEdge}",name.Data()));
    } else {
      var->setRange(range[0],range[1]);
    }
  }
}

//__________________________________________________________________________________|___________

void TSUtils::setParameterValues(const RooAbsCollection& parameters, TQFolder* fitResult){
  // the parameters in the workspace to the values given by the fit result
  if(!fitResult) return;
  TQFolderIterator pars(fitResult->getListOfFolders("?"),true);
  while(pars.hasNext()){
    TQFolder* par = pars.readNext();
    RooRealVar* p = dynamic_cast<RooRealVar*>(parameters.find(par->GetName()));
    if(!p){
      warn(TString::Format("unable to find parameter '%s' in set '%s'",par->GetName(),parameters.GetName()));
      continue;
    }
    p->setVal(par->getTagDoubleDefault("val",0.));
  }
}


//__________________________________________________________________________________|___________

void TSUtils::setParametersConstant(const RooAbsCollection* parameters, const std::vector<TString>& parnames, bool constval){
  // the parameters in the workspace to the constant o given by the tags
  DEBUGfunc("entering function");
  for(const auto& name:parnames){
    for(auto* obj:*parameters){
      if(!obj) continue;
      RooRealVar* var = dynamic_cast<RooRealVar*>(obj);
      if(!var) continue;
      if(TQStringUtils::matches(var->GetName(),name)){
        if(var->isConstant() != constval){
          //          info(TString::Format("setting parameter '%s' to %s",var->GetName(),constval ? "constant" : "floating"));
          var->setConstant(constval);
        }
      }
    }
  }
}

//__________________________________________________________________________________|___________

void TSUtils::addParameters(const RooAbsCollection* parameters, const std::vector<TString>& parnames, RooAbsCollection& pars){
  // the parameters in the workspace to the constant o given by the tags
  DEBUGfunc("entering function");
  TString buf;
  for(const auto& name:parnames){
    for(auto* obj:*parameters){
      if(!obj) continue;
      RooRealVar* var = dynamic_cast<RooRealVar*>(obj);
      if(!var) continue;
      if(TQStringUtils::matches(var->GetName(),name)){
        pars.add(*var);
      }
    }
  }
}

//__________________________________________________________________________________|___________


RooDataSet* TSUtils::getDataHistogram(RooAbsPdf* pdf, RooArgSet* observables, RooRealVar* weightVar, RooAbsArg* moreArgs){
  // obtain a RooDataHist from a PDF
  const double infty = pow(10., 18);
  TString name = TString::Format("data_%s", pdf->GetName());

  RooArgSet * obs = pdf->getObservables(observables);
  RooRealVar* thisObs = dynamic_cast<RooRealVar*>(obs->first());

  RooArgSet allVars;
  allVars.add(*obs);
  if(moreArgs) allVars.add(*moreArgs);

  RooDataSet * data = NULL;
  if(weightVar){
    allVars.add(*weightVar);
    data = new RooDataSet(name,name,allVars,RooFit::WeightVar(*weightVar));
  } else {
    data = new RooDataSet(name,name,allVars);
  }


  double expectedEvents = pdf->expectedEvents(obs);
  for (Int_t jj = 0; jj < thisObs->numBins(); ++jj) {
    thisObs->setBin(jj);
    double thisNorm = pdf->getVal(obs) * thisObs->getBinWidth(jj);
    double val = thisNorm * expectedEvents;
    if (val == val && val >= 0. && val < infty){
      data->add(*obs, val);
    } else {
      throw std::runtime_error(TString::Format("Invalid entries for bin %d of '%s': %g",jj,pdf->GetName(),val).Data());
    }
  }
  return data;
}


//__________________________________________________________________________________|___________

TH1* TSUtils::getHistogram(RooAbsPdf* pdf, RooArgSet* observables){
  // obtain a TH1 from a PDF
  const double infty = pow(10., 18);
  TString name = TString::Format("h_data_%s", pdf->GetName());

  RooArgSet * obs = pdf->getObservables(observables);
  RooRealVar* thisObs = dynamic_cast<RooRealVar*>(obs->first());

  std::vector<double> bins = TSUtils::getBinning(pdf,thisObs);
  TH1* data = new TH1F(name,name,bins.size()-1,&bins[0]);
  data->SetDirectory(NULL);

  double expectedEvents = pdf->expectedEvents(obs);
  for (Int_t jj = 0; jj < thisObs->numBins(); ++jj) {
    thisObs->setBin(jj);
    double thisNorm = pdf->getVal(obs) * thisObs->getBinWidth(jj);
    double val = thisNorm * expectedEvents;
    if (val > 0. && val < infty){
      data->SetBinContent(jj+1,val);
    } else {
      throw std::runtime_error(TString::Format("Invalid entries for bin %d",jj).Data());
    }
  }
  return data;
}

//__________________________________________________________________________________|___________

std::vector<double> TSUtils::getBinning(RooAbsPdf* pdf, RooRealVar* obs){
  // retrieve the list of bin boundaries
  auto bl = pdf->binBoundaries(*obs,obs->getMin(),obs->getMax());
  if(!bl){
    throw std::runtime_error(TString::Format("unable to retrieve bin boundaries from pdf segment '%s' for observable '%s'!",pdf->GetName(),obs->GetName()).Data());
  }
  std::vector<double> bins;
  for (auto it=bl->begin() ; it!=bl->end() ; ++it) {
    bins.push_back(*it);
  }
  if(bins[bins.size()-1] < obs->getMax()){
    bins.push_back(obs->getMax());
  }
  return bins;
}

//__________________________________________________________________________________|___________

double TSUtils::diffParameterSets(TQFolder* p1, TQFolder* p2, bool /*verbose*/){
  // get the numerical difference(s) between two parameter sets
  TQFolderIterator itr(p2->getListOfFolders("?"),true);
  double d = 0;
  while(itr.hasNext()){
    TQFolder* f2 = itr.readNext();
    if(!f2) continue;
    TQFolder* f1 = p1->getFolder(f2->GetName());
    if(!f1) continue;
    double v1 = f1->getTagDoubleDefault("val",0.);
    double v2 = f2->getTagDoubleDefault("val",0.);
    d += pow(v1-v2,2);
  }
  return sqrt(d);
}

//__________________________________________________________________________________|___________

int TSUtils::nParameters(RooAbsReal* func){
  // retrun the number of floating parameters a function depends on
   RooArgSet* paramSet = func->getParameters(RooArgSet());
   int n = 0;
   for(auto* arg:*paramSet){
     if (arg->IsA()->InheritsFrom(RooAbsRealLValue::Class()) && !arg->isConstant()){
       n++;
     }
   }
   delete paramSet;
   return n;
}

//__________________________________________________________________________________|___________

TMatrixDSym TSUtils::getCorrelationMatrix(const TMatrixDSym& V) {
  // convert a covariance matrix to a correlation matrix
  TMatrixDSym C(V.GetNcols()) ;
  for (int i=0 ; i<V.GetNrows() ; ++i) {
    for (int j=0 ; j<V.GetNcols() ; ++j) {
      const double corr = V(i,j)/sqrt(V(i,i)*V(j,j)) ;
      C(i,j) = corr;
      C(j,i) = corr;
    }
  }
  return C;
}

//__________________________________________________________________________________|___________

void TSUtils::applySettings(TQTaggable* config, const RooArgSet& allVars, RooStats::ModelConfig* mc){

  std::vector<std::string> pois;
  std::vector<std::string> nps;
  std::vector<std::string> globs;
  std::vector<std::string> obs;

  if(mc){
    TSUtils::getParameterNames(mc->GetNuisanceParameters(),nps);
    if(mc->GetNuisanceParameters())
      assert(mc->GetNuisanceParameters()->getSize() == nps.size());
    TSUtils::getParameterNames(mc->GetParametersOfInterest(),pois);
    if(mc->GetParametersOfInterest())
      assert(mc->GetParametersOfInterest()->getSize() == pois.size());
    TSUtils::getParameterNames(mc->GetGlobalObservables(),globs);
    if(mc->GetGlobalObservables())
      assert(mc->GetGlobalObservables()->getSize() == globs.size());
    TSUtils::getParameterNames(mc->GetObservables(),obs);
    if(mc->GetObservables())
      assert(mc->GetObservables()->getSize() == obs.size());
  }
  TString constParsFilter   = TQStringUtils::concat(config->getTagVString("constPars"));
  TString constExcept = TQStringUtils::concat(config->getTagVString("constPars.except"));
  TString floatParsFilter   = TQStringUtils::concat(config->getTagVString("floatPars"));
  TString floatExcept = TQStringUtils::concat(config->getTagVString("floatPars.except"));
  std::vector<std::string> addNPs = config->getTagVStandardString("addNPs");
  std::vector<std::string> removeNPs = config->getTagVStandardString("removeNPs");
  std::vector<std::string> addPOIs = config->getTagVStandardString("addPOIs");
  std::vector<std::string> removePOIs = config->getTagVStandardString("removePOIs");
  std::vector<std::string> addObs = config->getTagVStandardString("addObs");
  std::vector<std::string> removeObs = config->getTagVStandardString("removeObs");
  std::vector<std::string> addGlobs = config->getTagVStandardString("addGlobs");
  std::vector<std::string> removeGlobs = config->getTagVStandardString("removeGlobs");
  TSUtils::setParameterValues(&(allVars),config,"setPars",true);
  TSUtils::setParameterErrors(&(allVars),config,"setParErrors",true);
  TSUtils::setParameterRanges(&(allVars),config,"setParRanges");  

  ROOFIT_ITERATE(allVars,RooAbsArg,obj){    
    RooRealVar * var = dynamic_cast<RooRealVar*>(obj);
    if (!var) continue;
    bool setConst = /*is in whitelist*/ TQStringUtils::matchesFilter(var->GetName(), constParsFilter, ",", true) &&
      /*and not in blacklist*/ !TQStringUtils::matchesFilter(var->GetName(), constExcept, ",", true);
    bool setFloat = /*is in whitelist*/ TQStringUtils::matchesFilter(var->GetName(), floatParsFilter, ",", true) &&
      /*and not in blacklist*/ !TQStringUtils::matchesFilter(var->GetName(), floatExcept, ",", true);
    bool addNP = false;
    bool removeNP = false;
    bool addPOI = false;
    bool removePOI = false;
    bool addOb = false;
    bool removeOb = false;
    bool addGlob = false;
    bool removeGlob = false;
    for(const auto& vname:addNPs){
      if(TQStringUtils::matchesFilter(var->GetName(),vname)){
        addNP = true;
      }
    }
    for(const auto& vname:removeNPs){
      if(TQStringUtils::matchesFilter(var->GetName(),vname)){
        removeNP = true;
      }
    }
    for(const auto& vname:addPOIs){
      if(TQStringUtils::matchesFilter(var->GetName(),vname)){
        addPOI = true;
      }
    }
    for(const auto& vname:removePOIs){
      if(TQStringUtils::matchesFilter(var->GetName(),vname)){
        removePOI = true;
      }
    }
    for(const auto& vname:addObs){
      if(TQStringUtils::matchesFilter(var->GetName(),vname)){
        addOb = true;
      }
    }
    for(const auto& vname:removeObs){
      if(TQStringUtils::matchesFilter(var->GetName(),vname)){
        removeOb = true;
      }
    }
    for(const auto& vname:addGlobs){
      if(TQStringUtils::matchesFilter(var->GetName(),vname)){
        addGlob = true;
      }
    }
    for(const auto& vname:removeGlobs){
      if(TQStringUtils::matchesFilter(var->GetName(),vname)){
        removeGlob = true;
      }
    }
    if(setConst && !setFloat){
      var->setConstant(true);
      info(TString::Format("setting parameter '%s' constant",var->GetName()));
    }
    //add/remove NP
    if(addNP){
      auto found_np = std::find(nps.begin(),nps.end(),std::string(var->GetName()));
      if(found_np == nps.end()){
        nps.push_back(var->GetName());
        info(TString::Format("adding parameter '%s' to the list of nuisance parameters",var->GetName()));
      }
    } else if(removeNP){
      info(TString::Format("removing parameter '%s' from the list of nuisance parameters",var->GetName()));
      auto found_np = std::find(nps.begin(),nps.end(),std::string(var->GetName()));
      if(found_np != nps.end()) nps.erase(found_np);
    }
    //add/remove POI
    if(addPOI){
      auto found_poi = std::find(pois.begin(),pois.end(),std::string(var->GetName()));
      if(found_poi == pois.end()){
        pois.push_back(var->GetName());
        info(TString::Format("adding parameter '%s' to the list of parameters of interest",var->GetName()));
      }
    } else if(removePOI){
      info(TString::Format("removing parameter '%s' from the list of parameters of interest",var->GetName()));
      auto found_poi = std::find(pois.begin(),pois.end(),std::string(var->GetName()));
      if(found_poi != pois.end()) pois.erase(found_poi);
    }
    //add/remove Obs (Observable)
    if(addOb){
      auto found_obs = std::find(obs.begin(),obs.end(),std::string(var->GetName()));
      if(found_obs == obs.end()){
        obs.push_back(var->GetName());
        info(TString::Format("adding parameter '%s' to the list of observables",var->GetName()));
      }
    } else if(removeOb){
      info(TString::Format("removing parameter '%s' from the list of observables",var->GetName()));
      auto found_obs = std::find(obs.begin(),obs.end(),std::string(var->GetName()));
      if(found_obs != obs.end()) obs.erase(found_obs);
    }
    //add/remove Glob (GlobalObservable)
    if(addGlob){
      auto found_glob = std::find(globs.begin(),globs.end(),std::string(var->GetName()));
      if(found_glob == globs.end()){
        globs.push_back(var->GetName());
        info(TString::Format("adding parameter '%s' to the list of global observables",var->GetName()));
      }
    } else if(removeGlob){
      info(TString::Format("removing parameter '%s' from the list of global observables",var->GetName()));
      auto found_glob = std::find(globs.begin(),globs.end(),std::string(var->GetName()));
      if(found_glob != globs.end()) globs.erase(found_glob);
    }

    if(setFloat && !setConst){
      info(TString::Format("setting parameter '%s' floating",var->GetName()));
      var->setConstant(false);
    }
    if(setFloat && setConst){
      warn(TString::Format("refusing to change const property of parameter '%s' matching both constPars='%s' and floatPars='%s'",var->GetName(),constParsFilter.Data(),floatParsFilter.Data()));
    }
  }

  if(mc){
    RooWorkspace* ws = mc->GetWorkspace();
    if(!ws) throw std::runtime_error("ModelConfig has no workspace!");

    RooArgSet npset; getArgs(ws,nps,npset);
    mc->SetNuisanceParameters(npset);
    assert(mc->GetNuisanceParameters()->getSize() == nps.size());
    RooArgSet poiset; getArgs(ws,pois,poiset);
    mc->SetParametersOfInterest(poiset);
    assert(mc->GetParametersOfInterest()->getSize() == pois.size());
    RooArgSet obsset; getArgs(ws,obs,obsset);
    mc->SetObservables(obsset);
    assert(mc->GetObservables()->getSize() == obs.size());
    RooArgSet globset; getArgs(ws,globs,globset);
    mc->SetGlobalObservables(globset);
    assert(mc->GetGlobalObservables()->getSize() == globs.size());
  }

}


//hack section (advanced stuff to tame RooFit)

//__________________________________________________________________________________|___________

std::vector<const RooAbsArg*> * TSUtils::getConstituents(const RooAbsArg* parent) {
  //convenience wrapper to extract constituent terms from various RooFit classes
  //"... because uniform interfaces are too mainstream ..."
  //caller takes ownership of returned vector object (but not its contents)

  if (!parent) return nullptr;

  const TClass* parentClass = parent->IsA();
  std::vector<const RooAbsArg*>* children = nullptr;

  if (parentClass == RooSimultaneous::Class()) {
    //case: it's a RooSimultaneous
    //since the pdfs inside a RooSimultaneous are in a protected member we use a small wrapper class to access them
    return ::RooSimultaneousHelper::getConstituents(dynamic_cast<const RooSimultaneous*>(parent));
  } else if (parentClass == RooRealSumPdf::Class()) {
    const RooRealSumPdf* sum = dynamic_cast<const RooRealSumPdf*>(parent);
    if (sum) {
      children = new std::vector<const RooAbsArg*>();
      for(auto* arg:sum->funcList()){
        if (!arg) continue;
        children->push_back(arg);
      }
    }
    return children;
  } else if (parentClass == RooProdPdf::Class()) {
    //case: RooProdPdf
    const RooProdPdf* prod = dynamic_cast<const RooProdPdf*>(parent);
    if (prod) {
      children = new std::vector<const RooAbsArg*>();
      for(auto* arg:prod->pdfList()){
        if (!arg) continue;
        children->push_back(arg);
      }
    }
    return children;
  } else if (parentClass == RooProduct::Class()) {
    //case: RooProduct
    const RooProduct* prod = dynamic_cast<const RooProduct*>(parent);
    if (prod) {
      children = new std::vector<const RooAbsArg*>();
      //thanks to RooProduct::components not being marked as const, we need this ugly cast here...
      RooArgList al = const_cast<RooProduct*>(prod)->components(); //we need to store the RooArgsList in some object as it's returned by value, not by reference
      for(auto* arg:al){
        if (!arg) continue;
        children->push_back(arg);
      }
    }
    return children;
  } else if (parentClass == PiecewiseInterpolation::Class()) {
    //case: PiecewiseInterpolation
    const PiecewiseInterpolation* interp = dynamic_cast<const PiecewiseInterpolation*>(parent);
    if (interp) {
      children = new std::vector<const RooAbsArg*>();
      const RooAbsArg* nominal = ::PiecewiseInterpolationHelper::getNominalMember(interp);
      if (nominal) children->push_back(nominal); //add the "_nominal" member (typically a RooHistFunc)
      for(auto* arg:interp->paramList()){
        if (!arg) continue;
        children->push_back(arg);
      }
    }
    return children;
  } /*else {
    std::cout<<"Unsupported Class? "<<parent->IsA()->GetName()<<std::endl;
    if (parent->IsA() == ParamHistFunc::Class()) parent->Print();
    if (parent->IsA() == RooStats::HistFactory::FlexibleInterpVar::Class()) parent->Print();
  }*/
  //eventually return a nullptr if we didn't get a class that has constituents (or is not supported)
  return children;
} // end getConstituents

//__________________________________________________________________________________|___________

std::set<const RooAbsArg*>* TSUtils::getContributionsRecursive(const RooAbsArg* rootNode, TClass* cl, bool recurseMatching, std::set<const RooAbsArg*>* elements) {
  if (!rootNode) return elements; //possibly nullptr

  std::vector<const RooAbsArg*>* constituents = getConstituents(rootNode);
  if (!constituents) return elements; //possibly nullptr / nothing to do here, can't recurse

  if (!elements) elements = new std::set<const RooAbsArg*>();
  recurseMatching = recurseMatching || !cl; //if not explicit class is specified we always recurse

  for (const RooAbsArg* node : *constituents) {
    if (!node) continue;
    if (!cl || node->IsA() == cl) { //matching type
      elements->insert(node);
    }
    if (recurseMatching || !(node->IsA() == cl)) { //not a matching type or we should also recurse within matching types (this includes also not having an explicit class specified)
      getContributionsRecursive(node, cl, recurseMatching, elements);
    }
  }
  delete constituents;
  constituents = nullptr;

  return elements;
}

std::map<std::string,RooArgSet>* TSUtils::getNamedSets(RooWorkspace* ws) {
  return &((*ws).*RooWorkspaceHackResult<RooWorkspace_namedSets>::ptr);
}


namespace {
  enum MatrixStatus {
    DIAG_UP_OK,
    DIAG_DOWN_OK,
    DIAG_UP_FLIPPED,
    DIAG_DOWN_FLIPPED,
    NOT_OK
  };

  // test the orientation of the matrix
  MatrixStatus validateMatrix(TH2* hist, bool isCorrelation){
    if(!hist) return NOT_OK;
    size_t n = hist->GetNbinsX();
    if(n != (size_t) hist->GetNbinsY()) return NOT_OK;

    bool diag_down_vals = true;
    bool diag_up_vals = true;

    // check if the values are distributed sanely
    // for correlation matrices, just check that a diagonal is 1 (and which one it is)
    // for covariance matrix, try converting it into a correlation
    // matrix using both possible orientations and check which one
    // fits the above criterion
    for(size_t i=0; i<n; ++i){
      double maxval_v1 = -inf;
      double maxval_v2 = -inf;
      int maxidx_v1 = -1;
      int maxidx_v2 = -1;

      double ii1 = (hist->GetBinContent(i+1,i+1));
      double ii2 = (hist->GetBinContent(i+1,n-i));

      for(size_t j=0; j<n; ++j){
        double val = hist->GetBinContent(i+1,j+1);
        double v1,v2;
        if(isCorrelation){
          v1 = val;
          v2 = val;
        } else {
          double jj1 = (hist->GetBinContent(j+1,j+1));
          double jj2 = (hist->GetBinContent(n-j,j+1));

          v1 = val / sqrt(ii1 * jj1);
          v2 = val / sqrt(ii2 * jj2);
        }
        if(v1 > maxval_v1){
          maxval_v1 = v1;
          maxidx_v1 = j;
        }
        if(v2 > maxval_v2){
          maxval_v2 = v2;
          maxidx_v2 = (int) j;
        }
      }
      if(! (TMath::AreEqualRel(maxval_v1,1.,1e-3) && (maxidx_v1 ==   (int) i  )) ){
        diag_up_vals = false;
      }
      if(! (TMath::AreEqualRel(maxval_v2,1.,1e-3) && (maxidx_v2 == (int) (n-i-1))) ){
        diag_down_vals = false;
      }
    }


    // check if the labels are distributed sanely
    bool diag_down_labels = true;
    bool diag_up_labels = true;
    for(size_t i=0; i<n; ++i){
      if(!TQStringUtils::equal(hist->GetXaxis()->GetBinLabel(i+1),hist->GetYaxis()->GetBinLabel(i+1))){
        diag_up_labels = false;
      }
      if(!TQStringUtils::equal(hist->GetXaxis()->GetBinLabel(i+1),hist->GetYaxis()->GetBinLabel(n-i))){
        diag_down_labels = false;
      }
    }


    if(diag_up_vals   && diag_up_labels  ) return DIAG_UP_OK;
    if(diag_up_vals   && diag_down_labels) return DIAG_UP_FLIPPED;
    if(diag_down_vals && diag_down_labels) return DIAG_DOWN_OK;
    if(diag_down_vals && diag_up_labels  ) return DIAG_DOWN_FLIPPED;

    return NOT_OK;
  }
}

  TH2* TSUtils::makeValidMatrix(TH2* orig, bool up, bool isCovariance, bool makeCorrelation, bool verbose){
    size_t n = orig->GetXaxis()->GetNbins();
    TH2* correlations = new TH2F("correlations","correlations",n,0,n,n,0,n);
    correlations->SetDirectory(NULL);

    MatrixStatus status = validateMatrix(orig,!isCovariance);
    bool down = !up;
    bool flipXlabels = false;
    // bool flipXvalues = false; // BW: hashed (set but not used, also hashed below)
    // bool diag_down = false;   // BW: hashed (unused variable)
    /*   */if(down && status == DIAG_DOWN_OK){
      if(verbose) info("using matrix as-is");
    } else if(down && status == DIAG_DOWN_FLIPPED){
      if(verbose) info("flipping X labels");
      flipXlabels = true;
    } else if(up && status == DIAG_UP_OK){
      if(verbose) info("using matrix as-is");
    } else if(up && status == DIAG_UP_FLIPPED){
      if(verbose) info("flipping X labels");
      flipXlabels = true;
    } else if(down && status == DIAG_UP_OK){
      if(verbose) info("flipping X values & labels");
      flipXlabels = true;
      //flipXvalues = true;
    } else if(down && status == DIAG_UP_FLIPPED){
      if(verbose) info("flipping X values");
      //flipXvalues = true;
    } else if(up && status == DIAG_DOWN_OK){
      if(verbose) info("flipping X values & labels");
      flipXlabels = true;
      //flipXvalues = true;
    } else if(up && status == DIAG_DOWN_FLIPPED){
      if(verbose) if(verbose) info("flipping X values");
      //flipXvalues = true;
    } else {
      throw std::runtime_error("matrix is broken, aborting!");
    }

    for(size_t i=0; i<n; ++i){
      double xx = orig->GetBinContent(down?(i+1):(n-i),down?(n-i):(i+1));
      for(size_t j=0; j<n; ++j){
        double xy = orig->GetBinContent(down?(i+1):(n-i),j+1);
        double yy = orig->GetBinContent(n-j,j+1);
        double corr = ( isCovariance && makeCorrelation ) ? (xy / sqrt(xx * yy)) : xy;
        correlations->SetBinContent(i+1,j+1,corr);
      }
    }

    for(size_t i=0; i<n; ++i){
      int x = flipXlabels ? n-i : i+1;
      int y = i+1;
      correlations->GetXaxis()->SetBinLabel(i+1,orig->GetXaxis()->GetBinLabel(x));
      correlations->GetYaxis()->SetBinLabel(i+1,orig->GetYaxis()->GetBinLabel(y));
    }

    return correlations;

}

TVectorD TSUtils::getErrors(const TMatrixD& covariance){
  TVectorD errors(covariance.GetNcols());
  for(int i=0; i<covariance.GetNcols(); ++i){
    errors(i) = sqrt(covariance(i,i));
  }
  return errors;
}
TVectorD TSUtils::getErrors(const RooAbsCollection* parameters){
  TVectorD errors(parameters->getSize());
  int i=0; 
  for(auto arg:*parameters){
    RooRealVar* p = dynamic_cast<RooRealVar*>(arg);
    if(!p) continue;
    double e = p->getError();
    if(e <= 0){
      e = 0.5*(p->getErrorHi() + p->getErrorLo());
    }
    errors(i) = e;
  }
  return errors;
}
TMatrixDSym TSUtils::makeCovarianceMatrix(const TMatrixD& correlation, const TVectorD& errors){
  TMatrixDSym covariance(correlation.GetNcols());
  for(int i=0; i<correlation.GetNcols(); ++i){
    for(int j=0; j<correlation.GetNrows(); ++j){
      covariance(i,j) = correlation(i,j) * errors(i) * errors(j);
    }
  }
  return covariance;
}
TMatrixDSym TSUtils::makeCovarianceMatrix(const TMatrixD& correlation, const std::vector<double>& errors){
  TMatrixDSym covariance(correlation.GetNcols());
  for(int i=0; i<correlation.GetNcols(); ++i){
    for(int j=0; j<correlation.GetNrows(); ++j){
      covariance(i,j) = correlation(i,j) * errors[i] * errors[j];
    }
  }
  return covariance;
}
TMatrixDSym TSUtils::makeCorrelationMatrix(const TMatrixD& covariance){
  TVectorD errors(TSUtils::getErrors(covariance));
  TMatrixDSym correlation(covariance.GetNcols());
  for(int i=0; i<covariance.GetNcols(); ++i){
    for(int j=0; j<covariance.GetNrows(); ++j){
      correlation(i,j) = covariance(i,j) / errors(i) / errors(j);
    }
  }
  return correlation;
}


namespace {
  void getMeshHelper(const std::vector<RooRealVar*>& observables,std::vector<double>& currentValues, std::vector<std::vector<double> >& retval,size_t idx){
    if(idx == currentValues.size()){
      retval.push_back(currentValues);
    } else {
      RooRealVar* obs = observables[idx];
      size_t nbins = obs->getBinning().numBins();
      for(size_t i=0; i<nbins; ++i){
        currentValues[idx] = obs->getBinning().binCenter(i);
        getMeshHelper(observables,currentValues,retval,idx+1);
      }
    }
  }
  
  std::vector<std::vector<double> > getMesh(const std::vector<RooRealVar*>& observables){
    std::vector<std::vector<double> > retval;
    std::vector<double> currentValues(observables.size());
    getMeshHelper(observables,currentValues,retval,0);
    return retval;
  }

  void getVariations(RooAbsReal* func, RooArgList& params, std::vector<double>& up, std::vector<double>& dn,double relThreshold){
    RooArgSet* servers = func->getParameters((RooArgSet*)0);
    Double_t nom = func->getVal();
    if(!TQUtils::isNum(nom)){
      throw std::runtime_error("unable to process non-numeric nominal value!");
    }
    for (Int_t ivar=params.getSize()-1 ; ivar>=0; --ivar) {
      RooRealVar* p = (RooRealVar*)(params.at(ivar));
      Double_t cenVal = p->getVal() ;
      Double_t errVal = p->getError();
      RooRealVar* v = (RooRealVar*)(servers->find(p->GetName()));
      if(!v || !TQUtils::isNum(errVal)){
        params.remove(*p,true,true);
        continue;
      }
      // Make Plus variation
      v->setVal(cenVal+errVal) ;
      v->setValueDirty();
      const double plusVar = func->getVal();
      // Make Minus variation
      v->setVal(cenVal-errVal) ;
      v->setValueDirty();
      const double minusVar = func->getVal();
      v->setVal(cenVal) ;
      //      std::cout << func->GetName() << " " << func->ClassName() << " " << v->GetName() << " " << plusVar << " " << nom << " " << minusVar << std::endl;
      if(fabs(plusVar/nom - 1) > relThreshold || fabs(minusVar/nom - 1) > relThreshold){
        //        std::cout << " acc" << std::endl;
        up.push_back(plusVar);
        dn.push_back(minusVar);
      } else {
        //        std::cout << " dec" << std::endl;        
        params.remove(*v,true,true);
      }
    }
    delete servers;
  }
}

std::map<std::vector<double> ,RooAbsReal*> TSUtils::slice(RooAbsReal* func, const std::vector<RooRealVar*>& observables, const RooArgList& nps, double relThreshold){
  // slice a function, providing an array of separate functions, one for every bin in the n-dim grid of observables given
  DEBUG("slicing %s",func->GetName());
  RooArgSet obsset;
  for(auto obs:observables) obsset.add(*obs);
  std::map<std::vector<double> , RooAbsReal* > slices;
  if(!func->dependsOn(obsset)){
    DEBUG("no dependency on observable, copying");
    auto mesh = ::getMesh(observables);
    for(const auto& coordinates:mesh){
      slices[coordinates] = func;
    }
  } else if(func->InheritsFrom(RooAbsPdf::Class())){
    DEBUG("slicing pdf");        
    DEBUG("preparing tmp workspace");    
    RooWorkspace tmpws("tmpws");
    tmpws.import(*func);
    std::map<std::vector<double> , std::vector<RooAbsReal*> > compslices;
    std::vector<RooAbsArg*> servers;
    ROOFIT_ITERATE(func->servers(),auto,s){      
      if(!s->InheritsFrom(RooAbsReal::Class())) continue;
      servers.push_back(s);
      auto slices = slice((RooAbsReal*)s,observables,nps,relThreshold);
      if(compslices.size() == 0){
        for(const auto& slice:slices){
          compslices[slice.first] = {slice.second};
          tmpws.import(*slice.second);
        }
      } else {
        for(const auto& slice:slices){
          compslices[slice.first].push_back(slice.second);
          tmpws.import(*slice.second);          
        }
      }
    }
    for(const auto& slice:compslices){
      DEBUG("processing slice with %d components",(int)slice.first.size());
      std::stringstream edit;
      edit << "EDIT::" << func->GetName();
      for(size_t i=0; i<slice.first.size(); ++i){
        edit << "_" << observables[i]->GetName() << "_" << observables[i]->getBinning().binNumber(slice.first[i]);
        observables[i]->setVal(slice.first[i]);
      }
      edit << "(" << func->GetName();
      for(size_t i=0; i<slice.first.size(); ++i){
        edit << "," << servers[i]->GetName() << "=" << slice.second[i]->GetName();
      }
      edit << ")";
      TString editstr(edit.str().c_str());
      RooAbsReal* slicefunc = (RooAbsReal*)(tmpws.factory(editstr.Data()));
      slices[slice.first] = (RooAbsReal*)(slicefunc->cloneTree());
    }
  } else {
    DEBUG("slicing function");            
    auto mesh = ::getMesh(observables);
    DEBUG("looping over %d coordinates",(int)mesh.size());
    for(const auto& coordinates:mesh){
      std::stringstream ss;
      ss << func->GetName();
      for(size_t i=0; i<coordinates.size(); ++i){
        ss << "_" << observables[i]->GetName() << "_" << observables[i]->getBinning().binNumber(coordinates[i]);
        observables[i]->setVal(coordinates[i]);
      }
      double central = func->getVal();
      TString name(ss.str());
      DEBUG("  %s is %g for %s",func->GetName(),central,name.Data());
      #ifdef _DEBUG_
      func->Print("t");
      #endif
      std::vector<double> up,dn;
      RooArgList localnps(nps);
      ::getVariations(func,localnps,up,dn,relThreshold);
      RooAbsReal* slice = NULL;
      if(localnps.getSize() > 0){
        slice = new RooStats::HistFactory::FlexibleInterpVar(name.Data(),name.Data(),localnps,central,up,dn);
      } else {
        slice = new RooConstVar(name.Data(),name.Data(),central);
      }
      slices[coordinates] = slice;
    }
  }
  // std::cout << "done slicing " << func->GetName() << std::endl;
  return slices;
}

namespace {
  class HypoTestResultChanger : public RooStats::HypoTestResult {
  public:
    void setCLb(double v){
      if(!fBackgroundIsAlt)
	fNullPValue = v;
      else
	fAlternatePValue = v;
    }
    void setCLsplusb(double v){
      if(!fBackgroundIsAlt)
	fAlternatePValue = v;
      else
	fNullPValue = v;
    }
  };
}


int TSUtils::fixToys(RooStats::HypoTestInverterResult* r){
  //Manually fix issues where toys fail and CLs return as -1. Why isn't this fixed centrally in RooStats?
  int nfailed = 0;
  
  TGraph clb;
  TGraph clsplusb;

  double threshold = .99;  
  for(int i=0;i<r->ArraySize();i++){
    RooStats::HypoTestResult* result=r->GetResult(i);
    if(result->GetTestStatisticData() <= 0){
      result->SetTestStatisticData(std::numeric_limits<double>::quiet_NaN());
    }
    
    if(i==0 || result->CLb() <= threshold){
      clb.SetPoint(clb.GetN(),r->GetXValue(i),result->CLb());
    }
    if(i==0 || result->CLsplusb() <= threshold){
      clsplusb.SetPoint(clsplusb.GetN(),r->GetXValue(i),result->CLsplusb());
    }
  }
  for(int i=0;i<r->ArraySize();i++){
    RooStats::HypoTestResult* result=r->GetResult(i);
    if(i>0 || result->CLb() > threshold){
      ((HypoTestResultChanger*)result)->setCLb(TQHistogramUtils::evaluateGraph(&clb,r->GetXValue(i),1)); // 1 = logscale interpolation
    }
    if(i>0 || result->CLsplusb() > threshold){
      ((HypoTestResultChanger*)result)->setCLsplusb(TQHistogramUtils::evaluateGraph(&clsplusb,r->GetXValue(i),1));  // 1 = logscale interpolation
    }
  }
  

  for(int i=0;i<r->ArraySize();i++){
    RooStats::HypoTestResult* result=r->GetResult(i);    
    std::vector<double> alt_points = result->GetAltDistribution()->GetSamplingDistribution();
    std::vector<double> alt_weights = result->GetAltDistribution()->GetSampleWeights();
    std::vector<double> null_points = result->GetNullDistribution()->GetSamplingDistribution();
    std::vector<double> null_weights = result->GetNullDistribution()->GetSampleWeights();
	
    std::vector<double> new_alt_points;
    std::vector<double> new_alt_weights;
    std::vector<double> new_null_points;
    std::vector<double> new_null_weights;
   
    double ratio = 10;

    double alt_max = 0;
    for(size_t j=0;j<alt_points.size();j++){
      alt_max = std::max(alt_max,alt_points[j]);
    }        
    TH1* alt_hist  = new TH1F("hist1","hist1",100,0.,1.1*alt_max);
    alt_hist->SetDirectory(0);
    for(size_t j=0;j<alt_points.size();j++){
      alt_hist->Fill(alt_points[j]);
    }

    int alt_peaks = TQHistogramUtils::purgePeaks1D(alt_hist,ratio,0);
    std::cout << "fixed " << alt_peaks << " spikes!" << std::endl;

    double null_max = 0;
    for(size_t j=0;j<null_points.size();j++){
      null_max = std::max(null_max,null_points[j]);
    }    
    TH1* null_hist = new TH1F("hist0","hist0",100,0.,1.1*null_max);
    null_hist->SetDirectory(0);
    for(size_t j=0;j<null_points.size();j++){
      null_hist->Fill(null_points[j]); 
    }

    TQHistogramUtils::purgePeaks1D(null_hist,ratio,0);

    double epsilon = 1e-9;
    for(size_t j=0;j<alt_points.size();j++){
      if(alt_points[j]<0 || alt_hist->GetBinContent(alt_hist->FindBin(alt_points[j])) < epsilon){
	nfailed++;
	continue;
      }
      new_alt_points.push_back(alt_points[j]);
      new_alt_weights.push_back(alt_weights[j]);
    }
	
    for(size_t j=0;j<null_points.size();j++){
      if(null_points[j]<0 || null_hist->GetBinContent(null_hist->FindBin(null_points[j])) < epsilon){
	nfailed++;
	continue;
      }
      new_null_points.push_back(null_points[j]);
      new_null_weights.push_back(null_weights[j]);
    }

    delete alt_hist;
    delete null_hist;	
	
    result->SetAltDistribution(new RooStats::SamplingDistribution("new_alt","new_alt",new_alt_points,new_alt_weights));
    result->SetNullDistribution(new RooStats::SamplingDistribution("new_null","new_null",new_null_points,new_null_weights));
  }
  return nfailed;
}



RooStats::HypoTestInverterResult* TSUtils::collectToyLimits(const std::vector<std::string>& filenames,const char* limitname, const char* resultname){
  RooStats::HypoTestInverterResult* allresults = 0;
  for(const auto& fname : filenames){
    TString err;
    
    TQFolder* toyset = TQFolder::loadFolder(fname,err);
    if(!toyset){
      std::cout << (TString::Format("unable to load file '%s': %s",fname.c_str(),err.Data())) << std::endl;
      continue;
    } 
    TString path(TQFolder::concatPaths(limitname,"results"));
    TQFolder* limit = toyset->getFolder(path);
    if(!limit){
      std::cout << TString::Format("cannot find limit at '%s'",path.Data());
      continue;
    }
    RooStats::HypoTestInverterResult* hypores = (RooStats::HypoTestInverterResult*) limit->getObject(resultname);
    if(!hypores){
      std::cout << TString::Format("cannot find limit result named '%s'",resultname) << std::endl;
      continue;
    }
    if(!allresults){
      allresults = (RooStats::HypoTestInverterResult*)hypores->Clone();
    }
    else allresults->Add(*hypores);
    delete toyset;
  }

  TSUtils::fixToys(allresults);
  allresults->ExclusionCleanup();
  
  return allresults;
}


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