int
OperatorUtils::LoadMatrix( const QString& inFileName, Param& outParam )
{
  if( inFileName.isEmpty() )
    return MatNotFound;

  if( QFileInfo( inFileName ).suffix() == MATRIX_EXTENSION )
  {
    ParamList paramsFromFile;
    paramsFromFile.Load( inFileName.toLocal8Bit().constData(), true );
    if( paramsFromFile.Size() == 0 )
      return MatNotFound;
    if( paramsFromFile.Size() > 1 )
      return MatMultipleParams;
    Param p = paramsFromFile[0];
    outParam.SetDimensions( p.NumRows(), p.NumColumns() );
    for( int row = 0; row < p.NumRows(); ++row )
      for( int col = 0; col < p.NumColumns(); ++col )
        outParam.Value( row, col ) = p.Value( row, col );
    outParam.RowLabels() = p.RowLabels();
    outParam.ColumnLabels() = p.ColumnLabels();
  }
  else
  {
    ifstream input( inFileName.toLocal8Bit() );
    input.clear();
    vector<vector<string> > matrix;
    string line;
    while( getline( input, line ) )
    {
      istringstream is( line );
      vector<string> row;
      string value;
      while( getline( is, value, '\t' ) )
        row.push_back( value );
      if( !row.empty() )
        matrix.push_back( row );
    }
    if( matrix.empty() )
      return MatNotFound;

    size_t numRows = matrix.size(),
    numCols = matrix[ 0 ].size();
    for( size_t row = 1; row < numRows; ++row )
      if( matrix[ row ].size() != numCols )
        return MatLoadColsDiff;

    outParam.SetDimensions( numRows, numCols );
    for( size_t row = 0; row < numRows; ++row )
      for( size_t col = 0; col < numCols; ++col )
      {
        istringstream iss( matrix[ row ][ col ] );
        iss >> outParam.Value( row, col );
      }
  }
  return NoError;
}
void
_TParamDef::param_add_all( ParamList* inList, const char* inSectionPrefix, long inDefaultDimension )
{
  string  sectionPrefix( inSectionPrefix ),
          externalPrefix( "ext_" ),
          runtimeSuffix( RUNTIME_SUFFIX ),
          runtimeElement( RUNTIME_ELEMENT );
  for( list<_TParamDef*>::const_iterator i = _TParamDef::params().begin();
        i != params().end(); ++i )
  {
    Param p( ( *i )->definitionLine() );
    string section = p.Section();
    if( section.find( externalPrefix ) != 0 )
    {
      if( section != sectionPrefix )
      {
         section = sectionPrefix + "_" + section;
         p.SetSection( section );
      }
      string name = p.Name();
      size_t suffixPos = name.find( runtimeSuffix );
      if( suffixPos != name.npos )
      {
        p.SetType( "matrix" );
        string value = p.Value();
        size_t pos = value.find( runtimeSuffix );
        p.SetDimensions( inDefaultDimension + 1, 1 );
        for( int i = p.NumRows() - 1; i >= 0; --i )
        {
          // Replace RUNTIME_SUFFIX in the comment and use it as a row label.
          ostringstream os;
          os << i;
          string comment = p.Comment();
          size_t comment_pos = comment.find( runtimeSuffix );
          if( comment_pos != comment.npos )
            comment.replace( comment_pos, runtimeSuffix.length(), os.str() );
          p.RowLabels()[ i ] = comment;
          // Replace RUNTIME_SUFFIX in the parameter values.
          if( pos == value.npos )
            p.Value( i, 0 ) = value;
          else
          {
            string newValue = value;
            newValue.replace( pos, runtimeSuffix.length(), os.str() );
            p.Value( i, 0 ) = newValue;
          }
        }
        p.ColumnLabels()[ 0 ] = "";

        ostringstream oss;
        oss << p;
        string line = oss.str();
        // Replace RUNTIME_SUFFIX in the parameter name.
        pos = line.find( runtimeSuffix );
        if( pos != line.npos )
          line.replace( pos, runtimeSuffix.length(), "" );
        // Replace RUNTIME_SUFFIX in the comment.
        pos = line.rfind( runtimeSuffix );
        if( pos != line.npos )
          line.replace( pos, runtimeSuffix.length(), "N" );
        name.replace( suffixPos, runtimeSuffix.length(), "" );
        if( !inList->Exists( name ) )
          inList->Add( line );
      }
      else
      { // The parameter might be a special instance for a certain suffix.
        // This will only work for true suffices, i.e. at the end of the name.
        size_t pos = name.find_last_not_of( "0123456789" );
        Param* param = NULL;
        if( pos != name.length() - 1 )
        {
          string paramName = name.substr( 0, pos + 1 );
          if( inList->Exists( paramName ) )
            param = &( *inList )[ paramName ];
        }
        if( param != NULL && string( "matrix" ) == param->Type() )
        {
          long suffix = ::atoi( name.substr( pos ).c_str() );
          param->Value( suffix, 0 ) = p.Value();
          param->RowLabels()[ suffix ] = p.Comment();
        }
        else if( !PARAM_EXISTS( inList, p.Name() ) )
        {
          ostringstream oss;
          oss << p;
          string line = oss.str();
          // Runtime elements are not supported, the user must supply a value.
          size_t rtPos;
          while( ( rtPos = line.find( runtimeElement ) ) != line.npos )
            line.replace( rtPos, runtimeElement.length(), "N/A" );
          inList->Add( line );
        }
      }
    }
  }
}