#include "QFramework/TQFilterObservable.h"

#include <limits>
#include <vector>
#include "TTreeFormula.h"
#include "TString.h"

#include "QFramework/TQSample.h"
#include "QFramework/TQStringUtils.h"
#include "QFramework/TQUtils.h"

// uncomment the following line to enable debug printouts
//#define _DEBUG_
// you can perform debug printouts with statements like this
// DEBUG("error number %d occurred",someInteger);

// be careful to not move the _DEBUG_ flag behind the following line
// otherwise, it will show no effect
#include "QFramework/TQLibrary.h"

////////////////////////////////////////////////////////////////////////////////////////////////
//
// TQFilterObservable
//
// TODO: write documentation
//
////////////////////////////////////////////////////////////////////////////////////////////////

/*@observable: [TQFilterObservable] The TQFilterObservable can be used to filter the entrie(s) of a
    vector or scalar Observable. As the result of applying such a filter is in general of variying length 
    (varying number of entries) the FilterObservable itself is a vector Observable (i.e. it cannot be 
    used in cuts/event selection). The FilterObservable is automatically created and contains two 
    subobservables. Its creation is triggered by expressions of the form 
    'Filter(subExpressionValue, subExpressionCondition)'. The 'subExpressionValue' corresponds to the 
    Subobservable providing the values the FilterObservable possibly provides. It will, however, only 
    provide these values of the first subobservable where the corresponding entry of the condition
    Subobservable evaluates to true (= non-zero). Hence, the length of the vector of values provided by the
    two Subobservables must be equal or the condition must be scalar (in which case either all on none
    of the values from the first Subobservable are forwarded). In this way the FilterObservalbe allows,
    for example, to fill histograms with the pT of all electrons in an event (values provided by first
    Subobservable) which pass certain criteria evaluated via the second Subobservable (within a certain 
    eta range, passing certain ID criteria,...)
*/

ClassImp(TQFilterObservable)

//______________________________________________________________________________________________

TQFilterObservable::TQFilterObservable(){
  // default constructor
  DEBUGclass("default constructor called");
}

//______________________________________________________________________________________________

TQFilterObservable::~TQFilterObservable(){
  // default destructor
  DEBUGclass("destructor called");
} 


//______________________________________________________________________________________________

TObjArray* TQFilterObservable::getBranchNames() const {
  // retrieve the list of branch names 
  // ownership of the list belongs to the caller of the function
  DEBUGclass("retrieving branch names");

  TObjArray* bnames = new TObjArray();
  if (!this->fCutObs) {
    ERROR("there is no fCutObs");
  } else {
      TCollection* c = this->fCutObs->getBranchNames();
      if(c){
        c->SetOwner(false);
        bnames->AddAll(c);
        delete c;
      }
  }
  if (!this->fValueObs) {
    ERROR("there is no fValueObs");
  } else {
      TCollection* c = this->fValueObs->getBranchNames();
      if(c){
        c->SetOwner(false);
        bnames->AddAll(c);
        delete c;
      }
  }
  return bnames;
}

//______________________________________________________________________________________________
bool TQFilterObservable::makeCache() const {
  // determine all return values for getValueAt and getNevaluations if this hasn't been done yet
  
  if (this->fCachedEntry == this->getCurrentEntry() && this->fCachedEntry>0) return true; //nothing to do here, the cache is already up-to-date
  
  this->fCachedValues.clear();
  //we have to consider three cases: scalar value + scalar cut, vector value + scalar cut, vector value + vector cut
  if (!this->fCutObs) {
    ERRORclass("No cut observable present! (Was this observable correctly initialized?)");
    return false;
  }
  if (!this->fValueObs) {
    ERRORclass("No value observable present! (Was this observable correctly initialized?)");
    return false;
  }
  
  //case 1+2:
  if (this->fCutObs->getObservableType() == TQObservable::ObservableType::scalar) {
    if (std::fabs(this->fCutObs->getValue()) > 2*std::numeric_limits<double>::epsilon()) { //check for cut being passed
      for (int i=0; i<this->fValueObs->getNevaluations(); i++) {
        this->fCachedValues.push_back(this->fValueObs->getValueAt(i));
      }
    }
  } else if (this->fValueObs->getObservableType() == TQObservable::ObservableType::vector) {//case 3: vector value + vector cut
    int nEval = this->fCutObs->getNevaluations();
    if (nEval != this->fValueObs->getNevaluations()) {
      ERRORclass(TString::Format("Cut and value observables have different number of evaluations in TQFilterObservable with expression '%s'",this->getExpression().Data()).Data());
      return false;
    }
    for (int i=0; i<nEval; i++) {
      if (std::fabs(this->fCutObs->getValueAt(i)) > 2*std::numeric_limits<double>::epsilon()) { //check for cut being passed
        this->fCachedValues.push_back(this->fValueObs->getValueAt(i));
      }
    }
  } else { //none of the cases 1-3 applies (think of scalar value + vector cut: what should we do in this case?)
    ERRORclass("Illegal combination of observable types: Trying to filter a scalar value based on a vector type cut is highly ambiguous!");
    return false;
  }
  this->fCachedEntry = this->getCurrentEntry();
  return true;
}


double TQFilterObservable::getValue() const {
  // in the rest of this function, you should retrieve the data and calculate your return value
  // here is the place where most of your custom code should go
  // a couple of comments should guide you through the process
  // when writing your code, please keep in mind that this code can be executed several times on every event
  // make your code efficient. catch all possible problems. when in doubt, contact experts!
  
  // here, you should calculate your return value
  // of course, you can use other data members of your observable at any time
  /* example block for TTreeFormula method:
  const double retval = this->fFormula->Eval(0.);
  */
  /* exmple block for TTree::SetBranchAddress method:
  const double retval = this->fBranch1 + this->fBranch2;
  */

  throw std::runtime_error("Called vector type observable TQFilterObservable in scalar context.");
  return -999.;
}

int TQFilterObservable::getNevaluations() const {
  
  if (!this->makeCache()) {
    throw std::runtime_error(TString::Format("Failed to create return value(s) in TQFilterObservable with expression '%s'",this->getExpression().Data()).Data());
    return -1;
  }
  return this->fCachedValues.size();
  /* Frank's original code
  if (this->fCutObs->getValue() > 0) {
    return 0;
  } else {
    return 1;
  }
  */
}

double TQFilterObservable::getValueAt(int index) const {
  if (index >= TQFilterObservable::getNevaluations()) {
    throw std::runtime_error("Caught attempt to evaluate TQFilterObservable out of bounds!");
    return -999.;
  } else {
    return this->fCachedValues.at(index);
  }
}
//______________________________________________________________________________________________

TQFilterObservable::TQFilterObservable(const TString& expression):
TQObservable(expression)
{
  // constructor with expression argument
  DEBUGclass("constructor called with '%s'",expression.Data());
  // the predefined string member "expression" allows your observable to store an expression of your choice
  // this string will be the verbatim argument you passed to the constructor of your observable
  // you can use it to choose between different modes or pass configuration options to your observable
  this->SetName(TQObservable::makeObservableName(expression));
  this->setExpression(expression);
}

//______________________________________________________________________________________________

const TString& TQFilterObservable::getExpression() const {
  // retrieve the expression associated with this observable
  
  return this->fExpression; 
}

//______________________________________________________________________________________________

bool TQFilterObservable::hasExpression() const {
  // check if this observable type knows expressions
  return true;
}

//______________________________________________________________________________________________
void TQFilterObservable::setExpression(const TString& expr){
  // set the expression to a given string
  if (!this->parseExpression(expr)) this->fExpression = expr;
  else this->fExpression = TString("Filter("+this->fValueString+","+this->fCutString+")");
}
//______________________________________________________________________________________________

bool TQFilterObservable::parseExpression(const TString& expr){
  // parse the expression
  if (!expr.BeginsWith("Filter(") || !expr.EndsWith(")")) {
    return false;
  }

  TString exprArgs = expr(7, expr.Length() - 8); // remove opening and closing parenthesis
  std::vector<TString> tokens = TQStringUtils::tokenizeVector(exprArgs, ",", true, "()[]{}", "'\"");
  if (tokens.size() != 2) {
    return false;
  }
  this->fValueString = tokens[0];
  this->fCutString = tokens[1];
  
  return true;
}

//______________________________________________________________________________________________

void TQFilterObservable::clearParsedExpression(){
  this->fValueString.Clear();
  this->fCutString.Clear();
}

//______________________________________________________________________________________________

TString TQFilterObservable::getActiveExpression() const {
  // retrieve the expression associated with this incarnation
  return this->fActiveExpression;
}

//______________________________________________________________________________________________

Long64_t TQFilterObservable::getCurrentEntry() const {
  if (this->fCutObs && this->fCutObs->getCurrentEntry()>0) return this->fCutObs->getCurrentEntry();
  if (this->fValueObs && this->fValueObs->getCurrentEntry()>0) return this->fValueObs->getCurrentEntry();
  return -1; //fallback if we can't determine the current entry
}

//______________________________________________________________________________________________

bool TQFilterObservable::initializeSelf(){
  // initialize self - compile container name, construct accessor
  this->fActiveExpression = TQObservable::compileExpression(this->fExpression,this->fSample);
  if (!this->parseExpression(this->fExpression)) {
    return false;
  }
  DEBUGclass("Initializing observable with active expression '%s'",this->fActiveExpression.Data());
  this->fValueObs = TQObservable::getObservable(this->fValueString, this->fSample);
  if (!this->fValueObs) {
      ERROR("Failed to retrieve value-observable.");
      return false;
  }
  if (!this->fValueObs->initialize(this->fSample)) {
      ERROR("Failed to initialize value-observable.");
      return false;
  }

  this->fCutObs = TQObservable::getObservable(this->fCutString, this->fSample);
  if (!this->fCutObs) {
      ERROR("Failed to retrieve cut-observable.");
      return false;
  }
  if (!this->fCutObs->initialize(this->fSample)) {
      ERROR("Failed to initialize cut-observable.");
      return false;
  }


  return true;
}
 
//______________________________________________________________________________________________

bool TQFilterObservable::finalizeSelf(){
  // finalize self - delete accessor
  if (this->fCutObs != NULL) {
        if (!this->fCutObs->finalize()) {
            ERROR("finalizing CutObs failed");
        }
        this->fCutObs = NULL;
  }
  if (this->fValueObs != NULL) {
        if (!this->fValueObs->finalize()) {
            ERROR("finalizing ValueObs failed");
        }
        this->fValueObs = NULL;
  }
  this->clearParsedExpression();
  this->fActiveExpression.Clear();
  return true;
}
//______________________________________________________________________________________________
int TQFilterObservable::registerFactory() {
  TQObservable::manager.registerFactory(TQFilterObservable::getFactory(),true);
  ERROR("registerFactory");
  return 0;
}


// the following preprocessor macro defines an "observable factory"
// that is supposed to create instances of your class based on input
// expressions.

// it should receive an expression as an input and decide whether this
// expression should be used to construct an instance of your class,
// in which case it should take care of this, or return NULL.

// in addition to defining your observable factory here, you need to
// register it with the TQObservable manager. This can either be done
// from C++ code, using the line
//   TQObservable::manager.registerFactory(TQFilterObservable::getFactory(),true);
// or from python code, using the line
//   TQObservable.manager.registerFactory(TQFilterObservable.getFactory(),True)
// Either of these lines need to be put in a location where they are
// executed before observables are retrieved. You might want to 'grep'
// for 'registerFactory' in the package you are adding your observable
// to in order to get some ideas on where to put these!

DEFINE_OBSERVABLE_FACTORY(TQFilterObservable,TString expr){
  // try to create an instance of this observable from the given expression
  // return the newly created observable upon success
  // or NULL upon failure

  // first, check if the expression fits your observable type
  // for example, you can grab all expressions that begin wth "TQFilterObservable:"
  // if this is the case, then we call the expression-constructor
  if (!expr.BeginsWith("Filter(") || !expr.EndsWith(")")) {
    return NULL;
  }

  TString exprArgs = expr(7, expr.Length() - 8); // remove opening and closing parenthesis
  std::vector<TString> tokens = TQStringUtils::tokenizeVector(exprArgs, ",", true, "()[]{}", "'\"");

  if (tokens.size() != 2) {
    return NULL;
  }
  return new TQFilterObservable(expr);
  
  // else, that is, if the expression doesn't match the pattern we
  // expect, we return this is important, because only in doing so we
  // give other observable types the chance to check for themselves
  return NULL;
  // if you do not return NULL here, your observable will become the
  // default observable type for all expressions that don't match
  // anything else, which is probably not what you want...
}

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