void _RSGenerator_AssignFromXML( void* meshGenerator, Stg_ComponentFactory* cf, void* data )
{
   RSGenerator*			self 		= (RSGenerator*)meshGenerator;
   FiniteElementContext*	context 	= Stg_ComponentFactory_ConstructByName( cf, (Name)"context", FiniteElementContext, True, NULL  );
   Dictionary*			dict		= Dictionary_Entry_Value_AsDictionary( Dictionary_Get( cf->componentDict, (Dictionary_Entry_Key)self->name ) );
   Dictionary_Entry_Value	*minList, *maxList, *tmp;
   char*			rootKey;
   unsigned			d_i;
   double 			maxVal;

   _CartesianGenerator_AssignFromXML( meshGenerator, cf, data );

   // mesh min/max coords are written to file from the mesh->min/maxGlobalCoord field. these differ from the min/max
   // coords as defined in the RSGenerator->min/maxCrd (these are in r-theta-phi, not x-y-z), so if we're restarting
   // we need to over-ride the coords from the hdf5 mesh file with those from the xml (assuming they don't differ
   // between runs...
   if( self->nDims > 2 ) {
      if( context->loadFromCheckPoint ) {
         minList = Dictionary_Get( dict, (Dictionary_Entry_Key)"minCoord" );
         maxList = Dictionary_Get( dict, (Dictionary_Entry_Key)"maxCoord" );
         if( minList && maxList ) {
                assert( Dictionary_Entry_Value_GetCount( minList ) >= self->nDims );
                assert( Dictionary_Entry_Value_GetCount( maxList ) >= self->nDims  );
                for( d_i = 0; d_i < self->nDims; d_i++ ) {
                   tmp = Dictionary_Entry_Value_GetElement( minList, d_i );
                   rootKey = Dictionary_Entry_Value_AsString( tmp );

                   if( !Stg_StringIsNumeric( (char*)rootKey ) )
                      tmp = Dictionary_Get( cf->rootDict, (Dictionary_Entry_Key)rootKey );
                   self->crdMin[d_i] = Dictionary_Entry_Value_AsDouble( tmp );

                   tmp = Dictionary_Entry_Value_GetElement( maxList, d_i );
                   rootKey = Dictionary_Entry_Value_AsString( tmp );

                   if( !Stg_StringIsNumeric( (char*)rootKey ) )
                      tmp = Dictionary_Get( cf->rootDict, (Dictionary_Entry_Key)rootKey );
                   self->crdMax[d_i] = Dictionary_Entry_Value_AsDouble( tmp );
                   /* test to ensure provided domain is valid */
                   maxVal = (abs(self->crdMax[d_i]) > abs(self->crdMin[d_i])) ? abs(self->crdMax[d_i]) : abs(self->crdMin[d_i]);
                   if( maxVal == 0 ) maxVal = 1;  /* if maxVal is zero, then both numbers must be zero, set to one as next test will fail */
                   Journal_Firewall( ( ( (self->crdMax[d_i] - self->crdMin[d_i])/maxVal) > 1E-10 || d_i==J_AXIS), global_error_stream,
                     "\n\nError in %s for %s '%s'\n\n"
                     "Dimension of domain (min = %f, max = %f) for component number %u is not valid.\n\n",
                     __func__, self->type, self->name, self->crdMin[d_i], self->crdMax[d_i], d_i );
                }
         }
      }
      // phi = (pi/2, pi)
      Journal_Firewall( !(fabs(self->crdMin[2] -self->crdMax[2])>=179.99 || self->crdMax[2] < self->crdMin[2]),
         global_error_stream, "\nError in %s: Phi definition is wrong. Ensure minZ < maxZ & abs(minZ-maxZ)<180\n", __func__);
   }
   Journal_Firewall( self->nDims==3, global_error_stream,
        "Error in %s: Must have 3 dimensions for component %s\n", __func__, self->name );
   // check domain size is valid
   Journal_Firewall( !(self->crdMin[0] <= 0 || self->crdMax[0] < self->crdMin[0]), global_error_stream,
        "Error in %s: Radius definition is wrong. Ensure maxX > minX & minX > 0\n", __func__ );

   Journal_Firewall(!( fabs(self->crdMin[1]-self->crdMax[1]) >= 179.99 || self->crdMax[1] < self->crdMin[1] ),
         global_error_stream, "Error in %s: Theta definition is wrong. Ensure minY < maxY && abs(minY-maxY) < 180\n", __func__ );
}
Dictionary_Entry_Value* _Stg_ComponentFactory_PluginGetNumericalValue( void* cf, void *codelet, Dictionary_Entry_Key key, Dictionary_Entry_Value* defaultVal ) {
   Stg_ComponentFactory*    self           = (Stg_ComponentFactory*)cf;
   Dictionary_Entry_Value* returnVal;
   Bool                    usedDefault       = False;
   Stream*                 stream            = self->infoStream;
   Stream*         errorStream       = Journal_Register( Error_Type, self->type );

   Journal_Firewall( self != NULL, errorStream, "In func %s: Stg_Component is NULL.\n", __func__ );

   returnVal = _Stg_ComponentFactory_PluginGetDictionaryValue( self, codelet, key, defaultVal );

   /* Check to see whether the type is a string -
    * if it is then assume that this is a dictionary key linking to the root dictionary */
   if ( returnVal ) {
      Dictionary_Entry_Key rootDictKey = Dictionary_Entry_Value_AsString( returnVal );
      Dictionary*          rootDict    = self->rootDict;

      /* Check if the number really is a string or not */
      if ( Stg_StringIsNumeric( rootDictKey ) )
         return returnVal;
      
      Journal_PrintfL( stream, 2, "Key '%s' points to key '%s' in the root dictionary: ", key, rootDictKey );

      Journal_Firewall( rootDict != NULL, errorStream, "Root Dictionary NULL in component factory.\n" );

      /* Get Value from dictionary */
      returnVal = Dictionary_Get( rootDict, rootDictKey );
      if ( !returnVal && defaultVal ) {
         returnVal = Dictionary_GetDefault( rootDict, rootDictKey, defaultVal );
         usedDefault = True;
      }

      /* Print Stuff */
      if ( usedDefault ) {
         Journal_PrintfL( stream, 2, "Using default value = " );
         if ( Stream_IsPrintableLevel( stream, 2 ) ) 
            Dictionary_Entry_Value_Print( returnVal, stream );
         Journal_PrintfL( stream, 2, "\n" );
         return returnVal;
      }
      else if ( returnVal ) {
         Journal_PrintfL( stream, 2, "Found - Value = " );
         if ( Stream_IsPrintableLevel( stream, 2 ) ) 
            Dictionary_Entry_Value_Print( returnVal, stream );
         Journal_PrintfL( stream, 2, "\n" );
      }
      else 
         Journal_PrintfL( stream, 2, "Not found.\n" );
   }

   return returnVal;
}
Dictionary_Entry_Value* _Dictionary_GetDouble_WithScopeDefault(
   Dictionary*             dictionary,
   Dictionary_Entry_Key    key,
   Dictionary_Entry_Value* defaultVal )
{
   Dictionary_Entry_Value *returnVal=NULL;
   Bool                    usedDefault = False;
   Stream*                 stream = Journal_Register( Info_Type, "Dictionary" );

   returnVal = Dictionary_GetDefault( dictionary, key, defaultVal );

   if( returnVal && returnVal->type == Dictionary_Entry_Value_Type_String ) { 
      Dictionary_Entry_Key rootDictKey = Dictionary_Entry_Value_AsString( returnVal ); 
      Dictionary*          rootDict    = dictionary; 

      /* Check if the number really is a string or not */ 
      if( Stg_StringIsNumeric( rootDictKey ) ) 
         return returnVal; 

      Journal_PrintfL(
         stream,
         2,
         "Key '%s' points to key '%s' in the root dictionary: ",
         key,
         rootDictKey ); 

      /* Get Value from dictionary */ 
      returnVal = Dictionary_Get( rootDict, rootDictKey ); 
      if( !returnVal && defaultVal ) { 
         returnVal = Dictionary_GetDefault( rootDict, rootDictKey, defaultVal ); 
         usedDefault = True; 
      } 

      /* Print Stuff */ 
      if( usedDefault ) { 
         Journal_PrintfL( stream, 2, "Using default value = " ); 
         if( Stream_IsPrintableLevel( stream, 2 ) )  
            Dictionary_Entry_Value_Print( returnVal, stream ); 
            Journal_PrintfL( stream, 2, "\n" ); 
         return returnVal; 
      } 
      else if( returnVal ) { 
         Journal_PrintfL( stream, 2, "Found - Value = " ); 
         if( Stream_IsPrintableLevel( stream, 2 ) )  
            Dictionary_Entry_Value_Print( returnVal, stream ); 
         Journal_PrintfL( stream, 2, "\n" ); 
      } 
      else  
         Journal_PrintfL( stream, 2, "Not found.\n" ); 
   } 
   return returnVal;
}
void TestIsStringNumeric( Stream* stream, char* string ) {
	Journal_Printf( stream, "Stg_StringIsNumeric( '%s' ) = %s\n", 
			string, Stg_StringIsNumeric( string ) ? "True" : "False" );
}