/*
$Id: UInt4Container.cc 2110 2010-04-07 04:35:47Z jisuzuki $
*/


#include "UInt4Container.hh"
////////////////////////////////////////////////////////
UInt4Container::
UInt4Container()
{
  v.clear();
  s.clear();
  vd.clear();
  sd.clear();

  header = new HeaderBase();

  PythonConverter = NULL;
}
////////////////////////////////////////////////////////
/*
UInt4Container::
UInt4Container( HeaderBase Header )
{
  v.clear();
  s.clear();
  vd.clear();
  sd.clear();

  header = new HeaderBase();
  *header = Header;

  PythonConverter = NULL;
}
*/
////////////////////////////////////////////////////////
UInt4Container::
UInt4Container( HeaderBase *Header )
{
  v.clear();
  s.clear();
  vd.clear();
  sd.clear();

  header = new HeaderBase(*Header);

  PythonConverter = NULL;
}
////////////////////////////////////////////////////////
UInt4Container::
UInt4Container( const UInt4Container &ob )
{
  header = new HeaderBase();
  *header = *( ob.header );

  s.clear();
  v.clear();
  vd.clear();
  sd.clear();

  ///////////////////////////////
  UInt4 Ssize = (UInt4)(ob.s.size());
  for( UInt4 i=0; i<Ssize; i++ ){
    s.push_back( ob.s[i] );
  }

  UInt4 Vsize = (UInt4)(ob.v.size());
  for( UInt4 i=0; i<Vsize; i++){
    std::vector<UInt4> *NewVec = new std::vector<UInt4>;
    *NewVec = *( ( ob.v )[i] );
    v.push_back( NewVec );
  }
  ///////////////////////////////
  UInt4 Sdsize = (UInt4)(ob.sd.size());
  for( UInt4 i=0; i<Sdsize; i++ ){
    sd.push_back( ob.sd[i] );
  }

  UInt4 Vdsize = (UInt4)(ob.vd.size());
  for( UInt4 i=0; i<Vdsize; i++){
    std::vector<Double> *NewVec = new std::vector<Double>;
    *NewVec = *( ( ob.vd )[i] );
    vd.push_back( NewVec );
  }
  ///////////////////////////////

  PythonConverter = NULL;
}
/////////////////////////////////////////////////////////
UInt4Container UInt4Container ::
operator=( const UInt4Container &ob )
{
  if( ob.header != NULL ){
    if( header != NULL ){
      delete header;
    }
    header = new HeaderBase();
    *header = *( ob.header );
  }
  else{
    header = NULL;
  }

  //////////////////////////
  s.clear();
  UInt4 size = (UInt4)(v.size());
  for( UInt4 i=0; i<size; i++ ){
    delete v[i];
  }
  v.clear();

  UInt4 Ssize = (UInt4)(ob.s.size());
  for( UInt4 i=0; i<Ssize; i++){
    s.push_back( ob.s[i] );
  }

  UInt4 Vsize = (UInt4)(ob.v.size());
  for( UInt4 i=0; i<Vsize; i++){
    std::vector<UInt4> *NewVec = new std::vector<UInt4>;
    *NewVec = *( ( ob.v )[i] );
    v.push_back( NewVec );
  }
  //////////////////////////
  sd.clear();
  UInt4 sized = (UInt4)(vd.size());
  for( UInt4 i=0; i<sized; i++ ){
    delete vd[i];
  }
  vd.clear();

  UInt4 Sdsize = (UInt4)(ob.sd.size());
  for( UInt4 i=0; i<Sdsize; i++){
    sd.push_back( ob.sd[i] );
  }

  UInt4 Vdsize = (UInt4)(ob.vd.size());
  for( UInt4 i=0; i<Vdsize; i++){
    std::vector<Double> *NewVec = new std::vector<Double>;
    *NewVec = *( ( ob.vd )[i] );
    vd.push_back( NewVec );
  }
  //////////////////////////

  if( PythonConverter != NULL ){
    delete PythonConverter;
  }
  PythonConverter = NULL;

  return *this;
}
////////////////////////////////////////////////////////
UInt4Container::
~UInt4Container()
{
  if( header != NULL ){
    delete header; // Delete the header object.
  }

  //////////////////////////////////////
  s. clear(); // Clear std::string std::vector.
  UInt4 size = (UInt4)(v.size());
  for( UInt4 i=0; i<size; i++ ){ // Delete each vector object
    delete v[ i ];
  }                              // stored in "v".
  v.clear();
  //////////////////////////////////////
  sd. clear(); // Clear std::string std::vector.
  UInt4 sized = (UInt4)(vd.size());
  for( UInt4 i=0; i<sized; i++ ){ // Delete each vector object
    delete vd[ i ];
  }                              // stored in "v".
  vd.clear();
  //////////////////////////////////////

  if( PythonConverter != NULL ){
    delete PythonConverter;
  }
}
////////////////////////////////////////////////////////
HeaderBase UInt4Container::
PutHeader()
{
  HeaderBase tmpH;
  tmpH = *header;
  return tmpH;
}
////////////////////////////////////////////////////////
void UInt4Container::
SetupPythonConverter()
{
  if( PythonConverter == NULL ){
    PythonConverter = new CppToPython();
  }
}
////////////////////////////////////////////////////////
UInt4 UInt4Container::
PutIndexNumber( std::string Key )
{
  UInt4 size = (UInt4)(s.size());
  std::vector<std::string> :: iterator S = s.begin();
  for( UInt4 i=0; i<size; i++ ){
    if( S[i] == Key ){
      return i;
    }
  }
  std::cout << "UInt4Container::PutIndexNumber(Key)" << std::endl;
  std::cout << "Cannot find your Key !"              << std::endl;
  return 0;
}
////////////////////////////////////////////////////////
UInt4 UInt4Container::
PutIndexNumberDouble( std::string Key )
{
  UInt4 size = (UInt4)(sd.size());
  std::vector<std::string> :: iterator Sd = sd.begin();
  for( UInt4 i=0; i<size; i++ ){
    if( Sd[i] == Key ){
      return i;
    }
  }
  std::cout << "UInt4Container::PutIndexNumberDouble(Key)" << std::endl;
  std::cout << "Cannot find your Key !"              << std::endl;
  return 0;
}
////////////////////////////////////////////////////////
void UInt4Container::
InputHeader( HeaderBase Header )
{
  delete header;
  header = new HeaderBase();
  *header = Header;
}
////////////////////////////////////////////////////////
void UInt4Container::
DumpKey()
{
  UInt4 size = (UInt4)(s.size());
  for( UInt4 i=0; i<size; i++ ){
    std::cout << "std::vector<UInt4>" << "\t" << i << "\t"
              << s[i] << std::endl;
  }
  size = (UInt4)(sd.size());
  for( UInt4 i=0; i<size; i++ ){
    std::cout << "std::vector<Double>" << "\t" << i << "\t"
              << sd[i] << std::endl;
  }
}
////////////////////////////////////////////////////////
void UInt4Container::
Add( std::string Key, std::vector< UInt4 > value )
{
  if( CheckKey( Key ) != 0 ){
    std::cout << "\"" << Key
              << "\" has been installed in this container."
              << std::endl;
    std::cout << "Please choose another Key." << std::endl;
    return;
  }

  UInt4 size = (UInt4)(value.size());
  //std::vector<UInt4> *vec = new std::vector<UInt4>( size );
  std::vector<UInt4> *vec;
  try{
    vec = new std::vector<UInt4>( size );
  }
  catch( std::bad_alloc error ){
    std::cout << "UInt4Container::Add()" << std::endl;
    std::cout << "Out of memory " << error.what() << std::endl;
    return;
  }

  for( UInt4 i=0; i<size; i++ ){
    ( *vec )[i] = value[i];
  }
  s.push_back( Key );
  v.push_back( vec );
}
////////////////////////////////////////////////////////
void UInt4Container::
AddDouble( std::string Key, std::vector< Double > value )
{
  if( CheckKeyDouble( Key ) != 0 ){
    std::cout << "\"" << Key
              << "\" has been installed in this container."
              << std::endl;
    std::cout << "Please choose another Key." << std::endl;
    return;
  }

  UInt4 size = (UInt4)(value.size());
  //std::vector<Double> *vec = new std::vector<Double>( size );
  std::vector<Double> *vec;
  try{
    vec = new std::vector<Double>( size );
  }
  catch( std::bad_alloc error ){
    std::cout << "UInt4Container::Add()" << std::endl;
    std::cout << "Out of memory " << error.what() << std::endl;
    return;
  }
  for( UInt4 i=0; i<size; i++ ){
    ( *vec )[i] = value[i];
  }
  sd.push_back( Key );
  vd.push_back( vec );
}
////////////////////////////////////////////////////////
UInt4 UInt4Container::
CheckKey( std::string Key )
{
  UInt4 flag = 0;
  UInt4 size = (UInt4)(s.size());
  for( UInt4 index=0; index<size; index++ ){
    if( s[index] == Key ){
      flag = flag + 1;
    }
  }
  return flag;
}
////////////////////////////////////////////////////////
UInt4 UInt4Container::
CheckKeyDouble( std::string Key )
{
  UInt4 flag = 0;
  UInt4 size = (UInt4)(sd.size());
  for( UInt4 index=0; index<size; index++ ){
    if( sd[index] == Key ){
      flag = flag + 1;
    }
  }
  return flag;
}
////////////////////////////////////////////////////////
void UInt4Container::
Add( std::string Key, UInt4 *&Array, UInt4 ArraySize )
{
  if( CheckKey( Key ) != 0 ){
    std::cout << "\"" << Key << "\" has been installed in this container." << std::endl;
    std::cout << "Please choose another Key." << std::endl;
    return;
  }

  //std::vector<UInt4> *vec = new std::vector<UInt4>( ArraySize );
  std::vector<UInt4> *vec;
  try{
    vec = new std::vector<UInt4>( ArraySize );
  }
  catch( std::bad_alloc error ){
    std::cout << "UInt4Container::Add()" << std::endl;
    std::cout << "Out of memory " << error.what() << std::endl;
    return;
  }
  for( UInt4 i=0; i<ArraySize; i++ ){
    ( *vec )[ i ] = Array[ i ];
  }
  s.push_back( Key );
  v.push_back( vec );
}
////////////////////////////////////////////////////////
void UInt4Container::
AddDouble( std::string Key, Double *&Array, UInt4 ArraySize )
{
  if( CheckKeyDouble( Key ) != 0 ){
    std::cout << "\"" << Key << "\" has been installed in this container." << std::endl;
    std::cout << "Please choose another Key." << std::endl;
    return;
  }

  //std::vector<Double> *vec = new std::vector<Double>( ArraySize );
  std::vector<Double> *vec;
  try{
    vec = new std::vector<Double>( ArraySize );
  }
  catch( std::bad_alloc error ){
    std::cout << "UInt4Container::Add()" << std::endl;
    std::cout << "Out of memory " << error.what() << std::endl;
    return;
  }
  for( UInt4 i=0; i<ArraySize; i++ ){
    ( *vec )[ i ] = Array[ i ];
  }
  sd.push_back( Key );
  vd.push_back( vec );
}
////////////////////////////////////////////////////////
void UInt4Container::
Add( std::string Key, PyObject *value )
{
  if( CheckKey( Key ) != 0 ){
    std::cout << "\"" << Key << "\" has been installed in this container." << std::endl;
    std::cout << "Please choose another Key." << std::endl;
    return;
  }
  SetupPythonConverter();
  std::vector<UInt4> TmpVec = PythonConverter -> ListToUInt4Vector( value );

  UInt4 size = (UInt4)(TmpVec.size());
  std::vector<UInt4> *vec;
  try{
    vec = new std::vector<UInt4>( size );
  }
  catch( std::bad_alloc error ){
    std::cout << "UInt4Container::Add()" << std::endl;
    std::cout << "Out of memory " << error.what() << std::endl;
    return;
  }

  for( UInt4 i=0; i<size; i++ ){
    ( *vec )[ i ] = TmpVec[ i ];
  }
  s.push_back( Key );
  v.push_back( vec );
}
////////////////////////////////////////////////////////
void UInt4Container::
AddDouble( std::string Key, PyObject *value )
{
  if( CheckKeyDouble( Key ) != 0 ){
    std::cout << "\"" << Key << "\" has been installed in this container." << std::endl;
    std::cout << "Please choose another Key." << std::endl;
    return;
  }
  SetupPythonConverter();
  std::vector<Double> TmpVec = PythonConverter -> ListToDoubleVector( value );
  UInt4 size = (UInt4)(TmpVec.size());

  std::vector<Double> *vec;
  try{
    vec = new std::vector<Double>( size );
  }
  catch( std::bad_alloc error ){
    std::cout << "UInt4Container::Add()" << std::endl;
    std::cout << "Out of memory " << error.what() << std::endl;
    return;
  }
  for( UInt4 i=0; i<size; i++ ){
    ( *vec )[ i ] = TmpVec[ i ];
  }
  sd.push_back( Key );
  vd.push_back( vec );
}
////////////////////////////////////////////////////////
std::vector<UInt4> UInt4Container::
Put( UInt4 IndexNumber )
{
  UInt4 size = (UInt4)(s.size());
  if( IndexNumber >= size ){
    std::cout << "UInt4Container::Put(index)" << std::endl;
    std::cout << "Input index size is too large" << std::endl;
    std::cout << "Anyway, a blank vector is returned." << std::endl;

    std::vector<UInt4> vec;
    vec.clear();
    return vec;
  }

  return *( v[IndexNumber] );
}
///////////////////////////////////////////////////////////
std::vector<Double> UInt4Container::
PutDouble( UInt4 IndexNumber )
{
  UInt4 size = (UInt4)(sd.size());
  if( IndexNumber >= size ){
    std::cout << "UInt4Container::PutDouble(index)" << std::endl;
    std::cout << "Input index size is too large" << std::endl;
    std::cout << "Anyway, a blank vector is returned." << std::endl;

    std::vector<Double> vec;
    vec.clear();
    return vec;
  }

  return *( vd[IndexNumber] );
}
///////////////////////////////////////////////////////////
std::vector<UInt4> UInt4Container::
Put( std::string Key )
{
  UInt4 size = (UInt4)(s.size());
  std::vector<std::string> :: iterator S = s.begin();
  for( UInt4 i=0; i<size; i++ ){
    if( S[i] == Key ){
      return *( v[ i ] );
    }
  }
  std::cout << "UInt4Container::Put(Key)" << std::endl;
  std::cout << "Cannot find your Key !"   << std::endl;
  std::cout << "Anyway, a blank vector is returned." << std::endl;
  std::vector<UInt4> vec;
  vec.clear();
  return vec;
}
///////////////////////////////////////////////////////////
std::vector<Double> UInt4Container::
PutDouble( std::string Key )
{
  UInt4 size = (UInt4)(sd.size());
  std::vector<std::string> :: iterator S = sd.begin();
  for( UInt4 i=0; i<size; i++ ){
    if( S[i] == Key ){
      return *( vd[ i ] );
    }
  }
  std::cout << "UInt4Container::PutDouble(Key)" << std::endl;
  std::cout << "Cannot find your Key !"   << std::endl;
  std::cout << "Anyway, a blank vector is returned." << std::endl;
  std::vector<Double> vec;
  vec.clear();
  return vec;
}
///////////////////////////////////////////////////////////
UInt4 UInt4Container::
Put( std::string Key, UInt4 Index )
{
  return ( Put( PutIndexNumber( Key ) ) )[ Index ];
}
///////////////////////////////////////////////////////////
Double UInt4Container::
PutDouble( std::string Key, UInt4 Index )
{
  return ( PutDouble( PutIndexNumberDouble( Key ) ) )[ Index ];
}
///////////////////////////////////////////////////////////
PyObject * UInt4Container::
PutList( std::string Key )
{
  std::vector<UInt4> vec = Put( Key );
  SetupPythonConverter();
  return PythonConverter -> VectorToList( vec );
}
///////////////////////////////////////////////////////////
PyObject * UInt4Container::
PutListDouble( std::string Key )
{
  std::vector<Double> vec = PutDouble( Key );
  SetupPythonConverter();
  return PythonConverter -> VectorToList( vec );
}
///////////////////////////////////////////////////////////
void UInt4Container::
Dump()
{
  if( header != NULL ){
    header -> Dump();
  }
  DumpValue();
}
///////////////////////////////////////////////////////////
void UInt4Container::
DumpValue()
{
  /*
  if( header != NULL ){
    header -> Dump();
  }
  */

  UInt4 Size = (UInt4)(s.size());
  for( UInt4 i=0; i<Size; i++ ){
    std::cout << "std::vector<UInt4>  " << s[ i ] << " [";
    std::vector<UInt4> target = *( v[ i ] );
    UInt4 TargetSize = (UInt4)(target.size());
    for( UInt4 j=0; j<TargetSize-1; j++ ){
      std::cout << target[j] << ",";
    }
    std::cout << target[TargetSize-1] << "]" << std::endl;
  }

  /*
  UInt4 SizeD = sd.size();
  for( UInt4 i=0; i<SizeD; i++ ){
    std::cout << "std::vector<Double> " << sd[ i ] << " [";
    std::vector<Double> target = *( vd[ i ] );
    UInt4 TargetSize = target.size();
    for( UInt4 j=0; j<TargetSize-1; j++ ){
      std::cout << target[j] << ",";
    }
    std::cout << target[TargetSize-1] << "]" << std::endl;
  }
  */
}
///////////////////////////////////////////////////////////
void UInt4Container::
DumpFromVectorContainer()
{
  UInt4 Size = (UInt4)(s.size());
  for( UInt4 i=0; i<Size; i++ ){
    std::cout << s[ i ]
              << "\t" << PutSize( i ) << "\t" << "[";
    std::vector<UInt4> target = *( v[ i ] );
    UInt4 TargetSize = (UInt4)(target.size());
    for( UInt4 j=0; j<TargetSize-1; j++ ){
      std::cout << target[j] << ",";
    }
    std::cout << target[TargetSize-1] << "]" << std::endl;
  }
}
///////////////////////////////////////////////////////////
void UInt4Container::
Dump( UInt4 size )
{
  if( header != NULL ){
    header -> Dump();
  }
  Dump( size );
}
///////////////////////////////////////////////////////////
void UInt4Container::
DumpValue( UInt4 size )
{
  /*
  if( header != NULL ){
    header -> Dump();
  }
  */

  UInt4 TableSize = PutSize();

  if( size == 0 ){
    for( UInt4 j=0; j<TableSize; j++ ){
      std::cout << j     << "\t"
                << PutName( j ) << "\t"
                << PutSize( j ) << "\t"
                << "[ ... ]"    << std::endl;
    }
  }

  else{
    for( UInt4 t=0; t<TableSize; t++ ){
      std::string key   = PutName( t );
      UInt4  depth = PutSize( t );

      std::cout << t     << "\t"
                << key   << "\t"
                << depth << "\t[ ";

      if( depth >= 1 && depth <= size ){
        std::vector<UInt4> V = Put( t );
        for( UInt4 d=0; d<depth-1; d++ ){
          std::cout << V[d] << ",";
        }
        std::cout << V[depth-1] << " ]" << std::endl;
      }

      else if( depth >= 1 && depth > size ){
        std::vector<UInt4> V = Put( t );
        for( UInt4 d=0; d<size-1; d++ ){
          std::cout << V[d] << ",";
        }
        std::cout << V[size-1] << " ,..... ]" << std::endl;
      }

      else{
        std::cout << "The size of vector is zero.]" << std::endl;
      }
    }
  }
}
///////////////////////////////////////////////////////////
void UInt4Container::
DumpFromVectorContainer( UInt4 size )
{
  UInt4 TableSize = PutSize();

  if( size == 0 ){
    for( UInt4 j=0; j<TableSize; j++ ){
      std::cout << PutName( j ) << "\t"
                << PutSize( j ) << "\t"
                << "[ ... ]"    << std::endl;
    }
  }

  else{
    for( UInt4 t=0; t<TableSize; t++ ){
      std::string key   = PutName( t );
      UInt4  depth = PutSize( t );

      std::cout << key   << "\t"
                << depth << "\t[ ";

      if( depth >= 1 && depth <= size ){
        std::vector<UInt4> V = Put( t );
        for( UInt4 d=0; d<depth-1; d++ ){
          std::cout << V[d] << ",";
        }
        std::cout << V[depth-1] << " ]" << std::endl;
      }

      else if( depth >= 1 && depth > size ){
        std::vector<UInt4> V = Put( t );
        for( UInt4 d=0; d<size-1; d++ ){
          std::cout << V[d] << ",";
        }
        std::cout << V[size-1] << " ,..... ]" << std::endl;
      }

      else{
        std::cout << "The size of vector is zero.]" << std::endl;
      }
    }
  }
}
///////////////////////////////////////////////////////////
std::string UInt4Container::
PutMergedKey()
{
  UInt4 Size = (UInt4)(s.size());

  if( Size == 0 ){
    return "NULL";
  }

  std::string str;
  str.clear();
  for( UInt4 i=0; i<Size-1; i++ ){
    str = str + s[ i ] + ",";
  }
  str = str + s[ Size-1 ];
  return str;
}
///////////////////////////////////////////////////////////
std::string UInt4Container::
PutMergedKeyDouble()
{
  UInt4 Size = (UInt4)(sd.size());

  if( Size == 0 ){
    return "NULL";
  }

  std::string str;
  str.clear();
  for( UInt4 i=0; i<Size-1; i++ ){
    str = str + sd[ i ] + ",";
  }
  str = str + sd[ Size-1 ];
  return str;
}
///////////////////////////////////////////////////////////
std::vector<UInt4>  UInt4Container::
PutSizeVector()
{
  UInt4 Size = (UInt4)(v.size());
  std::vector<UInt4> vec( Size );
  for( UInt4 i=0; i<Size; i++ ){
    //vec[ i ] = ( *( v[i] ) ).size();
    vec[ i ] = (UInt4)(v[i] -> size());
  }
  return vec;
}
///////////////////////////////////////////////////////////
std::vector<UInt4>  UInt4Container::
PutSizeVectorDouble()
{
  UInt4 Size = (UInt4)(vd.size());
  std::vector<UInt4> vec( Size );
  for( UInt4 i=0; i<Size; i++ ){
    //vec[ i ] = ( *( vd[i] ) ).size();
    vec[ i ] = (UInt4)(vd[i] -> size());
  }
  return vec;
}
///////////////////////////////////////////////////////////
std::vector<UInt4>  UInt4Container::
PutMergedDataVector()
{
  UInt4 TotalSize = 0;
  UInt4 Size = (UInt4)(v.size());
  for( UInt4 i=0; i<Size; i++ ){
    TotalSize = TotalSize + (UInt4)(v[i] -> size());
  }

  std::vector<UInt4> vec( TotalSize );
  std::vector<UInt4> *Target;
  UInt4 TargetSize;
  UInt4 k = 0;
  for( UInt4 i=0; i<Size; i++ ){
    Target = v[i];
    TargetSize = (UInt4)(Target -> size());
    for( UInt4 j=0; j<TargetSize; j++ ){
      vec[ k++ ] = ( *Target )[j];
    }
  }
  return vec;
}
///////////////////////////////////////////////////////////
std::vector<Double>  UInt4Container::
PutMergedDataVectorDouble()
{
  UInt4 TotalSize = 0;
  UInt4 Size = (UInt4)(vd.size());
  for( UInt4 i=0; i<Size; i++ ){
    TotalSize = TotalSize + (UInt4)(vd[i] -> size());
  }

  std::vector<Double> vec( TotalSize );
  std::vector<Double> *Target;
  UInt4 TargetSize;
  UInt4 k = 0;
  for( UInt4 i=0; i<Size; i++ ){
    Target = vd[i];
    TargetSize =(UInt4)( Target -> size());
    for( UInt4 j=0; j<TargetSize; j++ ){
      vec[ k++ ] = ( *Target )[j];
    }
  }
  return vec;
}
///////////////////////////////////////////////////////////
void UInt4Container::
MakeContainer( std::string MergedKey,
               std::vector<UInt4> SizeVector,
               std::vector<UInt4> MergedDataVector,
               HeaderBase h )
{
  InputHeader( h );

  if( MergedKey != "NULL" ){
    SplitString *ss = new SplitString();
    std::vector<std::string> KeyVector = ss -> Split( MergedKey, "," );
    delete ss;

    if( KeyVector.size() != SizeVector.size() ){
      std::cout << "UInt4Container::MakeContainer(....)" << std::endl;
      std::cout << "The std::vector sizes of the first and second arguments " << std::endl;
      std::cout << "are not equal. -- reject!!" << std::endl;
      return;
    }

    UInt4 TotalSize = 0;
    UInt4 SizeVectorSize = (UInt4)(SizeVector.size());
    for( UInt4 i=0; i<SizeVectorSize; i++ ){
      TotalSize = TotalSize + SizeVector[ i ];
    }
    if( MergedDataVector.size() != TotalSize ){
      std::cout << "UInt4Container::MakeContainer(....)" << std::endl;
      std::cout << "The std::vector size of the thired argument is ";
      std::cout << "inconsistent with the content of the second argument." << std::endl;
      return;
    }

    UInt4 k = 0;
    for( UInt4 j=0; j<SizeVectorSize; j++ ){
      s.push_back( KeyVector[j] );
      UInt4 VectorSize = SizeVector[ j ];
      std::vector<UInt4> *vec = new std::vector<UInt4>( VectorSize );
      for( UInt4 w=0; w<VectorSize; w++ ){
        ( *vec )[ w ] = MergedDataVector[ k++ ];
      }
      v.push_back( vec );
    }
  }
}
///////////////////////////////////////////////////////////
void UInt4Container::
MakeContainer( std::string MergedKey,
               std::vector<UInt4>  SizeVector,
               std::vector<UInt4>  MergedDataVector,
               std::string MergedKeyDouble,
               std::vector<UInt4>  SizeVectorDouble,
               std::vector<Double> MergedDataVectorDouble,
               HeaderBase h )
{
  InputHeader( h );

  if( MergedKey != "NULL" ){
    SplitString *ss = new SplitString();
    std::vector<std::string> KeyVector = ss -> Split( MergedKey, "," );
    delete ss;

    if( KeyVector.size() != SizeVector.size() ){
      std::cout << "UInt4Container::MakeContainer(....)" << std::endl;
      std::cout << "The std::vector sizes of the first and second arguments " << std::endl;
      std::cout << "are not equal. -- reject!!" << std::endl;
      return;
    }

    UInt4 TotalSize = 0;
    UInt4 SizeVectorSize = (UInt4)(SizeVector.size());
    for( UInt4 i=0; i<SizeVectorSize; i++ ){
      TotalSize = TotalSize + SizeVector[ i ];
    }
    if( MergedDataVector.size() != TotalSize ){
      std::cout << "UInt4Container::MakeContainer(....)" << std::endl;
      std::cout << "The std::vector size of the thired argument is ";
      std::cout << "inconsistent with the content of the second argument." << std::endl;
      return;
    }

    UInt4 k = 0;
    for( UInt4 j=0; j<SizeVectorSize; j++ ){
      s.push_back( KeyVector[j] );
      UInt4 VectorSize = SizeVector[ j ];
      std::vector<UInt4> *vec = new std::vector<UInt4>( VectorSize );
      for( UInt4 w=0; w<VectorSize; w++ ){
        ( *vec )[ w ] = MergedDataVector[ k++ ];
      }
      v.push_back( vec );
    }
  }

  ////////////////////////////////

  if( MergedKeyDouble != "NULL" ){
    SplitString *ss = new SplitString();
    std::vector<std::string> KeyVectorDouble = ss -> Split( MergedKeyDouble, "," );
    delete ss;

    if( KeyVectorDouble.size() != SizeVectorDouble.size() ){
      std::cout << "UInt4Container::MakeContainer(....)" << std::endl;
      std::cout << "The std::vector sizes of the first and second arguments " << std::endl;
      std::cout << "are not equal. -- reject!!" << std::endl;
      return;
    }

    UInt4 TotalSize = 0;
    UInt4 SizeVectorDoubleSize = (UInt4)(SizeVectorDouble.size());
    for( UInt4 i=0; i<SizeVectorDoubleSize; i++ ){
      TotalSize = TotalSize + SizeVectorDouble[ i ];
    }
    if( MergedDataVectorDouble.size() != TotalSize ){
      std::cout << "UInt4Container::MakeContainer(....)" << std::endl;
      std::cout << "The std::vector size of the thired argument is ";
      std::cout << "inconsistent with the content of the second argument." << std::endl;
      return;
    }

    UInt4 k = 0;

    for( UInt4 j=0; j<SizeVectorDoubleSize; j++ ){
      sd.push_back( KeyVectorDouble[j] );
      UInt4 VectorSizeDouble = SizeVectorDouble[ j ];
      std::vector<Double> *vec = new std::vector<Double>( VectorSizeDouble );
      for( UInt4 w=0; w<VectorSizeDouble; w++ ){
        ( *vec )[ w ] = MergedDataVectorDouble[ k++ ];
      }
      vd.push_back( vec );
    }
  }

}
///////////////////////////////////////////////////////////
std::vector<UInt4>* UInt4Container::
operator()( std::string Key )
{
  UInt4 size = (UInt4)(s.size());
  UInt4 index = 0;
  for( index=0; index<size; index++ ){
    if( s[index] == Key ){
      return v[index];
    }
  }

  std::cout << "UInt4Container::operator[]"            << std::endl;
  std::cout << "Cannot find your Key ! "      << Key     << std::endl;
  std::cout << "Anyway, NULL pointer is returned." << std::endl;

  return NULL;
}
/////////////////////////////////////////////////////////
std::vector<UInt4>* UInt4Container::
operator()( UInt4 index )
{
  UInt4 size = (UInt4)(s.size());
  if( index >= size ){
    std::cout << "UInt4Container::operator[](index)" << std::endl;
    std::cout << "Input index size is too large"       << std::endl;
    std::cout << "Anyway, NULL pointer is returned."   << std::endl;
    return NULL;
  }
  return v[index];
}
/////////////////////////////////////////////////////////
std::vector<UInt4>* UInt4Container::
operator[]( std::string Key )
{
  UInt4 size = (UInt4)(s.size());
  UInt4 index = 0;
  for( index=0; index<size; index++ ){
    if( s[index] == Key ){
      return v[index];
    }
  }

  std::cout << "UInt4Container::operator[]"            << std::endl;
  std::cout << "Cannot find your Key ! "      << Key     << std::endl;
  std::cout << "Anyway, NULL pointer is returned." << std::endl;

  return NULL;
}
/////////////////////////////////////////////////////////
std::vector<UInt4>* UInt4Container::
operator[]( UInt4 index )
{
  UInt4 size = (UInt4)(s.size());
  if( index >= size ){
    std::cout << "UInt4Container::operator[](index)" << std::endl;
    std::cout << "Input index size is too large"       << std::endl;
    std::cout << "Anyway, NULL pointer is returned."   << std::endl;
    return NULL;
  }
  return v[index];
}
/////////////////////////////////////////////////////////
ElementContainer UInt4Container::
ConvertIntoElementContainer()
{
  ElementContainer e;
  e.InputHeader( PutHeader() );
  UInt4 Usize = PutSize();
  for( UInt4 i=0; i<Usize; i++ ){
    e.Add( PutName( i ), Put( i ) );
  }
  return e;
}
/////////////////////////////////////////////////////////















