#include "QFramework/TQAlgorithm.h"
#include "QFramework/TQSample.h"
#include "QFramework/TQSampleFolder.h"
#include "QFramework/TQObservable.h"
#include "TTree.h"

#include "QFramework/TQLibrary.h"

////////////////////////////////////////////////////////////////////////////////////////////////
//
// TQAlgorithm
//
// The TQAlgorithm class is a hook in order to precompute arbitrary
// event-based quantities and cache their values. The entire list of
// algorithms is executed on every event.
//
// every algorithm should implement the initialize, finalize and execute and cleanup methods.
// initialize will be called at the beginning of every sample and will take the sample as an argument
// finalize, execute and cleanup will not receive arguments and are called
// at the end of each sample (finalize), before each event (execute) and after each 
// event (cleanup).
// All four functions should return true in case of success, false in case of failure
// failure of any algorithm will cause the event loop to halt,
// additional error handling may be done by raising exceptions.
//
// All input/output managing is entirely up to the user and may be
// done via filling the TStore, creating decorations to objects in
// the TEvent or any other available operation.
//
// Please note that for use of TQAlgorithms with the TQMultiChannelAnalysisSampleVisitor
// must be streamable, i.e., correctly work with the TObject::Clone() method. This implies
// that all transient members (typically marked with the '//!' suffix in the header file)
// must be set in the 'TQAlgorithm::initialize(TQSample* s)' method! This also applies to 
// TQAlgorithms which are supposedly singletons (i.e. returning 'true' in TQAlgorithm::isSingleton())
// for which 'TQAlgorithm::initializeSingleton(const std::vector<TQSample*>& samples)' should 
// take the place of 'initialize(TQSample* s)'.
// If an implementation of an algorithm is marked as a singleton but should still be useable
// with SCASV as well as MCASV (or similar classes) BOTH initialization methods must be
// overridden!
//
////////////////////////////////////////////////////////////////////////////////////////////////

bool TQAlgorithm::Manager::addAlgorithm(TQAlgorithm* newAlgorithm){
  // add a new cache
  // the function takes ownership of the object, you shall not delete it!
  for(size_t i=0; i<this->gAlgorithmList.size(); ++i){
    if(TQStringUtils::equal(gAlgorithmList[i]->GetName(),newAlgorithm->GetName())){
      return false;
    }
  }
  this->gAlgorithmList.push_back(newAlgorithm);
  return true;
}

void TQAlgorithm::Manager::clearAlgorithms(){
  // clear the list of caches, deleting every one of them
  for(size_t i=0; i< this->gAlgorithmList.size(); ++i){
    delete this->gAlgorithmList[i];
  }
  this->gAlgorithmList.clear();
}

void TQAlgorithm::Manager::clearClonedAlgorithms() {
  // clear the list (of lists) of active caches, deleting every one of them
  for (auto& origAlgAndSubMapPair: this->gAlgorithmStore) {
    for (auto& stringAndClonedAlgPair : origAlgAndSubMapPair.second) {
      delete stringAndClonedAlgPair.second;
    }
    origAlgAndSubMapPair.second.clear();
  }
  this->gAlgorithmStore.clear();
}

const std::vector<TQAlgorithm*>& TQAlgorithm::Manager::getAlgorithms(){
  // retrieve a const reference to the list of all caches
  return this->gAlgorithmList;
}


void TQAlgorithm::Manager::printAlgorithms() const {
	// print the list of all currently registered algorithms
  std::cout<<"Registered algorithms:"<<std::endl;
  for (TQAlgorithm* const& alg : gAlgorithmList) {
    std::cout<<"  "<<(alg?alg->GetName():"NULL")<<std::endl;
  }
}

void TQAlgorithm::Manager::printActiveAlgorithms() const {
	// print the list of all currently active algorithms
  std::cout<<"Active algorithms:"<<std::endl;
  for (TQAlgorithm* const& alg : gActiveAlgorithms) {
    std::cout<<"  "<<(alg?alg->GetName():"NULL")<<std::endl;
  }
}
/*
bool TQAlgorithm::Manager::cloneAlgorithms(int n) {
  // create n clones of each cache unless the cache is a singleton (in which case only one clone is created)
  if (this->gClonedAlgorithmList.size() != 0) {
    WARNfunc("The list of cloned algorithms is not empty. Will implicitly call TQAlgorithm::Manager::clearClonedAlgorithms() before creating a fresh set of clones! Please consider performing this call explicitly before requesting a new set of clones to be created.");
    this->clearClonedAlgorithms();
  }
  for (const auto& origAlg: this->gAlgorithmList) {
    this->gClonedAlgorithmList.push_back(std::vector<TQAlgorithm*>());
    const size_t index = this->gClonedAlgorithmList.size()-1;
    if (origAlg->isSingleton()) { //single clone if algorithm should run once per event
      this->gClonedAlgorithmList[index].push_back( static_cast<TQAlgorithm*>( origAlg->Clone() ) );
    } else {
      for (int i=0;i<n;++i) { //n clones if n instances of the algorithm should run per event (typically n channels)
        this->gClonedAlgorithmList[index].push_back( static_cast<TQAlgorithm*>( origAlg->Clone() ) );
      }
    }
  }
  return true;
  
}
*/

TQAlgorithm* TQAlgorithm::getClone() const {
  // retrieve a clone of this algorithm
  return static_cast<TQAlgorithm*>( this->Clone() );
}

bool TQAlgorithm::Manager::initializeAlgorithms(TQSample*s){
  // initialize all algorithms
  for(size_t i=0; i<this->gAlgorithmList.size(); ++i){
    if(!this->gAlgorithmList[i]->initialize(s)) return false;
  }
  return true;
}

bool TQAlgorithm::Manager::initializeAlgorithms(TQSampleFolder*s){
  // initialize all algorithms
  for(size_t i=0; i<this->gAlgorithmList.size(); ++i){
    if(!this->gAlgorithmList[i]->initializeSampleFolder(s)) return false;
  }
  return true;
}

void TQAlgorithm::Manager::resetActiveAlgorithms() {
	// clear the list of currently active algorithms
  gActiveAlgorithms.clear();
}

namespace {
  template<class T> bool initAlg(TQAlgorithm* alg, T* obj);
  template<> bool initAlg<TQSample>(TQAlgorithm* alg, TQSample* obj){
    return alg->initialize(obj);
  }
  template<> bool initAlg<TQSampleFolder>(TQAlgorithm* alg, TQSampleFolder* obj){
    return alg->initializeSampleFolder(obj);
  }
  template<class T> bool initAlgSingleton(TQAlgorithm* alg, std::vector<T*>& obj);  
  template<> bool initAlgSingleton<TQSample>(TQAlgorithm* alg, std::vector<TQSample*>& obj){
    return alg->initializeSingleton(obj);
  }
  template<> bool initAlgSingleton<TQSampleFolder>(TQAlgorithm* alg, std::vector<TQSampleFolder*>& obj){
    return alg->initializeSampleFolderSingleton(obj);
  }
  template<class T> bool finAlg(TQAlgorithm* alg, T* obj);
  template<> bool finAlg<TQSample>(TQAlgorithm* alg, TQSample*/*obj*/){
    return alg->finalize();
  }
  template<> bool finAlg<TQSampleFolder>(TQAlgorithm* alg, TQSampleFolder* obj){
    return alg->finalizeSampleFolder(obj);
  }
  template<class T> bool finAlgSingleton(TQAlgorithm* alg, std::vector<T*>& obj);  
  template<> bool finAlgSingleton<TQSample>(TQAlgorithm* alg, std::vector<TQSample*>&/* obj*/){
    return alg->finalizeSingleton();
  }
  template<> bool finAlgSingleton<TQSampleFolder>(TQAlgorithm* alg, std::vector<TQSampleFolder*>& obj){
    return alg->finalizeSampleFolderSingleton(obj);
  }  
}

bool TQAlgorithm::Manager::isActiveAlgorithm(const TQAlgorithm* alg) const {
  for (const TQAlgorithm* ref : this->gActiveAlgorithms) {
    if (ref==alg) return true;
  }
  return false;
}

template <class T> std::map<TQAlgorithm*,T*> TQAlgorithm::Manager::getAlgorithmToSampleFolderMap(const std::vector<T*>& samples, const TString& tagKey) {
  
  std::map<TQAlgorithm*, T*> algMap;
  for (auto* s: samples) {
    TString key;
    if (!s->getTagString(tagKey,key)) { continue; } //TODO: is this the right treatment? we simply ignore SampleFolders which are, e.g., not yet split in channels?
    //note that skipping here implies that we will not finalize algs on such SampleFolders...
    for (const auto& origToChannels : this->gAlgorithmStore) {
      if (origToChannels.second.count(key)>0) {
        algMap[origToChannels.second.at(key)] = s;
      }
    }
  }
  return algMap;
}

template std::map<TQAlgorithm*,TQSample*> TQAlgorithm::Manager::getAlgorithmToSampleFolderMap<TQSample>(const std::vector<TQSample*> & samples, const TString& tagKey);
template std::map<TQAlgorithm*,TQSampleFolder*> TQAlgorithm::Manager::getAlgorithmToSampleFolderMap<TQSampleFolder>(const std::vector<TQSampleFolder*> & samples, const TString& tagKey);


template<class T> bool TQAlgorithm::Manager::finalizeClonedAlgorithms(std::vector<T*> & samples, const TString& tagKey){
  // finalize all algorithms (multi-channel variant)
  
  //step 1: finalize all singleton algorithms (which are not cloned)
  for (TQAlgorithm*const & alg : gActiveAlgorithms) {
    if(alg->isSingleton()){
      finAlgSingleton(alg,samples);
    } else {
      continue;
      //for(auto s:samples){
      //  finAlg(alg,s); //This is wrong!  each algo should only be finalized for the suitable sample(Folder)
      //}
    }
  }
  //step 2: finalize all cloned algoriths. For this we need to on-the-fly create the correct mapping of Algorithms to Sample(Folder)s
  std::map<TQAlgorithm*,T*> algMap = this->getAlgorithmToSampleFolderMap(samples, tagKey);
  for (const auto& algSF: algMap) {
    if (algSF.first->isSingleton()) continue; //just to make sure we don't accidentially include a singleton alg here...
    finAlg(algSF.first,algSF.second);
  }
  //TODO: return a more meaningful value here
  return true;
}

template bool TQAlgorithm::Manager::finalizeClonedAlgorithms<TQSample>(std::vector<TQSample*> & samples, const TString& tagKey);
template bool TQAlgorithm::Manager::finalizeClonedAlgorithms<TQSampleFolder>(std::vector<TQSampleFolder*> & samples, const TString& tagKey);

template<class T> bool TQAlgorithm::Manager::initializeClonedAlgorithms(std::vector<T*> & samples, const TString& tagKey, bool switchObservableSets){
  // initialize all already cloned or to-be-cloned algorithms (multi-channel variant)
  // creates clones of original algorithms if needed.
  this->resetActiveAlgorithms();
  
  for (TQAlgorithm* & origAlg: this->gAlgorithmList) {
    if (!origAlg) continue;
    if (origAlg->isSingleton()) {
      //the simple case, we just add it to the active algorithms and initialize it on all (active) samples at once
      if (!initAlgSingleton(origAlg,samples)) {
        throw std::runtime_error(TString::Format("Failed to initialize algorithm '%s' as singleton",origAlg->GetName()).Data());
        return false;
      }
      gActiveAlgorithms.push_back(origAlg);
      continue;//we're done with this algorithm for now
    }
    
    if (gAlgorithmStore.count(origAlg) == 0) {//there are no clones at all yet for this algorithm (and it's not a singleton)
      std::map<TString,TQAlgorithm*> algMap;
      for ( auto s  : samples) { //we had nothing before so we need to create the whole structure for each sample we are provided with
        TString key;
        if (!s->getTagString(tagKey,key)) {//cannot identify channel -> error (wouldn't know where to store it)
          throw std::runtime_error(TString::Format("Could not obtain channel identifier from sample '%s' using key '%s'",s->getPath().Data(), tagKey.Data()).Data());
          return false;
        }
        //make sure the algorithm uses the correct (active) observable set if needed. The "key" is the channel. Note that lazy evaluation prevents the switch from happening here if not requested
        if(switchObservableSets && !TQObservable::manager.setActiveSet(key)){
          TQObservable::manager.cloneActiveSet(key);
        }

        //clone origAlg, initialize clone and add to map and active algorithms
        TQAlgorithm* clone = origAlg->getClone();
        bool initSuccess = initAlg(clone,s);
        algMap[key] = clone; 
        gActiveAlgorithms.push_back(clone); //ownership belongs to algMap!
        if (!initSuccess) {
          ERRORclass("Failed to initialize algorithm '%s' on Sample(Folder)",origAlg->GetName(), s->getPath().Data());
          return false;
        }
      }
      //add algMap to gAlgorithmStore 
      gAlgorithmStore[origAlg] = algMap;
    } else {//there are already at least some clones of this algorithm, let's re-use them where possible
      std::map<TString,TQAlgorithm*>& algMap = gAlgorithmStore[origAlg]; 
      for ( auto s : samples) {
        TString key;
        if (!s->getTagString(tagKey,key)) {//cannot identify channel -> error (wouldn't know where to look for/store clones of the algorithm)
          throw std::runtime_error(TString::Format("Could not obtain channel identifier from sample '%s' using key '%s'",s->getPath().Data(), tagKey.Data()).Data());
          return false;
        }
        //make sure the algorithm uses the correct (active) observable set if needed. The "key" is the channel. Note that lazy evaluation prevents the switch from happening here if not requested
        if(switchObservableSets && !TQObservable::manager.setActiveSet(key)){
          TQObservable::manager.cloneActiveSet(key);
        }
        
        bool initSuccess = false;
        if (algMap.count(key) == 0) { //for this particular channel no clone exists yet
          TQAlgorithm* clone = origAlg->getClone();
          initSuccess = initAlg(clone,s);
          algMap[key] = clone; 
          gActiveAlgorithms.push_back(clone); //ownership belongs to algMap!
        } else { //there is already a clone for this channel, we use it
          TQAlgorithm* clone = algMap[key];
          initSuccess = initAlg(clone,s);
          gActiveAlgorithms.push_back(clone);
        }
        if (!initSuccess) {
            ERRORclass("Failed to initialize algorithm '%s' on Sample(Folder)",origAlg->GetName(), s->getPath().Data());
            return false;
        }
      }
      
    }
    
  }
  
  /*
  for(const std::vector<TQAlgorithm*>& clones : this->gClonedAlgorithmList){
    if (clones.size()==1  && clones[0]->isSingleton()) {
      if (!clones[0]->initializeSingleton(samples)) return false; //initialize singleton algorithm with list of all samples
    } else if (clones.size()==samples.size()) {
      //everything should be fine now, let's actually initialize the algorithms
      for (size_t i=0;i<clones.size();++i) {
        if (!clones[i]->initialize(samples[i]) ) return false;
      }
    } else { //we neither have a singleton algorithm nor does the number of clones match the number of samples -> ERROR
      ERRORclass("Failed to initialize cloned algorithms: number of clones differs from number of TQSamples provided!");
      return false;
    }
  }
  */
  return true;
} //end initializeClonedAlgorithms

template bool TQAlgorithm::Manager::initializeClonedAlgorithms<TQSample>(std::vector<TQSample*> & samples, const TString& tagKey, bool switchObservableSets);
template bool TQAlgorithm::Manager::initializeClonedAlgorithms<TQSampleFolder>(std::vector<TQSampleFolder*> & samples, const TString& tagKey, bool switchObservableSets);


bool TQAlgorithm::Manager::finalizeAlgorithms(){
  // finalize all algorithms
    for (const auto& alg : gAlgorithmList) {
      if (!alg->finalize()) return false;
    }
  return true;
}

bool TQAlgorithm::Manager::finalizeAlgorithmsSampleFolder(TQSampleFolder* sf){
  // finalize all algorithms
  for (const auto& alg : gAlgorithmList) {
    if (!alg->finalizeSampleFolder(sf)) return false;
    }
  return true;
}

bool TQAlgorithm::Manager::executeAlgorithms(){
  // execute all algorithms
  //for(size_t i=0; i<this->gAlgorithmList.size(); ++i){
    for (const auto& alg : gAlgorithmList) {
      if (!alg->execute()) return false;
    }
    //if(! this->gAlgorithmList[i]->execute()) return false;
  return true;
}

bool TQAlgorithm::Manager::executeClonedAlgorithms(){
  // execute all algorithms (multi-channel variant)
  for (TQAlgorithm* const & alg : gActiveAlgorithms) {
    if (!alg->execute()) return false;
  }
  return true;
}

bool TQAlgorithm::Manager::cleanupAlgorithms(){
  // cleanup all algorithms (multi channel variant)
  // post event method
    for (TQAlgorithm* const & alg : gAlgorithmList) {
      if (!alg->cleanup()) return false;
  }
  return true;
}

bool TQAlgorithm::Manager::cleanupClonedAlgorithms(){
  // cleanup all algorithms (multi channel variant)
  // post event method
  // actually a stupid name
  for ( TQAlgorithm* const & alg : gActiveAlgorithms) {
      if (!alg->cleanup()) return false;
    }
  return true;
}

//========================================================
//========================================================

bool TQAlgorithm::isSingleton() const {
  // return true if this algorithm is a singleton, false otherwise
  return false;
}

bool TQAlgorithm::finalizeSingleton(){
  // default implementation: call "old-style" finalize() method
  this->finalize();
  return true;  
}

bool TQAlgorithm::finalizeSampleFolderSingleton(const std::vector<TQSampleFolder*>& /*samples*/) { 
  // default implementation: do nothing
  return true;  
}

bool TQAlgorithm::initializeSingleton(const std::vector<TQSample*>& /*samples*/) { //parameter not used in baseClass implementation
  // default implementations simply report an error, it is the responsibility of the author of the derived class to implement at least one of these
  ERRORclass("initialization with a list of samples is not implemented for TQAlgorithm with name '%s'!", this->GetName());
  return false;
}

bool TQAlgorithm::initialize(TQSample* /*s*/) { //parameter not used in baseClass implementation
  // default implementations simply report an error, it is the responsibility of the author of the derived class to implement at least one of these
  ERRORclass("initialization with single TQSample is not implemented for TQAlgorithm with name '%s'!",this->GetName());
  return false;
}

bool TQAlgorithm::initializeSampleFolderSingleton(const std::vector<TQSampleFolder*>& /*samples*/) {
  // default implementation: do nothing
  return true;  
}
bool TQAlgorithm::initializeSampleFolder(TQSampleFolder* /*s*/) {
  // default implementation: do nothing
  return true;  
}
bool TQAlgorithm::finalizeSampleFolder(TQSampleFolder* /*sf*/){
  // default implementation: do nothing
  return true;  
}
 TQAlgorithm.cxx:1
 TQAlgorithm.cxx:2
 TQAlgorithm.cxx:3
 TQAlgorithm.cxx:4
 TQAlgorithm.cxx:5
 TQAlgorithm.cxx:6
 TQAlgorithm.cxx:7
 TQAlgorithm.cxx:8
 TQAlgorithm.cxx:9
 TQAlgorithm.cxx:10
 TQAlgorithm.cxx:11
 TQAlgorithm.cxx:12
 TQAlgorithm.cxx:13
 TQAlgorithm.cxx:14
 TQAlgorithm.cxx:15
 TQAlgorithm.cxx:16
 TQAlgorithm.cxx:17
 TQAlgorithm.cxx:18
 TQAlgorithm.cxx:19
 TQAlgorithm.cxx:20
 TQAlgorithm.cxx:21
 TQAlgorithm.cxx:22
 TQAlgorithm.cxx:23
 TQAlgorithm.cxx:24
 TQAlgorithm.cxx:25
 TQAlgorithm.cxx:26
 TQAlgorithm.cxx:27
 TQAlgorithm.cxx:28
 TQAlgorithm.cxx:29
 TQAlgorithm.cxx:30
 TQAlgorithm.cxx:31
 TQAlgorithm.cxx:32
 TQAlgorithm.cxx:33
 TQAlgorithm.cxx:34
 TQAlgorithm.cxx:35
 TQAlgorithm.cxx:36
 TQAlgorithm.cxx:37
 TQAlgorithm.cxx:38
 TQAlgorithm.cxx:39
 TQAlgorithm.cxx:40
 TQAlgorithm.cxx:41
 TQAlgorithm.cxx:42
 TQAlgorithm.cxx:43
 TQAlgorithm.cxx:44
 TQAlgorithm.cxx:45
 TQAlgorithm.cxx:46
 TQAlgorithm.cxx:47
 TQAlgorithm.cxx:48
 TQAlgorithm.cxx:49
 TQAlgorithm.cxx:50
 TQAlgorithm.cxx:51
 TQAlgorithm.cxx:52
 TQAlgorithm.cxx:53
 TQAlgorithm.cxx:54
 TQAlgorithm.cxx:55
 TQAlgorithm.cxx:56
 TQAlgorithm.cxx:57
 TQAlgorithm.cxx:58
 TQAlgorithm.cxx:59
 TQAlgorithm.cxx:60
 TQAlgorithm.cxx:61
 TQAlgorithm.cxx:62
 TQAlgorithm.cxx:63
 TQAlgorithm.cxx:64
 TQAlgorithm.cxx:65
 TQAlgorithm.cxx:66
 TQAlgorithm.cxx:67
 TQAlgorithm.cxx:68
 TQAlgorithm.cxx:69
 TQAlgorithm.cxx:70
 TQAlgorithm.cxx:71
 TQAlgorithm.cxx:72
 TQAlgorithm.cxx:73
 TQAlgorithm.cxx:74
 TQAlgorithm.cxx:75
 TQAlgorithm.cxx:76
 TQAlgorithm.cxx:77
 TQAlgorithm.cxx:78
 TQAlgorithm.cxx:79
 TQAlgorithm.cxx:80
 TQAlgorithm.cxx:81
 TQAlgorithm.cxx:82
 TQAlgorithm.cxx:83
 TQAlgorithm.cxx:84
 TQAlgorithm.cxx:85
 TQAlgorithm.cxx:86
 TQAlgorithm.cxx:87
 TQAlgorithm.cxx:88
 TQAlgorithm.cxx:89
 TQAlgorithm.cxx:90
 TQAlgorithm.cxx:91
 TQAlgorithm.cxx:92
 TQAlgorithm.cxx:93
 TQAlgorithm.cxx:94
 TQAlgorithm.cxx:95
 TQAlgorithm.cxx:96
 TQAlgorithm.cxx:97
 TQAlgorithm.cxx:98
 TQAlgorithm.cxx:99
 TQAlgorithm.cxx:100
 TQAlgorithm.cxx:101
 TQAlgorithm.cxx:102
 TQAlgorithm.cxx:103
 TQAlgorithm.cxx:104
 TQAlgorithm.cxx:105
 TQAlgorithm.cxx:106
 TQAlgorithm.cxx:107
 TQAlgorithm.cxx:108
 TQAlgorithm.cxx:109
 TQAlgorithm.cxx:110
 TQAlgorithm.cxx:111
 TQAlgorithm.cxx:112
 TQAlgorithm.cxx:113
 TQAlgorithm.cxx:114
 TQAlgorithm.cxx:115
 TQAlgorithm.cxx:116
 TQAlgorithm.cxx:117
 TQAlgorithm.cxx:118
 TQAlgorithm.cxx:119
 TQAlgorithm.cxx:120
 TQAlgorithm.cxx:121
 TQAlgorithm.cxx:122
 TQAlgorithm.cxx:123
 TQAlgorithm.cxx:124
 TQAlgorithm.cxx:125
 TQAlgorithm.cxx:126
 TQAlgorithm.cxx:127
 TQAlgorithm.cxx:128
 TQAlgorithm.cxx:129
 TQAlgorithm.cxx:130
 TQAlgorithm.cxx:131
 TQAlgorithm.cxx:132
 TQAlgorithm.cxx:133
 TQAlgorithm.cxx:134
 TQAlgorithm.cxx:135
 TQAlgorithm.cxx:136
 TQAlgorithm.cxx:137
 TQAlgorithm.cxx:138
 TQAlgorithm.cxx:139
 TQAlgorithm.cxx:140
 TQAlgorithm.cxx:141
 TQAlgorithm.cxx:142
 TQAlgorithm.cxx:143
 TQAlgorithm.cxx:144
 TQAlgorithm.cxx:145
 TQAlgorithm.cxx:146
 TQAlgorithm.cxx:147
 TQAlgorithm.cxx:148
 TQAlgorithm.cxx:149
 TQAlgorithm.cxx:150
 TQAlgorithm.cxx:151
 TQAlgorithm.cxx:152
 TQAlgorithm.cxx:153
 TQAlgorithm.cxx:154
 TQAlgorithm.cxx:155
 TQAlgorithm.cxx:156
 TQAlgorithm.cxx:157
 TQAlgorithm.cxx:158
 TQAlgorithm.cxx:159
 TQAlgorithm.cxx:160
 TQAlgorithm.cxx:161
 TQAlgorithm.cxx:162
 TQAlgorithm.cxx:163
 TQAlgorithm.cxx:164
 TQAlgorithm.cxx:165
 TQAlgorithm.cxx:166
 TQAlgorithm.cxx:167
 TQAlgorithm.cxx:168
 TQAlgorithm.cxx:169
 TQAlgorithm.cxx:170
 TQAlgorithm.cxx:171
 TQAlgorithm.cxx:172
 TQAlgorithm.cxx:173
 TQAlgorithm.cxx:174
 TQAlgorithm.cxx:175
 TQAlgorithm.cxx:176
 TQAlgorithm.cxx:177
 TQAlgorithm.cxx:178
 TQAlgorithm.cxx:179
 TQAlgorithm.cxx:180
 TQAlgorithm.cxx:181
 TQAlgorithm.cxx:182
 TQAlgorithm.cxx:183
 TQAlgorithm.cxx:184
 TQAlgorithm.cxx:185
 TQAlgorithm.cxx:186
 TQAlgorithm.cxx:187
 TQAlgorithm.cxx:188
 TQAlgorithm.cxx:189
 TQAlgorithm.cxx:190
 TQAlgorithm.cxx:191
 TQAlgorithm.cxx:192
 TQAlgorithm.cxx:193
 TQAlgorithm.cxx:194
 TQAlgorithm.cxx:195
 TQAlgorithm.cxx:196
 TQAlgorithm.cxx:197
 TQAlgorithm.cxx:198
 TQAlgorithm.cxx:199
 TQAlgorithm.cxx:200
 TQAlgorithm.cxx:201
 TQAlgorithm.cxx:202
 TQAlgorithm.cxx:203
 TQAlgorithm.cxx:204
 TQAlgorithm.cxx:205
 TQAlgorithm.cxx:206
 TQAlgorithm.cxx:207
 TQAlgorithm.cxx:208
 TQAlgorithm.cxx:209
 TQAlgorithm.cxx:210
 TQAlgorithm.cxx:211
 TQAlgorithm.cxx:212
 TQAlgorithm.cxx:213
 TQAlgorithm.cxx:214
 TQAlgorithm.cxx:215
 TQAlgorithm.cxx:216
 TQAlgorithm.cxx:217
 TQAlgorithm.cxx:218
 TQAlgorithm.cxx:219
 TQAlgorithm.cxx:220
 TQAlgorithm.cxx:221
 TQAlgorithm.cxx:222
 TQAlgorithm.cxx:223
 TQAlgorithm.cxx:224
 TQAlgorithm.cxx:225
 TQAlgorithm.cxx:226
 TQAlgorithm.cxx:227
 TQAlgorithm.cxx:228
 TQAlgorithm.cxx:229
 TQAlgorithm.cxx:230
 TQAlgorithm.cxx:231
 TQAlgorithm.cxx:232
 TQAlgorithm.cxx:233
 TQAlgorithm.cxx:234
 TQAlgorithm.cxx:235
 TQAlgorithm.cxx:236
 TQAlgorithm.cxx:237
 TQAlgorithm.cxx:238
 TQAlgorithm.cxx:239
 TQAlgorithm.cxx:240
 TQAlgorithm.cxx:241
 TQAlgorithm.cxx:242
 TQAlgorithm.cxx:243
 TQAlgorithm.cxx:244
 TQAlgorithm.cxx:245
 TQAlgorithm.cxx:246
 TQAlgorithm.cxx:247
 TQAlgorithm.cxx:248
 TQAlgorithm.cxx:249
 TQAlgorithm.cxx:250
 TQAlgorithm.cxx:251
 TQAlgorithm.cxx:252
 TQAlgorithm.cxx:253
 TQAlgorithm.cxx:254
 TQAlgorithm.cxx:255
 TQAlgorithm.cxx:256
 TQAlgorithm.cxx:257
 TQAlgorithm.cxx:258
 TQAlgorithm.cxx:259
 TQAlgorithm.cxx:260
 TQAlgorithm.cxx:261
 TQAlgorithm.cxx:262
 TQAlgorithm.cxx:263
 TQAlgorithm.cxx:264
 TQAlgorithm.cxx:265
 TQAlgorithm.cxx:266
 TQAlgorithm.cxx:267
 TQAlgorithm.cxx:268
 TQAlgorithm.cxx:269
 TQAlgorithm.cxx:270
 TQAlgorithm.cxx:271
 TQAlgorithm.cxx:272
 TQAlgorithm.cxx:273
 TQAlgorithm.cxx:274
 TQAlgorithm.cxx:275
 TQAlgorithm.cxx:276
 TQAlgorithm.cxx:277
 TQAlgorithm.cxx:278
 TQAlgorithm.cxx:279
 TQAlgorithm.cxx:280
 TQAlgorithm.cxx:281
 TQAlgorithm.cxx:282
 TQAlgorithm.cxx:283
 TQAlgorithm.cxx:284
 TQAlgorithm.cxx:285
 TQAlgorithm.cxx:286
 TQAlgorithm.cxx:287
 TQAlgorithm.cxx:288
 TQAlgorithm.cxx:289
 TQAlgorithm.cxx:290
 TQAlgorithm.cxx:291
 TQAlgorithm.cxx:292
 TQAlgorithm.cxx:293
 TQAlgorithm.cxx:294
 TQAlgorithm.cxx:295
 TQAlgorithm.cxx:296
 TQAlgorithm.cxx:297
 TQAlgorithm.cxx:298
 TQAlgorithm.cxx:299
 TQAlgorithm.cxx:300
 TQAlgorithm.cxx:301
 TQAlgorithm.cxx:302
 TQAlgorithm.cxx:303
 TQAlgorithm.cxx:304
 TQAlgorithm.cxx:305
 TQAlgorithm.cxx:306
 TQAlgorithm.cxx:307
 TQAlgorithm.cxx:308
 TQAlgorithm.cxx:309
 TQAlgorithm.cxx:310
 TQAlgorithm.cxx:311
 TQAlgorithm.cxx:312
 TQAlgorithm.cxx:313
 TQAlgorithm.cxx:314
 TQAlgorithm.cxx:315
 TQAlgorithm.cxx:316
 TQAlgorithm.cxx:317
 TQAlgorithm.cxx:318
 TQAlgorithm.cxx:319
 TQAlgorithm.cxx:320
 TQAlgorithm.cxx:321
 TQAlgorithm.cxx:322
 TQAlgorithm.cxx:323
 TQAlgorithm.cxx:324
 TQAlgorithm.cxx:325
 TQAlgorithm.cxx:326
 TQAlgorithm.cxx:327
 TQAlgorithm.cxx:328
 TQAlgorithm.cxx:329
 TQAlgorithm.cxx:330
 TQAlgorithm.cxx:331
 TQAlgorithm.cxx:332
 TQAlgorithm.cxx:333
 TQAlgorithm.cxx:334
 TQAlgorithm.cxx:335
 TQAlgorithm.cxx:336
 TQAlgorithm.cxx:337
 TQAlgorithm.cxx:338
 TQAlgorithm.cxx:339
 TQAlgorithm.cxx:340
 TQAlgorithm.cxx:341
 TQAlgorithm.cxx:342
 TQAlgorithm.cxx:343
 TQAlgorithm.cxx:344
 TQAlgorithm.cxx:345
 TQAlgorithm.cxx:346
 TQAlgorithm.cxx:347
 TQAlgorithm.cxx:348
 TQAlgorithm.cxx:349
 TQAlgorithm.cxx:350
 TQAlgorithm.cxx:351
 TQAlgorithm.cxx:352
 TQAlgorithm.cxx:353
 TQAlgorithm.cxx:354
 TQAlgorithm.cxx:355
 TQAlgorithm.cxx:356
 TQAlgorithm.cxx:357
 TQAlgorithm.cxx:358
 TQAlgorithm.cxx:359
 TQAlgorithm.cxx:360
 TQAlgorithm.cxx:361
 TQAlgorithm.cxx:362
 TQAlgorithm.cxx:363
 TQAlgorithm.cxx:364
 TQAlgorithm.cxx:365
 TQAlgorithm.cxx:366
 TQAlgorithm.cxx:367
 TQAlgorithm.cxx:368
 TQAlgorithm.cxx:369
 TQAlgorithm.cxx:370
 TQAlgorithm.cxx:371
 TQAlgorithm.cxx:372
 TQAlgorithm.cxx:373
 TQAlgorithm.cxx:374
 TQAlgorithm.cxx:375
 TQAlgorithm.cxx:376
 TQAlgorithm.cxx:377
 TQAlgorithm.cxx:378
 TQAlgorithm.cxx:379
 TQAlgorithm.cxx:380
 TQAlgorithm.cxx:381
 TQAlgorithm.cxx:382
 TQAlgorithm.cxx:383
 TQAlgorithm.cxx:384
 TQAlgorithm.cxx:385
 TQAlgorithm.cxx:386
 TQAlgorithm.cxx:387
 TQAlgorithm.cxx:388
 TQAlgorithm.cxx:389
 TQAlgorithm.cxx:390
 TQAlgorithm.cxx:391
 TQAlgorithm.cxx:392
 TQAlgorithm.cxx:393
 TQAlgorithm.cxx:394
 TQAlgorithm.cxx:395
 TQAlgorithm.cxx:396
 TQAlgorithm.cxx:397
 TQAlgorithm.cxx:398
 TQAlgorithm.cxx:399
 TQAlgorithm.cxx:400
 TQAlgorithm.cxx:401
 TQAlgorithm.cxx:402
 TQAlgorithm.cxx:403
 TQAlgorithm.cxx:404
 TQAlgorithm.cxx:405
 TQAlgorithm.cxx:406
 TQAlgorithm.cxx:407
 TQAlgorithm.cxx:408
 TQAlgorithm.cxx:409
 TQAlgorithm.cxx:410
 TQAlgorithm.cxx:411
 TQAlgorithm.cxx:412
 TQAlgorithm.cxx:413
 TQAlgorithm.cxx:414
 TQAlgorithm.cxx:415
 TQAlgorithm.cxx:416
 TQAlgorithm.cxx:417
 TQAlgorithm.cxx:418
 TQAlgorithm.cxx:419
 TQAlgorithm.cxx:420
 TQAlgorithm.cxx:421
 TQAlgorithm.cxx:422