CXMLAttribute* Engine::FileSystem::Config::CXMLElement::FindOrCreateAttribute( const char* name )
{
	CXMLAttribute* last = 0;
	CXMLAttribute* attrib = 0;
	for( attrib = rootAttribute;
		 attrib;
		 last = attrib, attrib = attrib->next )
	{		 
		if ( CXMLUtil::StringEqual( attrib->Name(), name ) ) {
			break;
		}
	}
	if ( !attrib ) {
		attrib = new (document->attributePool.Alloc() ) CXMLAttribute();
		attrib->XMLMemPool = &document->attributePool;
		if ( last ) {
			last->next = attrib;
		}
		else {
			rootAttribute = attrib;
		}
		attrib->SetName( name );
	}
	return attrib;
}
const CXMLAttribute* Engine::FileSystem::Config::CXMLElement::FindAttribute( const char* name ) const
{
	CXMLAttribute* a = 0;
	for( a=rootAttribute; a; a = a->next ) {
		if ( CXMLUtil::StringEqual( a->Name(), name ) )
			return a;
	}
	return 0;
}
char* Engine::FileSystem::Config::CXMLElement::ParseAttributes( char* p )
{
	const char* start = p;
	CXMLAttribute* prevAttribute = 0;

	// Read the attributes.
	while( p ) {
		p = CXMLUtil::SkipWhiteSpace( p );
		if ( !p || !(*p) ) {
			document->SetError( XML_ERROR_PARSING_ELEMENT, start, Name() );
			return 0;
		}

		// attribute.
		if ( CXMLUtil::IsAlpha( *p ) ) {
			CXMLAttribute* attrib = new (document->attributePool.Alloc() ) CXMLAttribute();
			attrib->XMLMemPool = &document->attributePool;

			p = attrib->ParseDeep( p, document->ProcessEntities() );
			if ( !p || Attribute( attrib->Name() ) ) {
				DELETE_ATTRIBUTE( attrib );
				document->SetError( XML_ERROR_PARSING_ATTRIBUTE, start, p );
				return 0;
			}
			// There is a minor bug here: if the attribute in the source xml
			// document is duplicated, it will not be detected and the
			// attribute will be doubly added. However, tracking the 'prevAttribute'
			// avoids re-scanning the attribute list. Preferring performance for
			// now, may reconsider in the future.
			if ( prevAttribute ) { 
				prevAttribute->next = attrib;
			}
			else {
				rootAttribute = attrib;
			}	
			prevAttribute = attrib;
		}
		// end of the tag
		else if ( *p == '/' && *(p+1) == '>' ) {
			closingType = CLOSED;
			return p+2;	// done; sealed element.
		}
		// end of the tag
		else if ( *p == '>' ) {
			++p;
			break;
		}
		else {
			document->SetError( XML_ERROR_PARSING_ELEMENT, start, p );
			return 0;
		}
	}
	return p;
}