void	CGroupPhraseSkillFilter::rebuild()
{
	CInterfaceManager *pIM = CInterfaceManager::getInstance();
	CSkillManager *pSM = CSkillManager::getInstance();

	// get the tree
	if (_Tree == NULL)
	{
		_Tree = dynamic_cast<CGroupTree*>(CWidgetManager::getInstance()->getElementFromId(getId(),"sbtree:tree_list"));

		if (_Tree == NULL)
		{
			nlwarning("cant find tree");
			return;
		}
	}

	// **** Bkup old tree state
	// get the old skill selected
	string oldSkillId= _Tree->getSelectedNodeId();

	// Backup for each skill the Opened State, to keep it after rebuild
	bool			skillOpened[SKILLS::NUM_SKILLS];
	memset(skillOpened, 0, SKILLS::NUM_SKILLS * sizeof(bool));

	bkupSkillOpenedStateRecurs(skillOpened, _Tree->getRootNode());


	// **** Build the new Skill Tree
	// clean all
	_Tree->removeAll();

	// Construct the snode hierarchy structure
	CGroupTree::SNode *pRoot = new CGroupTree::SNode;
	vector<CGroupTree::SNode*> allNodes;
	allNodes.resize(SKILLS::NUM_SKILLS, NULL);
	bool bQuit = false;
	uint nCounter = 0;

	// local variable (avoid realloc in loop)
	vector< pair<string, string> > tempVec(2);
	ucstring	sSkillName;
	string		sDBNameSkillValue;

	// Build the hierarchy
	while ((!bQuit) && (nCounter < 32)) // Counter is used to not infinitly loop
	{
		nCounter++;
		bQuit = true;
		// Try to create a skill
		for (uint32 i = 0; i < SKILLS::NUM_SKILLS; ++i)
		if (allNodes[i] == NULL) // not already created
		{
			if (pSM->isUnknown((SKILLS::ESkills)i)) continue;
			// if no bricks use this skill, skip
			if (!_BrickSkillUsage[i]) continue;

			// Can create if we can obtain its parent (if it get a parent)
			if (pSM->getParent((SKILLS::ESkills)i) != SKILLS::unknown)
			{
				if (allNodes[pSM->getParent((SKILLS::ESkills)i)] == NULL)
				{
					bQuit = false;
					continue;
				}
			}

			// Ok lets create it
			CGroupTree::SNode *pNode = new CGroupTree::SNode;
			pNode->Id = NLMISC::toString(i);

			// just text
			pNode->DisplayText = true;
			pNode->Template = NULL;
			pNode->Text= STRING_MANAGER::CStringManagerClient::getSkillLocalizedName((SKILLS::ESkills)i);;

			// Action handler?
			if(!_AHCtrlNode.empty())
			{
				pNode->AHName= _AHCtrlNode;
				pNode->AHParams= NLMISC::toString(i);
			}

			// Opened?
			pNode->Opened= skillOpened[i];

			// bkup
			allNodes[i] = pNode;

			// Attach to the good parent
			if (pSM->getParent((SKILLS::ESkills)i) == SKILLS::unknown)
				pRoot->addChild(pNode);
			else
				allNodes[pSM->getParent((SKILLS::ESkills)i)]->addChild(pNode);
		}
	}

	// Sort the First level in this order: Combat/Magic/Craft/Forage/Others.
	vector<CSortNode>	sortNodes;
	sortNodes.resize(pRoot->Children.size());
	uint	i;
	for(i=0;i<pRoot->Children.size();i++)
	{
		sortNodes[i].Node= pRoot->Children[i];
		// get the skill value of this node
		sint	skillValue;
		fromString(pRoot->Children[i]->Id, skillValue);
		// Special sort:
		if(skillValue==SKILLS::SF)
			skillValue= -4;
		if(skillValue==SKILLS::SM)
			skillValue= -3;
		if(skillValue==SKILLS::SC)
			skillValue= -2;
		if(skillValue==SKILLS::SH)
			skillValue= -1;
		// prepare tri
		sortNodes[i].Value= skillValue;
	}
	sort(sortNodes.begin(), sortNodes.end());
	// store sorted values
	for(i=0;i<pRoot->Children.size();i++)
	{
		pRoot->Children[i]= sortNodes[i].Node;
	}

	// Add a special Fitler at root for No filter (All)
	{
		// Ok lets create it
		CGroupTree::SNode *pNode = new CGroupTree::SNode;
		pNode->Id = NodeIdNoFilter;

		// just text
		pNode->DisplayText = true;
		pNode->Template = NULL;
		pNode->Text= CI18N::get("uiPhraseNoFilter");

		// Action handler?
		if(!_AHCtrlNode.empty())
		{
			pNode->AHName= _AHCtrlNode;
			pNode->AHParams= NLMISC::toString((uint32)SKILLS::unknown);
		}

		// No sons.
		pNode->Opened= false;

		// Append front
		pRoot->addChildFront(pNode);
	}

	// Add a special Fitler at root for Special Powers Phrases (because they don't use skill)
	{
		// Ok lets create it
		CGroupTree::SNode *pNode = new CGroupTree::SNode;
		pNode->Id = NodeIdSpecialPower;

		// just text
		pNode->DisplayText = true;
		pNode->Template = NULL;
		pNode->Text= CI18N::get("uiSpecialPowerFilter");

		// Action handler?
		if(!_AHCtrlNode.empty())
		{
			pNode->AHName= _AHCtrlNode;
			pNode->AHParams= "bt=" + BRICK_TYPE::toString(BRICK_TYPE::SPECIAL_POWER);
		}

		// No sons.
		pNode->Opened= false;

		pRoot->addChild(pNode);
	}

	// Setup the Ctrl Tree
	_Tree->setRootNode (pRoot);


	// **** Reset old Tree state.
	// Select node by its id setuped before.
	if(!_Tree->selectNodeById(oldSkillId))
		// if some error (none selected before...), select line 0: All.
		_Tree->selectLine(0);


	invalidateCoords();
	_MustRebuild = false;
}