int Dictionary_Entry_Value_AsInt( Dictionary_Entry_Value* self ) {
	if( !self ) {
		return 0;
	}
	
	switch( self->type ) {
		case Dictionary_Entry_Value_Type_Struct:
			/* Do nothing (later will print a warning) */
			return 0;
		case Dictionary_Entry_Value_Type_List:
			/* returns the first element as an unsigned int */
			if (self->as.typeList->first) {
				return Dictionary_Entry_Value_AsInt( self->as.typeList->first );
			} else {	
				return 0;
			}	
		case Dictionary_Entry_Value_Type_String:
			return strtoul( self->as.typeString, 0, 0 );
		case Dictionary_Entry_Value_Type_Double:
			return (unsigned int)self->as.typeDouble;
		case Dictionary_Entry_Value_Type_UnsignedInt:
			return self->as.typeUnsignedInt;
		case Dictionary_Entry_Value_Type_Int:
			return self->as.typeInt;
		case Dictionary_Entry_Value_Type_UnsignedLong:
			return self->as.typeUnsignedLong;
		case Dictionary_Entry_Value_Type_Bool:
			return (unsigned int)self->as.typeBool;
		default: {
			Stream* errorStream = Journal_Register( Error_Type, "Dictionary_Entry_Value" );
			Journal_Firewall( False, errorStream, "In func %s: self->type '%d' is invalid.\n", __func__, self->type );
		}
	}
	return 0;
}
int Dictionary_GetInt_WithDefault(
   Dictionary*          dictionary,
   Dictionary_Entry_Key key,
   const int            defaultVal )
{
   return Dictionary_Entry_Value_AsInt( 
      Dictionary_GetDefault(
         dictionary, key, Dictionary_Entry_Value_FromInt( defaultVal ) ) );
}
void _UnderworldContext_Init( UnderworldContext* self ) {
	self->isConstructed = True;

	/* always generate XDMF files when we generate HDF5 checkpoints */
#ifdef WRITE_HDF5
	if( Dictionary_Entry_Value_AsBool( Dictionary_GetDefault( self->dictionary, "generateXDMF", Dictionary_Entry_Value_FromBool( True ) ) ) ){
		ContextEP_Append( self, AbstractContext_EP_Save, XDMFGenerator_GenerateAll );
		ContextEP_Append( self, AbstractContext_EP_DataSave, XDMFGenerator_GenerateAll );

      if( Dictionary_Entry_Value_AsInt( Dictionary_GetDefault( self->dictionary, "checkpointEvery"    , Dictionary_Entry_Value_FromInt( 0 ) ) )  ||
          Dictionary_Entry_Value_AsInt( Dictionary_GetDefault( self->dictionary, "saveDataEvery"      , Dictionary_Entry_Value_FromInt( 0 ) ) )	 ||
          Dictionary_Entry_Value_AsInt( Dictionary_GetDefault( self->dictionary, "checkpointAtTimeInc", Dictionary_Entry_Value_FromInt( 0 ) ) )
            ){
            ContextEP_Append( self, AbstractContext_EP_Build, XDMFGenerator_GenerateTemporalTopLevel );
      }
	}
#endif
   
}
Dictionary_Entry_Value* Dictionary_Entry_Value_FromStringTo( char* string, char type ) {
	Dictionary_Entry_Value* retValue = Memory_Alloc( Dictionary_Entry_Value, "Return Value" );
	
	/* need to create the value temporarily so it can be converted if necessary */
	retValue->type = Dictionary_Entry_Value_Type_String;

	if ( string ) {
		retValue->as.typeString = ExpandEnvironmentVariables( string );
	}
	else {
		retValue->as.typeString = string;
	}
	
	switch (type) {
		case Dictionary_Entry_Value_Type_String:
			Dictionary_Entry_Value_InitFromString( retValue, retValue->as.typeString );
			break;
		case Dictionary_Entry_Value_Type_Double:
			Dictionary_Entry_Value_InitFromDouble( retValue, Dictionary_Entry_Value_AsDouble( retValue ) );
			break;
		case Dictionary_Entry_Value_Type_UnsignedInt:
			Dictionary_Entry_Value_InitFromUnsignedInt( retValue, Dictionary_Entry_Value_AsUnsignedInt( retValue ) );
			break;
		case Dictionary_Entry_Value_Type_Int:
			Dictionary_Entry_Value_InitFromInt( retValue, Dictionary_Entry_Value_AsInt( retValue ) );
			break;
		case Dictionary_Entry_Value_Type_UnsignedLong:
			Dictionary_Entry_Value_InitFromUnsignedLong( retValue, Dictionary_Entry_Value_AsUnsignedLong( retValue ) );
			break;
		case Dictionary_Entry_Value_Type_Bool:
			Dictionary_Entry_Value_InitFromBool( retValue, Dictionary_Entry_Value_AsBool( retValue ) );
			break;
		case Dictionary_Entry_Value_Type_Struct:
			Dictionary_Entry_Value_InitNewStruct( retValue );
			break;
		case Dictionary_Entry_Value_Type_List:
			Dictionary_Entry_Value_InitNewList( retValue );
			break;
		default: {
			Stream* errorStream = Journal_Register( Error_Type, "Dictionary_Entry_Value" );
			Journal_Firewall( False, errorStream, "In func %s: type '%d' is invalid.\n", __func__, type );
		}
	}		
	
	return retValue;
}
void Dictionary_Entry_Value_SetFromStringKeepCurrentType( Dictionary_Entry_Value* self, char* string ) {
	Dictionary_Entry_Value_Type currType = self->type;
	Dictionary_Entry_Value_DeleteContents( self );
	self->type = Dictionary_Entry_Value_Type_String;
	self->as.typeString = string;
	
	switch (currType) {
		case Dictionary_Entry_Value_Type_String:
			Dictionary_Entry_Value_SetValueString( self, string );
			break;
		case Dictionary_Entry_Value_Type_Double:
			Dictionary_Entry_Value_SetValueDouble( self, Dictionary_Entry_Value_AsDouble( self ) );
			break;
		case Dictionary_Entry_Value_Type_UnsignedInt:
			Dictionary_Entry_Value_SetValueUnsignedInt( self, Dictionary_Entry_Value_AsUnsignedInt( self ) );
			break;
		case Dictionary_Entry_Value_Type_Int:
			Dictionary_Entry_Value_SetValueInt( self, Dictionary_Entry_Value_AsInt( self ) );
			break;
		case Dictionary_Entry_Value_Type_UnsignedLong:
			Dictionary_Entry_Value_SetValueUnsignedLong( self, Dictionary_Entry_Value_AsUnsignedLong( self ) );
			break;
		case Dictionary_Entry_Value_Type_Bool:
			Dictionary_Entry_Value_SetValueBool( self, Dictionary_Entry_Value_AsBool( self ) );
			break;
		case Dictionary_Entry_Value_Type_Struct:
			Dictionary_Entry_Value_SetValueNewStruct( self );
			break;
		case Dictionary_Entry_Value_Type_List:
			Dictionary_Entry_Value_SetValueNewList( self );
			break;
		default: {
			Stream* errorStream = Journal_Register( Error_Type, "Dictionary_Entry_Value" );
			Journal_Firewall( False, errorStream, "In func %s: self->type '%d' is invalid.\n", __func__, self->type );
		}
	}
}
int Stg_ComponentFactory_PluginGetInt( void* cf, void *codelet, Dictionary_Entry_Key key, int defaultVal ) {
   return Dictionary_Entry_Value_AsInt( 
                _Stg_ComponentFactory_PluginGetNumericalValue( cf, codelet, key, 
                                                               Dictionary_Entry_Value_FromInt( defaultVal )));
}
Bool Stg_ComponentFactory_TryInt( void* cf, Name componentName, Dictionary_Entry_Key key, int* value ) {
   Dictionary_Entry_Value* dict_value = _Stg_ComponentFactory_GetNumericalValue( cf, componentName, key, NULL);
   if (!dict_value) return False;
   *value = Dictionary_Entry_Value_AsInt(dict_value);
   return True;
}
int _Stg_ComponentFactory_GetInt( void* cf, Name componentName, Dictionary_Entry_Key key, int defaultVal ) {
   return Dictionary_Entry_Value_AsInt( 
         _Stg_ComponentFactory_GetNumericalValue( cf, componentName, key, 
            Dictionary_Entry_Value_FromInt( defaultVal ) ) );
}   
Bool Dictionary_Entry_Value_CompareFull( Dictionary_Entry_Value* self, Dictionary_Entry_Value* dev, Bool strictTypeCheck ) {
	Bool         retValue = True; 
	Stream*      errorStream = Journal_Register( Error_Type, "Dictionary_Entry_Value" );

	if ( strictTypeCheck ) {
		if ( self->type != dev->type ) {
			return False;
		}
	}

	switch( self->type ) {
		case Dictionary_Entry_Value_Type_String: {
			/* Comparing as strings is tricky. When both are strings it's fine. If the dev to compare to is stored
			 * natively as a number, we should convert the first to a number also for comparison. Otherwise, you
			 * can get false Negatives when the entries are numerically the same, but use different notation
			 * (e.g. scientific vs decimal) */ 	
			switch( dev->type ) {
				case Dictionary_Entry_Value_Type_String:
					if ( 0 != strcmp( self->as.typeString, dev->as.typeString ) ) 
						retValue = False;
					break;
				case Dictionary_Entry_Value_Type_Double:
					if ( dev->as.typeDouble != Dictionary_Entry_Value_AsDouble( self ) )
						retValue = False;
					break;
				case Dictionary_Entry_Value_Type_UnsignedInt:
					if ( dev->as.typeUnsignedInt != Dictionary_Entry_Value_AsUnsignedInt( self ) )
						retValue = False;
					break;
				case Dictionary_Entry_Value_Type_Int:
					if ( dev->as.typeInt != Dictionary_Entry_Value_AsInt( self ) )
						retValue = False;
					break;
				case Dictionary_Entry_Value_Type_UnsignedLong:
					if ( dev->as.typeUnsignedLong != Dictionary_Entry_Value_AsUnsignedLong( self ) )
						retValue = False;
					break;
				case Dictionary_Entry_Value_Type_Bool:
					if ( dev->as.typeBool != Dictionary_Entry_Value_AsBool( self ) )
				case Dictionary_Entry_Value_Type_Struct:
				case Dictionary_Entry_Value_Type_List:
					retValue = False;
					break;
				default:
					Journal_Firewall( False, errorStream, "In func %s: dev->type '%d' is invalid.\n", __func__, dev->type );
			}
			break;
		}
		case Dictionary_Entry_Value_Type_Double:
			if ( self->as.typeDouble != Dictionary_Entry_Value_AsDouble( dev ) )
				retValue = False;
			break;
		case Dictionary_Entry_Value_Type_UnsignedInt:
			if ( self->as.typeUnsignedInt != Dictionary_Entry_Value_AsUnsignedInt( dev ) )
				retValue = False;
			break;
		case Dictionary_Entry_Value_Type_Int:
			if ( self->as.typeInt != Dictionary_Entry_Value_AsInt( dev ) )
				retValue = False;
			break;
		case Dictionary_Entry_Value_Type_UnsignedLong:
			if ( self->as.typeUnsignedLong != Dictionary_Entry_Value_AsUnsignedLong( dev ) )
				retValue = False;
			break;
		case Dictionary_Entry_Value_Type_Bool:
			if ( self->as.typeBool != Dictionary_Entry_Value_AsBool( dev ) )
				retValue = False;
			break;
		case Dictionary_Entry_Value_Type_Struct:
			if ( dev->type != Dictionary_Entry_Value_Type_Struct ) {
				retValue = False;
				break;
			}
			retValue = Dictionary_CompareAllEntriesFull( self->as.typeStruct, dev->as.typeStruct, strictTypeCheck );
			break;
		case Dictionary_Entry_Value_Type_List: {
			Dictionary_Entry_Value* cur1 = NULL;
			Dictionary_Entry_Value* cur2 = NULL;

			if ( dev->type != Dictionary_Entry_Value_Type_List ) {
				retValue = False;
				break;
			}
			if ( self->as.typeList->count != dev->as.typeList->count ) {
				retValue = False;
				break;
			}
			cur1 = self->as.typeList->first;
			cur2 = dev->as.typeList->first;
			while ( cur1 ) {
				retValue = Dictionary_Entry_Value_CompareFull( cur1, cur2, strictTypeCheck );
				if ( retValue == False ) break;
				cur1 = cur1->next;
				cur2 = cur2->next;
			}	
			break;
		}
		default:
			Journal_Firewall( False, errorStream, "In func %s: self->type '%d' is invalid.\n", __func__, self->type );
	};

	return retValue;
}