#include "AdvParamSet.hh"
//#include <typeinfo>
#include <cstdlib>
#include <cmath>

#define CAST_TO_INT 1

/** 
 *  container for Double type matrix
 *  @author TANIMORI Souichirou, AdvanceSoft Corp.
 *  @version 0.0
 */
/* {since=2.1.14}*/

const std::string AdvParamSet::className=std::string("AdvParamSet");


/** 
 *  constructor
 */
AdvParamSet::AdvParamSet()
{
    BoolMap.clear();
    Int4Map.clear();
    UInt4Map.clear();
    DoubleMap.clear();
    vectorMap.clear();
    matrixMap.clear();
    peakDataMap.clear();
    funcListMap.clear();
}


/** 
 *  destructor
 */
AdvParamSet::~AdvParamSet()
{
    std::string memberName=std::string("~PeakSet");
    DebugMessage(className, memberName, "enter\n");

    BoolMap.clear();
    Int4Map.clear();
    UInt4Map.clear();
    DoubleMap.clear();
    vectorMap.clear();
    matrixMap.clear();
    peakDataMap.clear();
    funcListMap.clear();

    DebugMessage(className, memberName, "exit\n");
}


/** 
 *  add a Int4 type parameter with its key
 */
void AdvParamSet::add(const std::string key, const Int4 value)  {
    std::string memberName = std::string("add(std::string, Int4)");
    std::string separator = std::string(":");
    if ( Int4Map.find(key) != Int4Map.end() ) {
        throw std::invalid_argument(className + separator + memberName + separator + std::string("value with the key already contains.") + separator + key);
        //std::cerr << "Error: AdvParamSet:add(const std::string&, const Int4) : the value with the key already exists. : " << key << std::endl;
        //std::cerr << std::endl;
        //return;
    }
    Int4Map.insert(std::pair<std::string, Int4>(key, value));
}


/**
 *  add a boolean parameter with its key
 */
void AdvParamSet::add(const std::string key, const Bool value)  {
    std::string memberName = std::string("add(std::string, Bool)");
    std::string separator  = std::string(":");

#ifdef CAST_TO_INT
    add(key, static_cast<Int4>(value));
#else
    if ( BoolMap.find(key) != BoolMap.end() ) {
        throw std::invalid_argument(className + separator + memberName + separator + std::string("value with the key already contains.") + separator + key);
        //std::cerr << "Error: AdvParamSet:add(const std::string&, const Bool) : the value with the key already exists. : " << key << std::endl;
        //std::cerr << std::endl;
        //return;
    }
    BoolMap.insert(std::pair<std::string, Bool>(key, value));
#endif
}


/** 
 *  add a UInt4 type parameter with its key
 */
void AdvParamSet::add(const std::string key, UInt4 value)  {
    std::string memberName = std::string("add(std::string, UInt4)");
    std::string separator = std::string(":");

#ifdef CAST_TO_INT
    add(key, static_cast<Int4>(value));
#else
    if ( UInt4Map.find(key) != UInt4Map.end() ) {
        throw std::invalid_argument(className + separator + memberName + separator + std::string("value with the key already contains.") + separator + key);
        //std::cerr << "Error: AdvParamSet:add(const std::string&, const UInt4) : the value with the key already exists. : " << key << std::endl;
        //std::cerr << std::endl;
        //return;
    }
    UInt4Map.insert(std::pair<std::string, UInt4>(key, value));
#endif
}


/** 
 *  add a Double type parameter with its key
 */
void AdvParamSet::add(const std::string key, const Double value)  {
    std::string memberName = std::string("add(std::string, Double)");
    std::string separator = std::string(":");
    if ( DoubleMap.find(key) != DoubleMap.end() ) {
        throw std::invalid_argument(className + separator + memberName + separator + std::string("value with the key already contains.") + separator + key);
        //std::cerr << "Error: AdvParamSet:add(const std::string&, const Double) : the value with the key already exists. : " << key << std::endl;
        //std::cerr << std::endl;
        //return;
    }
    DoubleMap.insert(std::pair<std::string, Double>(key, value));
}


/** 
 *  add a Double type std::vector with its key
 */
void AdvParamSet::add(const std::string key, std::vector<Double> &value)  {
    std::string memberName = std::string("add(std::string, std::vector<Double>)");
    std::string separator = std::string(":");
    if (vectorMap.find(key) != vectorMap.end() ) { 
        throw std::invalid_argument(className + separator + memberName + separator + std::string("value with the key already contains.") + separator + key);
        //std::cerr << "Error: AdvParamSet::add(const std::string&, std::vector<Double>&) : the value with the key already exists. : " << key << std::endl;
        //std::cerr << std::endl;
        //return;
    }
    if (value.empty()) {
        throw std::invalid_argument(className + separator + memberName + separator + std::string("the size of the value is zero") + separator + key);
        //std::cerr << "Error: AdvParamSet::add(const std::string&, std::vector<Double>&) : the size of the value is zero: " << key << std::endl;
        //std::cerr << std::endl;
        //return;
    }
    vectorMap.insert(std::pair<std::string, std::vector<Double> >(key, value));
    //std::cerr << "Debug : AdvParamSet::add(const std::string&, std::vector<Double>&) : " << vectorMap.find(key)->second.size() << std::endl;
}

void AdvParamSet::add(const std::string key, PyObject *value)  {
    std::string memberName = std::string("add(std::string, PyObject*)");
    std::string separator = std::string(":");
    if (vectorMap.find(key) != vectorMap.end() ) { 
        throw std::invalid_argument(className + separator + memberName + separator + std::string("value with the key already contains") + separator + key);
        //std::cerr << "Error: AdvParamSet::add(const std::string&, std::vector<Double>&) : the value with the key already exists. : " << key << std::endl;
        //std::cerr << std::endl;
        //return;
    }

    std::vector<Double> TmpVec = __gCppToPython.ListToDoubleVector(value);
    if (TmpVec.empty()) {
        throw std::invalid_argument(className + separator + memberName + separator + std::string("the size of the value is zero") + separator + key);
        //std::cerr << "Error: AdvParamSet::add(const std::string&, std::vector<Double>&) : the size of the value is zero: " << key << std::endl;
        //std::cerr << std::endl;
        //return;
    }
    vectorMap.insert(std::pair<std::string, std::vector<Double> >(key, TmpVec));
}


/** 
 *  add a Double type matrix wthe its key
 */
void AdvParamSet::add(const std::string key, std::vector< std::vector<Double> > value)  {
    std::string memberName = std::string("add(std::string, std::vector< std::vector<Double> >)");
    std::string separator = std::string(":");
    if (matrixMap.find(key) != matrixMap.end() ) { 
        throw std::invalid_argument(className + separator + memberName + separator + std::string("value with the key already contains.") + separator + key);
        //std::cerr << "Error: AdvParamSet::add(const std::string&, std::vector< std::vector<Double> >&) : the value with the key already exists. : " << key << std::endl;
        //std::cerr << std::endl;
        //return;
    }
    if ( ! (value.size() > 0) || ! (value[0].size() > 0) ) {
        throw std::invalid_argument(className + separator + memberName + separator + std::string("the size of the value is zero") + separator + key);
        //std::cerr << "Error: AdvParamSet::add(const std::string&, std::vector< std::vector<Double> >&) : the row or column size of the value is zero: " << key << std::endl;
        //std::cerr << std::endl;
        //return;
    }
    matrixMap.insert(std::pair<std::string, std::vector< std::vector<Double> > >(key, value));
}

/**
 *
 */
void AdvParamSet::add(const std::string key, AdvPeakData value)  {
    std::string memberName = std::string("add(std::string, AdvPeakData)");
    std::string separator = std::string(":");

    if ( peakDataMap.find(key) != peakDataMap.end() ) {
        throw std::invalid_argument(className + separator + memberName + separator + std::string("value with the key already contains.") + separator + key);
        //std::cerr << "Error: AdvParamSet::add(const std::string, AdvPeakData) : the value with the key already exists. : " << key << std::endl;
        //std::cerr << std::endl;
        //return;
    }
    if ( value.size() == 0) {
        throw std::invalid_argument(className + separator + memberName + separator + std::string("the size of the value is zero") + separator + key);
        //std::cerr << "Error: AdvParamSet::add(const std::string, AdvPeakData) : size of the value is zero: " << key << std::endl;
        //std::cerr << std::endl;
        //return;
    }
    peakDataMap.insert(std::pair<std::string, AdvPeakData>(key, value));
}


/**
 *
 */
void AdvParamSet::add(const std::string key, std::vector<AdvFuncBase*> value)  {
    std::string memberName = std::string("add(std::string, std::vector<AdvFuncBase*>)");
    std::string separator = std::string(":");

    if (funcListMap.find(key) != funcListMap.end()) {
        throw std::invalid_argument(className + separator + memberName + separator + std::string("value with the key already contains." + separator + key));
        //std::cerr << "Error: AdvParamSet::add(const std::string, std::vector<AdvFuncBase*>) : the value with the key already exists. : " << key << std::endl;
        //std::cerr << std::endl;
        //return;
    }
    if ( value.size() == 0) {
        throw std::invalid_argument(className + separator + memberName + separator + std::string("the size of the value is zero") + separator + key);
        //std::cerr << "Error: AdvParamSet::add(const std::string, std::vector<AdvFuncBase*>) : size of the value is zero: " << key << std::endl;
        //std::cerr << std::endl;
        //return;
    }
    funcListMap.insert(std::pair<std::string, std::vector<AdvFuncBase*> >(key, value));
}

/**
 *  add funcMatrix (a list of fucnBase lists) with key
 */
void AdvParamSet::add(const std::string key, std::vector< std::vector<AdvFuncBase*> > value)  {
    std::string memberName = std::string("add(std::string, std::vector< std::vector<AdvFuncBase*> >)");
    std::string separator = std::string(":");

    if (funcMatrixMap.find(key) != funcMatrixMap.end()) {
        throw std::invalid_argument(className + separator + memberName + separator + std::string("value with the key already contains." + separator + key));
    }
    if (value.size() == 0) {
        throw std::invalid_argument(className + separator + memberName + separator + std::string("the size of the value is zero") + separator + key);
    } else {
        for (UInt4 i=0; i<value.size(); ++i) {
            if ( value[i].size() == 0) {
                throw std::invalid_argument(className + separator + memberName + separator + std::string("empty list found") + separator + key);
            }
        }
    }
    funcMatrixMap.insert(std::pair<std::string, std::vector< std::vector<AdvFuncBase*> > >(key, value));
}


/** 
 *  erase the data with the given key
 */
void AdvParamSet::erase(const std::string &key) {

    std::map<std::string, Bool>::iterator                         i_Bool;
    std::map<std::string, Int4>::iterator                         i_Int4;
    std::map<std::string, UInt4>::iterator                        i_UInt4;
    std::map<std::string, Double>::iterator                       i_Double;
    std::map<std::string, std::vector<Double> >::iterator              i_vector;
    std::map<std::string, std::vector< std::vector<Double> > >::iterator    i_matrix;
    std::map<std::string, AdvPeakData>::iterator                     i_AdvPeakData;
    std::map<std::string, std::vector<AdvFuncBase*> >::iterator           i_funcList;
    std::map<std::string, std::vector< std::vector<AdvFuncBase*> > >::iterator i_funcMatrix;

    i_Bool =BoolMap.find(key);            if (i_Bool     != BoolMap.end()        ) { BoolMap.erase(i_Bool);             }
    i_Int4 =Int4Map.find(key);            if (i_Int4     != Int4Map.end()        ) { Int4Map.erase(i_Int4);             }
    i_UInt4=UInt4Map.find(key);           if (i_UInt4    != UInt4Map.end()       ) { UInt4Map.erase(i_UInt4);           }
    i_Double=DoubleMap.find(key);         if (i_Double   != DoubleMap.end()      ) { DoubleMap.erase(i_Double);         }
    i_vector  =vectorMap.find(key);       if (i_vector   != vectorMap.end()      ) { vectorMap.erase(i_vector);         }
    i_matrix  =matrixMap.find(key);       if (i_matrix   != matrixMap.end()      ) { matrixMap.erase(i_matrix);         }
    i_AdvPeakData=peakDataMap.find(key);     if (i_AdvPeakData != peakDataMap.end()    ) { peakDataMap.erase(i_AdvPeakData);     }
    i_funcList=funcListMap.find(key);     if (i_funcList != funcListMap.end()    ) { funcListMap.erase(i_funcList);     }
    i_funcMatrix=funcMatrixMap.find(key); if (i_funcMatrix != funcMatrixMap.end()) { funcMatrixMap.erase(i_funcMatrix); }
}


/** 
 *  replace the value of the Int4 type data with the given key
 *  
 *  @param[in] key    key for an Int4 type parameter
 *  @param[in] value the new value of the Iparameter
 */
void AdvParamSet::replace(const std::string &key, const Int4 value)  {
    std::string memberName = std::string("replace(std::string&, Int4)");
    std::string separator = std::string(":");

    if (Int4Map.find(key) == Int4Map.end()) {
        throw std::invalid_argument(className + separator + memberName + separator + std::string("Int4 type parameter with specified key not found") + separator + key);
        //std::cerr << "Error: AdvParamSet::replace(const stirng&, condt Int4) : Int4 type parameter with specified key not found: " << key << std::endl;
        //return;
    }
    Int4Map[key]=value;
}


/**
 *  replace the value of the Bool type data with the given lkey
 *
 * @param[in] key   key for a Bool type data parameter
 * @param[in] value new value of the parameter
 */
void AdvParamSet::replace(const std::string &key, const Bool value)  {
    std::string memberName = std::string("replace(std::string&, Bool)");
    std::string separator = std::string(":");

#ifdef CAST_TO_INT
    replace(key, static_cast<Int4>(value));
#else
    if ( BoolMap.find(key) == BoolMap.end() ) {
        throw std::invalid_argument(className + separator + memberName + separator + std::string("Bool type parameter with specified key not found") + separator + key);
        //std::cerr << "Error: AdvParamSet::replace(const stirng&, condt Bool) : Bool type parameter with specified key not found: " << key << std::endl;
        //return;
    }
    BoolMap[key]=value;
#endif
}


/** 
 *  replace the value of the UInt4 type data with the given key
 *  
 *  @param[in] key    key for an UInt4 type parameter
 *  @param[in] value the new value of the parameter
 */
void AdvParamSet::replace(const std::string &key, const UInt4 value)  {
    std::string memberName = std::string("replace(std::string&, UInt4)");
    std::string separator = std::string(":");

#ifdef CAST_TO_INT
    replace(key, static_cast<Int4>(value));
#else
    if (UInt4Map.find(key) == UInt4Map.end()) {
        throw std::invalid_argument(className + separator + memberName + separator + std::string("UInt4 type parameter with specified key not found") + separator + key);
        //std::cerr << "Error: AdvParamSet::replace(const stirng&, condt UInt4) : UInt4 type parameter with specified key not found: " << key << std::endl;
        //return;
    }
    UInt4Map[key]=value;
#endif
}


/** 
 *  replace the value of the Double type data with the given key
 *  
 *  @param[in] key     key for a Double type parameter
 *  @param[in] value new value of the  parameter
 */
void AdvParamSet::replace(const std::string &key, const Double value)  {
    std::string memberName = std::string("replace(std::string&, Double)");
    std::string separator = std::string(":");

    if (DoubleMap.find(key) == DoubleMap.end()) {
        throw std::invalid_argument(className + separator + memberName + separator + std::string("Double type parameter with specified key not found ") + separator + key);
        //std::cerr << "Error: AdvParamSet::replace(const stirng&, condt Double) : Double type parameter with specified key not found: " << key << std::endl;
        //return;
    }
    DoubleMap[key]=value;
}


/** 
 *  replace the value of the Double type std::vector/array with the given key
 *  
 *  @param[in] key the key for a Double type vecor
 *  @param[in] value the values of the parameter
 */
void AdvParamSet::replace(const std::string &key, std::vector<Double> value)  {
    std::string memberName = std::string("replace(std::string&, std::vector<Double>)");
    std::string separator = std::string(":");

    if (vectorMap.find(key) == vectorMap.end()) {
        throw std::invalid_argument(className + separator + memberName + separator + std::string("Double std::vector type parameter with specified key not found ") + separator + key);
        //std::cerr << "Error: AdvParamSet::replace(const stirng&, condt std::vector<Double>) : std::vector with specified key not found: " << key << std::endl;
        //return;
    }
    //vectorMap.find(key)->second.clear();
    //vectorMap.find(key)->second.assign(value.begin(), value.end());
    vectorMap.erase(vectorMap.find(key));
    vectorMap.insert(std::pair<std::string, std::vector<Double> >(key, value));
}

void AdvParamSet::replace(const std::string &key, PyObject *value)  {
    std::string memberName = std::string("replace(std::string&, PyObject*)");
    std::string separator = std::string(":");

    if (vectorMap.find(key) == vectorMap.end()) {
        throw std::invalid_argument(className + separator + memberName + separator + std::string("Double std::vector type parameter with specified key not found ") + separator + key);
        //std::cerr << "Error: AdvParamSet::replace(const stirng&, condt std::vector<Double>) : std::vector with specified key not found: " << key << std::endl;
        //return;
    }

    std::vector<Double> tmpVec = __gCppToPython.ListToDoubleVector(value);
    vectorMap.erase(vectorMap.find(key));
    vectorMap.insert(std::pair<std::string, std::vector<Double> >(key, tmpVec));
    
}


/** 
 *  replace the specified component of the vector with key
 *  
 *  @param[in] key the key of the vector
 *  @param[in] i       index of the component
 *  @param[in] value the new value of the componet
 */
void AdvParamSet::replace(const std::string &key, const UInt4 i, const Double value) {
    std::string memberName = std::string("replace(std::string&, UInt4, Double)");
    std::string separator = std::string(":");

    if (vectorMap.find(key) == vectorMap.end()) {
        throw std::invalid_argument(className + separator + memberName + separator + std::string("Double std::vector type parameter with specified key not found ") + separator + key);
        //std::cerr << "Error: AdvParamSet::replace(const stirng&, const Int4, condt Double) : std::vector with specified key not found: " << key << std::endl;
        //return;
    }
    if ( ! (0 <= i && i < vectorMap.find(key)->second.size()) ) {
        throw std::out_of_range("");
        //std::cerr << "Error: AdvParamSet::replace(const stirng&, const Int4, condt Double) : index is out of range: " << i << ", " << key << std::endl;
        //return;
    }
    vectorMap.find(key)->second[i]=value;
}


/** 
 *  replace the value of the Double type matrix with the given key
 *  
 *  @param[in] key the key for a Double type matix
 *  @param[in] value the values for the matrix
 */
void AdvParamSet::replace(const std::string &key, std::vector< std::vector<Double> > value)  {
    std::string memberName = std::string("replace(std::string&, std::vector< std::vector<Double> >)");
    std::string separator = std::string(":");

    if (matrixMap.find(key) == matrixMap.end()) {
        throw std::invalid_argument(className + separator + memberName + separator + std::string("matrix type  parameter with specified key not found ") + separator + key);
        //std::cerr << "Error: AdvParamSet::replace(const stirng&, std::vector< std::vector<Double> >) : matrix with specified key not found: " << key << std::endl;
        //return;
    }

    //std::cerr << "Debug: AdvParamSet::replace(const stirng&, std::vector< std::vector<Double> >) : row size of value: " << value.size() << std::endl;
    //std::cerr << "Debug: AdvParamSet::replace(const stirng&, std::vector< std::vector<Double> >) : column size of value: " << value[0].size() << std::endl;
    matrixMap.erase(matrixMap.find(key));
    matrixMap.insert(std::pair<std::string, std::vector< std::vector<Double> > >(key, value));
    //std::cerr << "Debug: AdvParamSet::replace(const stirng&, std::vector< std::vector<Double> >) : row size: " << matrixMap.find(key)->second.size() << std::endl;
    //std::cerr << "Debug: AdvParamSet::replace(const stirng&, std::vector< std::vector<Double> >) : row capacity: " << matrixMap.find(key)->second.capacity() << std::endl;
    //std::cerr << "Debug: AdvParamSet::replace(const stirng&, std::vector< std::vector<Double> >) : column size: " << matrixMap.find(key)->second[0].size() << std::endl;
    //std::cerr << "Debug: AdvParamSet::replace(const stirng&, std::vector< std::vector<Double> >) : column capacity: " << matrixMap.find(key)->second[0].capacity() << std::endl;
}


/** 
 *  replace the specified component of the matrix with key
 *  
 *  @param[in] key the key of the matrix
 *  @param[in] i       row index of the component
 *  @param[in] j       column index of the component
 *  @param[in] value the new value of the componet
 */
void AdvParamSet::replace(const std::string &key, const UInt4 i, const UInt4 j, const Double value) {
    std::string memberName = std::string("replace(std::string&, UInt4, UInt4, Double)");
    std::string separator = std::string(":");

    if (matrixMap.find(key) == matrixMap.end() ) {
        throw std::invalid_argument(className + separator + memberName + separator + std::string("matrix type  parameter with specified key not found ") + separator + key);
        //std::cerr << "Error: AdvParamSet::replace(const stirng&, std::vector< std::vector<Double> >) : matrix with specified key not found: " << key << std::endl;
        //return;
    }

    if ( ! (0 <= i && i < matrixMap.find(key)->second.size()) ) {
        throw std::out_of_range(className + separator + memberName + separator + std::string(" row is out of range") + separator + key);
        //std::cerr << "Error: AdvParamSet::replace(const stirng&, std::vector< std::vector<Double> >) : row is out of range: " << i << ", " << key << std::endl;
        //return;
    }
    if ( ! (0 <= j && j < matrixMap.find(key)->second[0].size()) ) {
        throw std::out_of_range(className + separator + memberName + separator + std::string("column is out of range") + separator + key);
        //std::cerr << "Error: AdvParamSet::replace(const stirng&, std::vector< std::vector<Double> >) : column is out of range: " << j << ", " << key << std::endl;
        //return;
    }
    matrixMap.find(key)->second[i][j]=value;
}

/**
 *
 */
void AdvParamSet::replace(const std::string &key, AdvPeakData value)  {
    std::string memberName = std::string("replace(std::string&, AdvPeakData)");
    std::string separator = std::string(":");

    if (peakDataMap.find(key) == peakDataMap.end()) {
        throw std::invalid_argument(className + separator + memberName + separator + std::string("peak data with the specified key not found: ") + separator + key);
        //std::cerr << "Error: AdvParamSet::replace(const stirng&, AdvPeakData)) : peak data with specified key not found: " << key << std::endl;
        //return;
    }
    //peakDataMap.erase(peakDataMap.find(key));
    //peakDataMap.insert(std::pair<std::string, AdvPeakData>(key, value));
    peakDataMap[key]=value;
}

/**
 *
 */
void AdvParamSet::replace(const std::string &key, std::vector<AdvFuncBase*> value)  {
    std::string memberName = std::string("replace(std::string&, std::vector<AdvFuncBase*>)");
    std::string separator = std::string(":");

    if ( funcListMap.find(key) == funcListMap.end() ) {
        throw std::invalid_argument(className + separator + memberName + separator + std::string("function list with the specified key not found") + separator + key);
        //std::cerr << "Error: AdvParamSet::replace(const stirng&, std::vector<AdvFuncBase*>) : function list with specified key not found: " << key << std::endl;
    }
    funcListMap.erase(funcListMap.find(key));
    funcListMap.insert(std::pair<std::string, std::vector<AdvFuncBase*> >(key, value));
}

void AdvParamSet::replace(const std::string &key, const UInt4 i, AdvFuncBase *value) {
    std::string memberName = std::string("replace(std::string&, UINt4, AdvFuncBase*)");
    std::string separator = std::string(":");

    if ( funcListMap.find(key) == funcListMap.end() ) {
        std::cerr << "Error: AdvParamSet::replace(const stirng&, std::vector<AdvFuncBase*>) : function list with specified key not found: " << key << std::endl;
    }
    if ( ! (0 <= i && i < funcListMap.find(key)->second.size()) ) {
        std::cerr << "Error: AdvParamSet::replace(const stirng&, UInt4, std::vector<AdvFuncBase*>) : index is out of range: " << i << ", " << key << std::endl;
    }
    funcListMap.find(key)->second[i]=value;
}

/**
 */
void AdvParamSet::replace(const std::string &key, std::vector< std::vector<AdvFuncBase*> > value)  {
    std::string memberName = std::string("replace(std::string&, std::vector< std::vector<AdvFuncBase*> >)");
    std::string separator = std::string(":");

    if ( funcMatrixMap.find(key) == funcMatrixMap.end() ) {
        throw std::invalid_argument(className + separator + memberName + separator + std::string("function matrix with the specified key not found") + separator + key);
    }
    funcMatrixMap.erase(funcMatrixMap.find(key));
    funcMatrixMap.insert(std::pair<std::string, std::vector< std::vector<AdvFuncBase*> > >(key, value));
}

void AdvParamSet::replace(const std::string &key, UInt4 i, UInt4 j, AdvFuncBase *value) {
    std::string memberName = std::string("replace(std::string&, UInt4, UInt4, AdvFuncBase*)");
    std::string separator = std::string(":");

    if ( funcMatrixMap.find(key) == funcMatrixMap.end() ) {
        throw std::invalid_argument(className + separator + memberName + separator + std::string("function matrix with the specified key not found") + separator + key);
    }
    if ( ! (0<=i && i< funcMatrixMap.find(key)->second.size()) ) {
        throw std::out_of_range(className + separator + memberName + separator + std::string(" row is out of range") + separator + key);
    }
    if ( ! (0<=j && j< funcMatrixMap.find(key)->second[i].size()) ) {
        throw std::out_of_range(className + separator + memberName + separator + std::string(" column is out of range") + separator + key);
    }
    funcMatrixMap.find(key)->second[i][j]=value;
}


/** 
 *  dump the set of parameters to stdout
 */
void AdvParamSet::dump() {

    std::string KEY=std::string("key");
    std::string VALUE=std::string("value");
    std::string SIZE=std::string("size");

    char title_fmt[]     = "%s\n";
    char SUB_TITLE_FMT[] = "%4s%s\n";

    message(title_fmt, "Parameter Set");
    if ( ! BoolMap.empty() ) {
        size_t l=0;
        for (std::map<std::string, Bool>::iterator i_Bool=BoolMap.begin(); i_Bool != BoolMap.end(); ++i_Bool) {
            if ( i_Bool->first.size() > l ) { l=i_Bool->first.size(); }
        }
        Char header_fmt[15+5+1], map_fmt[15+5+1];
        std::snprintf(header_fmt, sizeof(header_fmt), "%%4s%%4s%%-%lus %%5s\n",  std::max(l, KEY.size()));
        std::snprintf(map_fmt, sizeof(map_fmt), "%%4s%%4s%%-%lus %%-5s\n", std::max(l, KEY.size()));
        //std::printf("%s", header_fmt);
        //std::printf("%s", map_fmt);

        message(SUB_TITLE_FMT, " ", "Bool type parameter(s)");
        message(header_fmt,    " ", " ", KEY.c_str(), VALUE.c_str());
        for (std::map<std::string, Bool>::iterator i_Bool=BoolMap.begin(); i_Bool != BoolMap.end(); ++i_Bool) {
            message(map_fmt,       " ", " ", (i_Bool->first).c_str(), (i_Bool->second ? "true" : "false"));
        }
        message("\n");
    }

    if ( ! Int4Map.empty() ) {
        size_t l=0;
        for(std::map<std::string, Int4>::iterator i_Int4=Int4Map.begin(); i_Int4 != Int4Map.end(); ++i_Int4) {
            if ( i_Int4->first.size() > l) { l=i_Int4->first.size(); }
        }
        Char header_fmt[15+10+1], map_fmt[15+10+1]; 
        std::snprintf(header_fmt, sizeof(header_fmt), "%%4s%%4s%%-%lus %%10s\n", std::max(l, KEY.size()));
        std::snprintf(map_fmt, sizeof(map_fmt), "%%4s%%4s%%-%lus %%10d\n", std::max(l, KEY.size()));
        //std::printf("%s", header_fmt);
        //std::printf("%s", map_fmt);

        message(SUB_TITLE_FMT, " ", "Int4 type parameter(s)");
        message(header_fmt,    " ", " ", KEY.c_str(), VALUE.c_str());
        for (std::map<std::string, Int4>::iterator i_Int4=Int4Map.begin(); i_Int4 != Int4Map.end(); ++i_Int4) {
            message(map_fmt,       " ", " ", (i_Int4->first).c_str(), (i_Int4->second));
        }
        message("\n");
    }

    if ( ! UInt4Map.empty() ) {
        size_t l=0;
        for(std::map<std::string, UInt4>::iterator i_UInt4=UInt4Map.begin(); i_UInt4 != UInt4Map.end(); ++i_UInt4) {
            if ( i_UInt4->first.size() > l) { l=i_UInt4->first.size(); }
        }
        Char header_fmt[15+10+1], map_fmt[15+10+1];
        std::snprintf(header_fmt, sizeof(header_fmt), "%%4s%%4s%%-%lus %%10s\n", std::max(l, KEY.size()));
        std::snprintf(map_fmt, sizeof(map_fmt), "%%4s%%4s%%-%lus %%10u\n", std::max(l, KEY.size()));
        //std::printf("%s", header_fmt);
        //std::printf("%s", map_fmt);

        message(SUB_TITLE_FMT, " ", "UInt4 type parameter(s)");
        message(header_fmt,    " ", " ", KEY.c_str(), VALUE.c_str());
        for (std::map<std::string, UInt4>::iterator i_UInt4=UInt4Map.begin(); i_UInt4 != UInt4Map.end(); ++i_UInt4) {
            message(map_fmt,       " ", " ", (i_UInt4->first).c_str(), (i_UInt4->second));
        }
        message("\n");
    }

    if ( ! DoubleMap.empty() ) {

        size_t l=0;
        for (std::map<std::string, Double>::iterator i_Double=DoubleMap.begin(); i_Double != DoubleMap.end(); ++i_Double) {
            if ( i_Double->first.size() > l ) { l = i_Double->first.size(); }
        }
        Char header_fmt[15+10+1], map_fmt[18+10+1];
        std::snprintf(header_fmt, sizeof(header_fmt), "%%4s%%4s%%-%lus %%23s\n",    std::max(l, KEY.size()));
        std::snprintf(map_fmt, sizeof(map_fmt), "%%4s%%4s%%-%lus %%23.15e\n", std::max(l, KEY.size()));
        //std::printf("%s", header_fmt);
        //std::printf("%s", map_fmt);

        message(SUB_TITLE_FMT, " ", "Double type parameter(s)");
        message(header_fmt,    " ", " ", KEY.c_str(), VALUE.c_str());
        for(std::map<std::string, Double>::iterator i_Double=DoubleMap.begin(); i_Double != DoubleMap.end(); ++i_Double) {
            message(map_fmt,       " ", " ", (i_Double->first).c_str(), (i_Double->second));
        }
        message("\n");
    }

    if ( ! vectorMap.empty() ) {
        size_t l=0, im=0;
        for(std::map<std::string, std::vector<Double> >::iterator i_vector=vectorMap.begin(); i_vector != vectorMap.end(); ++i_vector) {
            if ( i_vector->first.size()  > l  ) { l=i_vector->first.size(); } 
            if ( i_vector->second.size() > im ) { im=i_vector->second.size(); }
        }
        Char header_fmt[20+10+1], map_fmt[20+10+1];
        size_t di=( im=0 ? 1 : (UInt4)(log10(static_cast<Double>(im))+1) );
        std::snprintf(header_fmt, sizeof(header_fmt), "%%4s%%4s%%-%lus %%%lus %%s\n", std::max(l, KEY.size()), std::max(di, SIZE.size()));
        std::snprintf(map_fmt, sizeof(map_fmt), "%%4s%%4s%%-%lus %%%lud %%s",   std::max(l, KEY.size()), std::max(di, SIZE.size()));
        //std::printf("%s", header_fmt);
        //std::printf("%s\n", map_fmt);

        message(SUB_TITLE_FMT, " ", "Double type std::vector(s)");
        message(header_fmt,    " ", " ", KEY.c_str(), SIZE.c_str(), VALUE.c_str());
        for(std::map<std::string, std::vector<Double> >::iterator i_vector=vectorMap.begin(); i_vector != vectorMap.end(); ++i_vector) {
            message(map_fmt, " ", " ", i_vector->first.c_str(), i_vector->second.size(), "(");
            for (std::vector<Double>::iterator id=i_vector->second.begin();id != i_vector->second.end(); ++id) {
                message(" %g", *id); // << " " << *(id);
            }
            message(")\n");
        }
        message("\n");
    }

    if ( ! matrixMap.empty() ) {
        size_t l=0, im=0, jm=0;
        for (std::map<std::string, std::vector< std::vector<Double> > >::iterator i=matrixMap.begin(); i != matrixMap.end(); ++i) {
            if ( i->first.size()     > l  ) { l =i->first.size();     }
            if ( i->second.size()    > im ) { im=i->second.size();    }
            if ( i->second[0].size() > jm ) { jm=i->second[0].size(); }
        }
        size_t di=( im=0 ? 1 : (UInt4)(log10(static_cast<Double>(im))+1) );
        size_t dj=( jm=0 ? 1 : (UInt4)(log10(static_cast<Double>(jm))+1) );
        //std::cerr << "Debug AdvParamSet::dump : l=" << l << std::endl;
        //std::cerr << "Debug AdvParamSet::dump : (di, dj)=(" << di << ", " << dj << ")" << std::endl;
        //std::cerr << "Debug AdvParamSet::dump : SIZE.size()=" << SIZE.size() << std::endl;
        //Char header_fmt[16+10+1], map_fmt[21+10+1];
	Char header_fmt[100], map_fmt[100];
        //std::sprintf(header_fmt, "    %%-%lus %%%lus %%s\n",        std::max(l, KEY.size()), std::max(di+dj+1, SIZE.size()));
        std::snprintf(map_fmt, sizeof(map_fmt), "%%4s%%4s%%-%lus %%%lulu*%%%lulu %%s", std::max(l, KEY.size()), di, dj);
        std::snprintf(header_fmt, sizeof(header_fmt), "%%4s%%4s%%-%lus %%%lus %%s\n",        std::max(l, KEY.size()), std::max(di+dj+1, SIZE.size()));
        //std::printf("%s", header_fmt);
        //std::printf("%s\n", map_fmt);

        message(SUB_TITLE_FMT, " ", "Double type matrix(s)");
        message(header_fmt,    " ", " ", KEY.c_str(), SIZE.c_str(), "matrix");
        for (std::map<std::string, std::vector< std::vector<Double> > >::iterator i_matrix=matrixMap.begin(); i_matrix != matrixMap.end(); ++i_matrix) {
            message(map_fmt,       " ", " ", i_matrix->first.c_str(), i_matrix->second.size(), i_matrix->second[0].size(), "(");
            for (std::vector< std::vector<Double> >::iterator i=i_matrix->second.begin(); i != i_matrix->second.end(); ++i) {
                message(" (");
                for (std::vector<Double>::iterator j=i->begin(); j != i->end(); ++j) {
                    message(" %g", *j);
                }
                message(")");
            }
            message(")\n");
        }
        message("\n");

        //std::cout << "Double type matrix(s)" << std::endl;
        //std::printf(header_fmt, KEY.c_str(), SIZE.c_str(), "matrix");
        //for (std::map<std::string, std::vector< std::vector<Double> > >::iterator i_matrix=matrixMap.begin(); i_matrix != matrixMap.end(); ++i_matrix) {
        //    std::printf(map_fmt, i_matrix->first.c_str(), i_matrix->second.size(), i_matrix->second[0].size(), "(");
        //    for (std::vector< std::vector<Double> >::iterator i=i_matrix->second.begin(); i != i_matrix->second.end(); ++i) {
        //        std::cout << " (";
        //        for (std::vector<Double>::iterator j=i->begin(); j != i->end(); ++j) {
        //            std::cout << " " << *j;
        //        }
        //        std::cout << ")";
        //    }
        //    std::cout << ")" <<std::endl;
        //}
        //std::cout << std::endl;
    }

    if ( ! peakDataMap.empty() ) {
        size_t l=0, nP=0;
        for (std::map<std::string, AdvPeakData>::iterator i_AdvPeakData=peakDataMap.begin(); i_AdvPeakData != peakDataMap.end(); ++i_AdvPeakData) {
            if ( i_AdvPeakData->first.size() > l ) { l = i_AdvPeakData->first.size(); }
            if ( i_AdvPeakData->second.size() > nP ) { nP = i_AdvPeakData->second.size(); }
            //std::cerr << "Debug AdvParamSet::dump : l=" << l << std::endl;
            //std::cerr << "Debug AdvParamSet::dump : nP=" << nP << std::endl;
        } 
        size_t di = (nP==0 ? 1 : (UInt4)(log10(static_cast<Double>(nP))+1));
        Char header_fmt[16+10+10+1], map_fmt[16+10+10+1];
        //std::sprintf(header_fmt, "    %%-%lus %%%lus %%s\n", std::max(l, KEY.size()), std::max(di, SIZE.size()));
        std::snprintf(header_fmt, sizeof(header_fmt), "%%4s%%4s%%-%lus %%%lus %%s\n", std::max(l, KEY.size()), std::max(di, SIZE.size()));
        std::snprintf(map_fmt, sizeof(map_fmt), "%%4s%%4s%%-%lus %%%lulu %%s",  std::max(l, KEY.size()), std::max(di, SIZE.size()));
        //std::printf("%s", header_fmt);
        //std::printf("%s\n", map_fmt);

        message(SUB_TITLE_FMT, " ", "Peak Data");
        message(header_fmt,    " ", " ", KEY.c_str(), SIZE.c_str(), "Peaks");
        for (std::map<std::string, AdvPeakData>::iterator i_AdvPeakData=peakDataMap.begin(); i_AdvPeakData != peakDataMap.end(); ++i_AdvPeakData) {
            message(map_fmt, " ", " ", i_AdvPeakData->first.c_str(), i_AdvPeakData->second.size(), "(");
            std::vector<Double> v=i_AdvPeakData->second.toFullVector();
            for (UInt4 i=0; i<i_AdvPeakData->second.size(); ++i) {
                message(" (");
                for (UInt4 j=0; j<AdvPeak::fullSize; ++j) {
                    message(" %g", v.at(AdvPeak::fullSize*i+j));
                }
                message(")");
            }
            message(")\n");
        }
        message("\n");
    }

    if ( ! funcListMap.empty() ) {

        size_t l=0, im=0;
        for (std::map<std::string, std::vector<AdvFuncBase*> >::iterator i_funcList=funcListMap.begin(); i_funcList != funcListMap.end(); ++i_funcList) {
            if (i_funcList->first.size()  > l  ) { l =i_funcList->first.size();    }
            if (i_funcList->second.size() > im ) { im=i_funcList->second.size(); }
        }
        size_t di = (im==0 ? 1 : (UInt4)(log10(static_cast<Double>(im)+1)));
        Char header_fmt[16+10+10+1], map_fmt[16+10+10+1];
        std::snprintf(header_fmt, sizeof(header_fmt), "%%4s%%4s%%-%lus %%%lus %%s\n", std::max(l, KEY.size()),  std::max(di, SIZE.size()));
        std::snprintf(map_fmt, sizeof(map_fmt), "%%4s%%4s%%-%lus %%%lulu %%s",  std::max(l, KEY.size()), std::max(di, SIZE.size()));

        message(SUB_TITLE_FMT, " ", "List of Functions");
        message(header_fmt,    " ", " ", KEY.c_str(), SIZE.c_str(), "functions");
        for (std::map<std::string, std::vector<AdvFuncBase*> >::iterator i_funcList=funcListMap.begin(); i_funcList != funcListMap.end(); ++i_funcList) {
            message(map_fmt, " ", " ", i_funcList->first.c_str(), i_funcList->second.size(), "(");
            for (std::vector<AdvFuncBase*>::iterator i=i_funcList->second.begin(); i != i_funcList->second.end(); ++i) {
                message(" %s", (*i)->getSymbol().c_str());
            }
            message(")\n");
        }
        message("\n");

    }

    if ( ! funcMatrixMap.empty() ) {
        size_t l=0, im=0, jm=0;
        for (std::map<std::string, std::vector< std::vector<Double> > >::iterator i=matrixMap.begin(); i != matrixMap.end(); ++i) {
            if ( i->first.size()     > l  ) { l =i->first.size();     }
            if ( i->second.size()    > im ) { im=i->second.size();    }
            if ( i->second[0].size() > jm ) { jm=i->second[0].size(); }
        }
        size_t di=( im=0 ? 1 : (UInt4)(log10(static_cast<Double>(im))+1) );
        size_t dj=( jm=0 ? 1 : (UInt4)(log10(static_cast<Double>(jm))+1) );
        //Char header_fmt[16+10+1], map_fmt[21+10+1];
	Char header_fmt[100], map_fmt[100];
        //std::sprintf(header_fmt, "    %%-%lus %%%lus %%s\n",        std::max(l, KEY.size()), std::max(di+dj+1, SIZE.size()));
        std::snprintf(map_fmt, sizeof(map_fmt), "%%4s%%4s%%-%lus %%%lulu*%%%lulu %%s", std::max(l, KEY.size()), di, dj);
        std::snprintf(header_fmt, sizeof(header_fmt), "%%4s%%4s%%-%lus %%%lus %%s\n",        std::max(l, KEY.size()), std::max(di+dj+1, SIZE.size()));

        message(SUB_TITLE_FMT, " ", "Set of Functions List");
        message(header_fmt,    " ", " ", KEY.c_str(), SIZE.c_str(), "set(s) of lists");
        for (std::map<std::string, std::vector< std::vector<AdvFuncBase*> > >::iterator i_funcMatrix=funcMatrixMap.begin(); i_funcMatrix != funcMatrixMap.end(); ++i_funcMatrix) {
            message(map_fmt, " ", " ", i_funcMatrix->first.c_str(), i_funcMatrix->second.size(), i_funcMatrix->second[0].size(), "(");
            for (std::vector< std::vector<AdvFuncBase*> >::const_iterator funcList=i_funcMatrix->second.begin(); funcList != i_funcMatrix->second.end(); ++funcList) {
                message(" (");
                for (std::vector<AdvFuncBase*>::const_iterator fp=funcList->begin(); fp != funcList->end(); ++fp) {
                    message(" %s", (*fp)->getSymbol().c_str());
                }
                message(")");
            }
            message(")\n");
        }
    }
}

/**
 * \retval true if no data is registed
 */
Bool AdvParamSet::empty() const {

    return (
        BoolMap.empty() &&
        Int4Map.empty() && UInt4Map.empty() && DoubleMap.empty() &&
        vectorMap.empty() && matrixMap.empty() &&
        peakDataMap.empty() && funcListMap.empty() && funcMatrixMap.empty()
    );
}


/** 
 *  get the value of the Int4 type data with the given key
 */
Int4 AdvParamSet::getInt4(const std::string &key) const {
    Int4 retval;

    if (Int4Map.empty()) {
        std::cerr << "Error: AdvParamSet::getInt4 : no Int4 type parameter registed" << std::endl;
        return 0;
    }

    if ( Int4Map.find(key) == Int4Map.end() ) {
        std::cerr << "Error: AdvParamSet::getInt4 : key for the Int4 type parameter not found: " << key << std::endl;
        return 0;
    } else {
        retval = Int4Map.find(key)->second;
    }
    return retval;
}


/**
 *  get the value of the Bool type data with the given key
 */
Bool AdvParamSet::getBool(const std::string &key) const {

#ifdef CAST_TO_INT
    return static_cast<Bool>(getInt4(key));
#else
    Bool retval;
    if ( BoolMap.empty() ) {
        //throw std::invalid_argument("no Bool type parameter registed: ");
        std::cerr << " Error: AdvParamSet::getBool(const std::string&) : no Bool type parameter registed: " << key << std::endl;
        retval=false;
    }

    if ( BoolMap.find(key) == BoolMap.end() ) {
        std::cerr << " Error: AdvParamSet::getBool(const std::string&) : key for Bool type parameter not found: " << key << std::endl;
        retval=false;
    } else {
        retval = BoolMap.find(key)->second;
    }
    return retval;
#endif
}


/** 
 *  get the value of the UInt4 type data with the given key
 */
UInt4 AdvParamSet::getUInt4(const std::string &key) const {

#ifdef CAST_TO_INT
    return static_cast<UInt4>(getInt4(key));
#else
    UInt4 retval;
    if (UInt4Map.empty()) {
        std::cerr << "Error: AdvParamSet::getInt4 : no Int4 type parameter registed" << std::endl;
        return 0;
    }

    if ( UInt4Map.find(key) == UInt4Map.end() ) {
        std::cerr << "Error: AdvParamSet::getInt4 : key for the Int4 type parameter not found: " << key << std::endl;
        return 0;
    } else {
        retval = UInt4Map.find(key)->second;
    }
    return retval;
#endif

}


/** 
 *  get the value of the Double type data with the given key
 */
Double AdvParamSet::getDouble(const std::string &key) const {
    Double retval;

    if ( DoubleMap.empty() ) {
        std::cerr << "Error: AdvParamSet::getDouble : no Double type paameter registed" << std::endl;
        retval = 0.0;
    }

    std::map<std::string, Double>::iterator i_Double;
    if ( DoubleMap.find(key) == DoubleMap.end()) {
        std::cerr << "Error: AdvParamSet::getDouble : key for Int4type  parameter not found: " << key << std::endl;
        retval = 0.0;
    } else {
        retval = DoubleMap.find(key)->second;
    }
    return retval;
}


/** 
 *  get the Double type  std::vector with the given key
 */
std::vector<Double> AdvParamSet::getVector(const std::string &key) const {
    std::vector<Double> tmp;
    if ( vectorMap.empty() ) {
        std::cerr << "Error: AdvParamSet::getVector(const std::string&): no std::vector registed: " << key << std::endl;
        return tmp;
    }
    if ( vectorMap.find(key) == vectorMap.end() ) {
        std::cerr << "Error: AdvParamSet::getVector(const std::string&): the vector with specified key not found: " << key << std::endl;
        return tmp;
    }

    return vectorMap.find(key)->second;
}


/** 
 *  get the value of the specified component of the Double type  std::vector with the given key
 *  
 *  @param[in] key
 *  @param[in] i        the index of the componet
 */
Double AdvParamSet::getDouble(const std::string &key, const UInt4 i) const {
    if ( vectorMap.empty() ) {
        std::cerr << "Error: AdvParamSet::getDouble(const std::string&, const UInt4): no std::vector registed: " << key << std::endl;
        return 0.0;
    }
    if ( vectorMap.find(key) == vectorMap.end() ) {
        std::cerr << "Error: AdvParamSet::getDouble(const std::string&, const UInt4): the vector with specified key not found: " << key << std::endl;
        return 0.0;
    }
    if ( ! (0 <= i && i < vectorMap.find(key)->second.size()) ) {
        std::cerr << "Error: AdvParamSet::getDouble(const std::string&, const UInt4): out of range : " << i << ", " << key << std::endl;
        return 0.0;
    }

    return vectorMap.find(key)->second.at(i);

}

UInt4 AdvParamSet::getVectorSize(const std::string &key) const {

    if ( vectorMap.empty() ) {
        return 0U;
    }
    if ( vectorMap.find(key) == vectorMap.end() ) {
        std::cerr << "Error: AdvParamSet::getDouble(const std::string&, const UInt4): the vector with specified key not found: " << key << std::endl;
        return 0U;
    }

    return vectorMap.find(key)->second.size();
}


/** 
 *  get the Double type  matrix with the given key
 *  
 *  @param[in] key
 */
std::vector< std::vector<Double> > AdvParamSet::getMatrix(const std::string &key) const {
    std::vector< std::vector<Double> > tmp;
    if ( matrixMap.empty() ) {
        std::cerr << "Error: AdvParamSet::getMatrix(const std::string&): no matrix registed: " << key << std::endl;
        return tmp;
    }
    if ( matrixMap.find(key) == matrixMap.end() ) {
        std::cerr << "Error: AdvParamSet::getMatrix(const std::string&): the matrix with the specified key not found: " << key << std::endl;
        return tmp;
    }

    return matrixMap.find(key)->second;
}


/** 
 *  get the value of the specified component of the Double type  matrix with the given key
 *  
 *  @param[in] key
 *  @param[in] i        row index of the componenet
 *  @param[in] j        column index of the component
 */
Double AdvParamSet::getDouble(const std::string &key, const UInt4 i, const UInt4 j) const 
{
    if ( matrixMap.empty() ) {
        std::cerr << "Error: AdvParamSet::getDouble(const std::string&, const UInt4, const UInt4): no matrix registed: " << key << std::endl;
        return 0.0;
    }
    if ( matrixMap.find(key) == matrixMap.end() ) {
        std::cerr << "Error: AdvParamSet::getDouble(const std::string&, const UInt4, const UInt4): the matrix with the specified key not found: " << key << std::endl;
        return 0.0;
    }
    if ( ! (0 <= i && i < matrixMap.find(key)->second.size() ) ) {
        std::cerr << "Error: AdvParamSet::getDouble(const std::string&, const UInt4, const UInt4): row index id out of range: " << i << ", " << key << std::endl;
        return 0.0;
    }
    if ( ! (0 <= j && j < matrixMap.find(key)->second[0].size() ) ) {
        std::cerr << "Error: AdvParamSet::getDouble(const std::string&, const UInt4, const UInt4): column index id out of range: " << j << ", " << key << std::endl;
        return 0.0;
    }
    return matrixMap.find(key)->second.at(i).at(j);
}

/**
 *  get the size of row of the matrix with key
 */
UInt4 AdvParamSet::getRowSize(const std::string &key) const {

    if ( matrixMap.empty() ) {
        std::cerr << "Error: AdvParamSet::getRowSize(const std::string&): no matrix registed: " << key << std::endl;
        return 0U;
    }
    if ( matrixMap.find(key) == matrixMap.end() ) {
        std::cerr << "Error: AdvParamSet::getRowSize(const std::string&): the matrix with the specified key not found: " << key << std::endl;
        return 0U;
    }
    return matrixMap.find(key)->second.size();
}


UInt4 AdvParamSet::getColumnSize(const std::string &key) const {

    if ( matrixMap.empty() ) {
        std::cerr << "Error: AdvParamSet::getColumnSize(const std::string&): no matrix registed: " << key << std::endl;
        return 0U;
    }
    if ( matrixMap.find(key) == matrixMap.end() ) {
        std::cerr << "Error: AdvParamSet::getColumnSize(const std::string&): the matrix with the specified key not found: " << key << std::endl;
        return 0U;
    }
    return matrixMap.find(key)->second[0].size();
}

/**
 *  get the value of AdvPeakData type parameter with the given key
 *
 *  @param[in] key
 */
AdvPeakData AdvParamSet::getPeakData(const std::string &key) const {

    if ( peakDataMap.empty() ) {
        std::cerr << "Error: AdvParamSet::getPeakData(const std::string &): no PeakDara registed: " << key << std::endl;
        return *(new AdvPeakData());
    }
    return peakDataMap.find(key)->second;
}

/**
 *
 */

std::vector<AdvFuncBase*> AdvParamSet::getFuncList(const std::string &key) const {
    if ( funcListMap.empty() ) {
        std::cerr << "Error: AdvParamSet::getFuncList(const std::string&): no list of functions registed: " << key << std::endl;
        return *(new std::vector<AdvFuncBase*>());
    }
    if ( funcListMap.find(key) == funcListMap.end() ) {
        std::cerr << "Error: AdvParamSet::getFuncList(const std::string&): not foune the value with the given key: " << key << std::endl;
        return *(new std::vector<AdvFuncBase*>());
    }
    return funcListMap.find(key)->second;
}

std::vector<AdvFuncBase*> *AdvParamSet::getFuncListP(const std::string &key) const {
    if ( funcListMap.empty() ) {
        std::cerr << "Error: AdvParamSet::getFuncList(const std::string&): no list of functions registed: " << key << std::endl;
        return new std::vector<AdvFuncBase*>();
    }
    if ( funcListMap.find(key) == funcListMap.end() ) {
        std::cerr << "Error: AdvParamSet::getFuncList(const std::string&): not found the value with the given key: " << key << std::endl;
        return new std::vector<AdvFuncBase*>();
    }
    std::vector<AdvFuncBase*>::const_iterator b=funcListMap.find(key)->second.begin();
    std::vector<AdvFuncBase*>::const_iterator e=funcListMap.find(key)->second.end();
    return (new std::vector<AdvFuncBase*>(b, e));
}

std::vector< std::vector<AdvFuncBase*> > AdvParamSet::getFuncMatrix(const std::string &key) const {
    if ( funcMatrixMap.empty() ) {
        std::cerr << "Error: AdvParamSet::getFuncMatrix(const std::string&): no matrix of functions registed: " << key << std::endl;
        return *(new std::vector< std::vector<AdvFuncBase*> >());
    }
    if ( funcMatrixMap.find(key) == funcMatrixMap.end() ) {
        std::cerr << "Error: AdvParamSet::getFuncMatrix(const std::string&): not found the value with the given key: " << key << std::endl;
        return *(new std::vector< std::vector<AdvFuncBase*> >());
    }
    return funcMatrixMap.find(key)->second;
}

/** 
 *  return a list of keys registed
 *  
 *  @return a list of keys registed
 */
std::vector<std::string> AdvParamSet::getKeyList() const {

    std::vector<std::string> *keyList=new std::vector<std::string>();
    keyList->clear();
    std::cout << "Debug AdvParamSet::getKeyLis()" << std::endl;

    if ( ! BoolMap.empty() ) {
        for (std::map<std::string, Bool>::const_iterator i=BoolMap.begin(); i != BoolMap.end(); ++i) {
            keyList->push_back(std::string(i->first));
        }
    }
    std::cout << "Debug AdvParamSet::getKeyLis() BoolMap" << std::endl;
    if ( ! Int4Map.empty() ) {
        for (std::map<std::string, Int4>::const_iterator i=Int4Map.begin(); i != Int4Map.end(); ++i) {
            keyList->push_back(std::string(i->first));
        }
    }
    std::cout << "Debug AdvParamSet::getKeyLis() Int4Map" << std::endl;
    if ( ! UInt4Map.empty() ) {
        for (std::map<std::string, UInt4>::const_iterator i=UInt4Map.begin(); i != UInt4Map.end(); ++i) {
            keyList->push_back(std::string(i->first));
        }
    }
    std::cout << "Debug AdvParamSet::getKeyLis() UInt4Map" << std::endl;
    if ( ! DoubleMap.empty() ) {
        for (std::map<std::string, Double>::const_iterator i=DoubleMap.begin(); i != DoubleMap.end(); ++i) {
            keyList->push_back(std::string(i->first));
        }
    }
    std::cout << "Debug AdvParamSet::getKeyLis() DoubleMap" << std::endl;
    if ( ! vectorMap.empty() ) {
        for (std::map<std::string, std::vector<Double> >::const_iterator i=vectorMap.begin(); i != vectorMap.end(); ++i) {
            keyList->push_back(std::string(i->first));
        }
    }
    std::cout << "Debug AdvParamSet::getKeyLis() vectorMap" << std::endl;
    if ( ! matrixMap.empty() ) {
       for (std::map<std::string, std::vector< std::vector<Double> > >::const_iterator i=matrixMap.begin(); i != matrixMap.end(); ++i) {
           keyList->push_back(std::string(i->first));
       }
    }
    std::cout << "Debug AdvParamSet::getKeyLis() matrixMap" << std::endl;
    if ( ! peakDataMap.empty() ) {
        for (std::map<std::string, AdvPeakData>::const_iterator i=peakDataMap.begin(); i != peakDataMap.end(); ++i) {
            keyList->push_back(std::string(i->first));
        }
    }
    std::cout << "Debug AdvParamSet::getKeyLis() peakDataMap" << std::endl;
    if ( ! funcListMap.empty() ) {
        for (std::map<std::string, std::vector<AdvFuncBase*> >::const_iterator i=funcListMap.begin(); i != funcListMap.end(); ++i) {
            keyList->push_back(std::string(i->first));
        }
    }
    std::cout << "Debug AdvParamSet::getKeyLis() funcListMap" << std::endl;
    if ( ! funcMatrixMap.empty() ) {
        for (std::map<std::string, std::vector< std::vector<AdvFuncBase*> > >::const_iterator i=funcMatrixMap.begin(); i != funcMatrixMap.end(); ++i) {
            keyList->push_back(std::string(i->first));
        }
    }
    std::cout << "Debug AdvParamSet::getKeyLis() funcMatrixMap" << std::endl;
    return *keyList;
}


/** 
 *  key (and the value(s) for the parameter with the key) is contained the param set
 *  
 *  @param[in] key the key for a parameter
 *  @retval true, if the this contains the key
 *  @retval false, otherwise
 */
Bool AdvParamSet::contain(const std::string &key) const 
{
    return ( ( BoolMap.find(key)       != BoolMap.end()    ) ||
             ( Int4Map.find(key)       != Int4Map.end()    ) ||
             ( UInt4Map.find(key)      != UInt4Map.end()   ) ||
             ( DoubleMap.find(key)     != DoubleMap.end()  ) ||
             ( vectorMap.find(key)     != vectorMap.end()  ) ||
             ( matrixMap.find(key)     != matrixMap.end()  ) ||
             ( peakDataMap.find(key)   != peakDataMap.end()) ||
             ( funcListMap.find(key)   != funcListMap.end()) ||
             ( funcMatrixMap.find(key) != funcMatrixMap.end()) );
}

