#define UNDERLYING(type)        type, IP_##type

template<class UnderlyingModel, class inputParamaters, class DataStructure>
class Underlying : UnderlyingModel, DataStructure
{
 public:
  Underlying(inputParamaters inParam) : UnderlyingModel(inParam), DataStructure(Q, S0, N, M)
  {
  }
};

template<class UnderlyingModel, class inputParamaters, class UnderlyingMethod>
class Underlying<UnderlyingModel, inputParamaters, Tree<Complete, UnderlyingMethod> > : UnderlyingModel 
{
private:
  Tree<Complete, UnderlyingMethod> *sTree_;

public:
  Underlying(inputParamaters inParam) : UnderlyingModel(inParam)
  {
    sTree_ = new Tree<Complete, UnderlyingMethod>(Q, S0, N, M, NULL);
  }

  PostOrderIterator<double>& getStockPostOrderIterator(void)
  {
    PostOrderIterator<double> *iter = sTree_->GetPostOrderIterator();
    
    iter->Reset();
    
    return *iter;
  }

  BreadthFirstIterator<double>& getStockBreadthFirstIterator(void)
  {
    BreadthFirstIterator<double> *iter = sTree_->GetBreadthFirstIterator();
    
    iter->Reset();
    
    return *iter;
  }

#ifdef GRAPHICS
  void graphStock(char *fname, unsigned int width, unsigned int height)
  {
    sTree_->dump(fname, width, height);
  }
#endif

};

template<class UnderlyingModel, class inputParamaters, class UnderlyingMethod>
class Underlying<UnderlyingModel, inputParamaters, Matrix<Complete, UnderlyingMethod> > : UnderlyingModel 
{
private:
  Matrix<Complete, UnderlyingMethod> *sJag_;

public:
  Underlying(inputParamaters inParam) : UnderlyingModel(inParam)
  {
    sJag_ = new Matrix<Complete, UnderlyingMethod>(Q, S0, N, M);
    
  }

  // stock access methods
  double getStockValue(unsigned int col, unsigned int row)
  {
    return sJag_->Get(col, row);
  }

  unsigned int getStockHeight(unsigned int col)
  {
    return sJag_->Height(col);
  }

#ifdef GRAPHICS
  void graphStock(char *fname, unsigned int width, unsigned int height)
  {
    sJag_->dump(fname, width, height);
  }
#endif
};


