bool addSingleCustomBuildingConfig( TiXmlElement* elemRoot,  vector<BuildingConfiguration>* knownBuildings ){
	const char* strName = elemRoot->Attribute("name");
	const char* strGameID = elemRoot->Attribute("gameID");

	if (strName == NULL || strGameID == NULL || strName[0] == 0 || strGameID[0] == 0)
	{
		contentError("<building> node must have name and gameID attributes",elemRoot);
		return false;
	}

	int gameID = TranslateBuildingName(strGameID, contentLoader.custom_workshop_types );

	if (gameID == INVALID_INDEX) {
		return false;
	}

	BuildingConfiguration building(strName, gameID );
	RootBlock* spriteroot = new RootBlock();
	building.sprites = spriteroot;
	if (!parseSpriteNode(spriteroot,elemRoot))
	{
		delete(spriteroot);
		return false;
	}

	//add a copy of 'building' to known buildings
	knownBuildings->push_back( building );
	return true;
}
inline bool readNode(SpriteNode* node, TiXmlElement* elemNode, TiXmlElement* elemParent, SpriteBlock* &oldSibling)
{
	const char* strType = elemNode->Value();
	if (strcmp(strType, "if") == 0 || strcmp(strType, "else") == 0)
	{
		SpriteBlock* block = new SpriteBlock();
		if (!elemNode->Attribute("file") && elemParent->Attribute("file"))
		{
			elemNode->SetAttribute("file", elemParent->Attribute("file"));
		}
		if (!parseSpriteNode(block,elemNode))
		{
			delete(block);
			return false;
		}
		if (elemNode->Attribute("else") || strcmp(strType, "else") == 0)
		{
			if (!oldSibling)
			{
				contentError("Misplaced or invalid element in SpriteNode",elemNode);
				return false;						
			}
			oldSibling->addElse(block);	
		}
		else
		{
			node->addChild(block);
		}
		oldSibling = block;
	}
	else if (strcmp(strType, "rotate") == 0)
	{
		RotationBlock* block = new RotationBlock();
		if (!elemNode->Attribute("file") && elemParent->Attribute("file"))
		{
			elemNode->SetAttribute("file",elemParent->Attribute("file"));
		}
		if (!parseSpriteNode(block,elemNode))
		{
			delete(block);
			return false;
		}
		else
		{
			node->addChild(block);
		}
		oldSibling = NULL;
	}
	else if ((strcmp(strType, "sprite") == 0) || (strcmp(strType, "empty") == 0))
	{
		int fileindex = 0;
		const char* pfilename = elemParent->Attribute("file");
		if (pfilename != NULL && pfilename[0] != 0)
		{
			fileindex = loadConfigImgFile((char*)pfilename,elemNode);
		}
		SpriteElement* sprite = new SpriteElement();
		sprite->sprite.set_by_xml(elemNode, fileindex);
		node->addChild(sprite);
	}
	else if (strcmp(strType, "include") == 0)
	{
		if (!includeFile(node,elemNode,oldSibling))
		{
			return false;
		}
	}
	else
	{
		contentError("Misplaced or invalid element in SpriteNode",elemNode);
		return false;
	}		
	return true;
}
inline bool readNode(SpriteNode* node, TiXmlElement* elemNode, TiXmlElement* elemParent, SpriteBlock* &oldSibling)
{
	const char* strType = elemNode->Value();
	if (strcmp(strType, "if") == 0 || strcmp(strType, "else") == 0)
	{
		SpriteBlock* block = new SpriteBlock();
		if (!elemNode->Attribute("file") && elemParent->Attribute("file"))
		{
			elemNode->SetAttribute("file", elemParent->Attribute("file"));
		}
		if (!parseSpriteNode(block,elemNode))
		{
			delete(block);
			return false;
		}
		if (elemNode->Attribute("else") || strcmp(strType, "else") == 0)
		{
			if (!oldSibling)
			{
				contentError("Misplaced or invalid element in SpriteNode",elemNode);
				return false;						
			}
			oldSibling->addElse(block);	
		}
		else
		{
			node->addChild(block);
		}
		oldSibling = block;
	}
	else if (strcmp(strType, "rotate") == 0)
	{
		RotationBlock* block = new RotationBlock();
		if (!elemNode->Attribute("file") && elemParent->Attribute("file"))
		{
			elemNode->SetAttribute("file",elemParent->Attribute("file"));
		}
		if (!parseSpriteNode(block,elemNode))
		{
			delete(block);
			return false;
		}
		else
		{
			node->addChild(block);
		}
		oldSibling = NULL;
	}
	else if ((strcmp(strType, "sprite") == 0) || (strcmp(strType, "empty") == 0))
	{
		SpriteElement* sprite = new SpriteElement();
		const char* strSheetIndex = elemNode->Attribute("index");
		const char* strOffsetX = elemNode->Attribute("offsetx");
		const char* strOffsetY = elemNode->Attribute("offsety");
		const char* filename = elemNode->Attribute("file");
		getAnimFrames(elemNode->Attribute("frames"));
		sprite->sprite.animFrames = getAnimFrames(elemNode->Attribute("frames"));
		if (sprite->sprite.animFrames == 0)
			sprite->sprite.animFrames = ALL_FRAMES;

		sprite->sprite.sheetIndex = (strSheetIndex != 0 ? atoi(strSheetIndex) : -1);
		sprite->sprite.x    = (strOffsetX    != 0 ? atoi(strOffsetX)    : 0);
		sprite->sprite.y   = (strOffsetY    != 0 ? atoi(strOffsetY)    : 0);
		sprite->sprite.fileIndex = -1;
		if (filename != NULL && filename[0] != 0)
		{
		  	sprite->sprite.fileIndex = loadConfigImgFile((char*)filename,elemNode);
		}
		else
		{
		  const char* pfilename = elemParent->Attribute("file");
	      if (pfilename != NULL && pfilename[0] != 0)
	      {
		      sprite->sprite.fileIndex = loadConfigImgFile((char*)pfilename,elemNode);
	      }
		}
		node->addChild(sprite);
	}
	else if (strcmp(strType, "include") == 0)
	{
		if (!includeFile(node,elemNode,oldSibling))
		{
			return false;
		}
	}
	else
	{
		contentError("Misplaced or invalid element in SpriteNode",elemNode);
		return false;
	}		
	return true;
}