PIDXMLReader(boost::shared_ptr<XMLData> piddata, const AttributesList& atts) {
     _piddata = piddata;
     if( !_piddata )
         _piddata.reset(new XMLData());
     RAVELOG_INFO("the attributes piddata is created with are:\n");
     for(AttributesList::const_iterator itatt = atts.begin(); itatt != atts.end(); ++itatt)
         RAVELOG_INFO("%s=%s\n",itatt->first.c_str(),itatt->second.c_str());
 }
//----------------------------------------------------- Méthodes publiques
void SimpleBuilder::buildDTD(DTD& dtd) const
{
	unsigned int elementNumber = 0;
	AttributesList attlist;

	// --- ROOT : SEQUENCE
	Sequence::OrderedContent embeddedContent;
	embeddedContent.push_back(new ElementReference(dtd, ns(1), name(1)));
	embeddedContent.push_back(new ElementReference(dtd, ns(4), name(4)));
	embeddedContent.push_back(new ElementReference(dtd, ns(2), name(2)));
	embeddedContent.push_back(new ElementReference(dtd, ns(3), name(3)));
	dtd.addElement(ns(elementNumber), name(elementNumber),
			*new Sequence(embeddedContent));

	attlist.clear();
	attlist.insert(new Attribute(attname(2)));
	attlist.insert(new Attribute(attname(3)));
	dtd.addAttributesList(ns(elementNumber), name(elementNumber), attlist);

	elementNumber = 1;

	// --- CHILD 1 : REPEATABLECONTENT(MIXEDCONTENT)
	MixedContent::ChoosableSet choosables;
	choosables.insert(new ElementReference(dtd, ns(5), name(5)));
	choosables.insert(new ElementReference(dtd, ns(6), name(6)));
	dtd.addElement(
			ns(elementNumber),
			name(elementNumber),
			*new RepeatableContent(
					*new MixedContent(*new TextContent(), choosables)));

	attlist.clear();
	attlist.insert(new Attribute(attname(0)));
	attlist.insert(new Attribute(attname(1)));
	dtd.addAttributesList(ns(elementNumber), name(elementNumber), attlist);

	elementNumber = 2;

	// --- CHILD 2 : OPTIONAL CONTENT
	dtd.addElement(ns(elementNumber), name(elementNumber),
			*new OptionalContent(*new ElementReference(dtd, ns(7), name(7))));

	attlist.clear();
	attlist.insert(new Attribute(attname(4)));
	attlist.insert(new Attribute(attname(5)));
	dtd.addAttributesList(ns(elementNumber), name(elementNumber), attlist);

	// --- LEAFS
	for (int i = 3; i <= 7; ++i)
	{
		dtd.addElement(ns(i), name(i), *new EmptyContent());
	}
}
//=============================================================================
//commits the changes of the ID session
//
void EntertainerManager::commitIdChanges(PlayerObject* customer,PlayerObject* designer, BString hair, uint32 amount,uint8 statMigration, BString holoEmote,uint8 flagHair)
{
    Ham* ham = designer->getHam();
    if(ham->checkMainPools(0,0,66))
    {
        //int32 mindCost = 66;
        designer->getHam()->updatePropertyValue(HamBar_Mind,HamProperty_CurrentHitpoints,-(66));
    }


    const PlayerObjectSet* const inRangePlayers	= customer->getKnownPlayers();
    PlayerObjectSet::const_iterator	itiR			= inRangePlayers->begin();

    int8 sql[1024];
    EntertainerManagerAsyncContainer* asyncContainer;

    //money
    if(amount >0)
        applyMoney(customer,designer,amount);


    ////////
    //Hair//
    ///////
    if(flagHair)
        applyHair(customer,hair);



    ////////////
    //attributes
    ///////////
    int8						mySQL[2048];
    AttributesList*				aList			 = customer->getIdAttributesList();
    AttributesList::iterator	it				 = aList->begin();
    BString						data;
    bool						firstUpdate		 = true;

    sprintf(mySQL,"UPDATE character_appearance set ");

    while(it != aList->end())
    {
        gLogger->log(LogManager::DEBUG,"ID apply changes : attribute : %s crc : %u", it->first.getAnsi(),it->first.getCrc());
        //apply the attributes and retrieve the data to update the db
        if(it->first.getCrc() != BString("height").getCrc())
        {
            data = commitIdAttribute(customer, it->first, it->second);
        }
        else
        {
            data = commitIdheight(customer, it->second);
        }


        if (firstUpdate)
        {
            sprintf(mySQL,"%s %s",mySQL,data.getAnsi());
            firstUpdate = false;
        }
        else
            sprintf(mySQL,"%s, %s",mySQL,data.getAnsi());

        ++it;
    }

    //colors
    ColorList* cList = customer->getIdColorList();
    ColorList::iterator cIt = cList->begin();
    while(cIt != cList->end())
    {
        gLogger->log(LogManager::DEBUG,"ID apply changes : attribute : %s crc : %u",cIt->first.getAnsi(),cIt->first.getCrc());
        data = commitIdColor(customer, cIt->first, cIt->second);
        if(data.getLength())
        {
            if (firstUpdate)
            {
                sprintf(mySQL,"%s %s",mySQL,data.getAnsi());
                firstUpdate = false;
            }
            else
                sprintf(mySQL,"%s, %s",mySQL,data.getAnsi());
        }


        ++cIt;
    }

    //do we have actual data or only the primer ??? "UPDATE character_appearance set "
    if(strlen(mySQL) > 33)
    {
        sprintf(sql,"%s where character_id = '%"PRIu64"'",mySQL,customer->getId());
        gLogger->log(LogManager::DEBUG,"ID apply changes : sql: %s ",sql);
        asyncContainer = new EntertainerManagerAsyncContainer(EMQuery_NULL,0);
        mDatabase->ExecuteSqlAsync(this,asyncContainer,sql);
        
    }




    //build plus send customization
    //please note that hair object customizatio is send updated and maintained b ycommitIdColor
    customer->buildCustomization(customer->getCustomization());

    gMessageLib->sendCustomizationUpdateCreo3(customer);
    gMessageLib->sendScaleUpdateCreo3(customer);

    //Holoemotes
    if(holoEmote.getLength())
        applyHoloEmote(customer,holoEmote);

    //statmigration
    if(statMigration)
    {
        //xp in case of statmigration will be handled by the callback
        int8 sql[256];
        asyncContainer = new EntertainerManagerAsyncContainer(EMQuery_IDMigrateStats,0);
        asyncContainer->customer = customer;
        asyncContainer->performer = designer;

        sprintf(sql,"SELECT target_health, target_strength, target_constitution, target_action, target_quickness, target_stamina, target_mind, target_focus, target_willpower FROM swganh.character_stat_migration where character_id = %"PRIu64"", customer->getId());
        mDatabase->ExecuteSqlAsync(this,asyncContainer,sql);
        
    }
    else
    {
        //XP does not stack. So in the case of statmigration only 2000xp will be given
        //otherwise xp will be determined here
        //
        uint32		xP		= 0;
        uint32		tempXP	= 0;

        it = aList->begin();
        while(it != aList->end())
        {
            tempXP = getIdXP(it->first, static_cast<uint16>(it->second));
            if(tempXP > xP)
                xP = tempXP;

            ++it;
        }

        cIt = cList->begin();
        while(cIt != cList->end())
        {
            tempXP = getIdXP(cIt->first, cIt->second);
            if(tempXP > xP)
                xP = tempXP;

            ++cIt;
        }

        if(flagHair)
        {
            tempXP = 50;
            if(tempXP > xP)
                xP = tempXP;
        }

        //only half XP if you design yourself
        if(designer == customer)
            gSkillManager->addExperience(XpType_imagedesigner,(uint32)(xP/2),designer);
        else
            gSkillManager->addExperience(XpType_imagedesigner,(uint32)xP,designer);
    }

    //empty the attribute lists
    aList->clear();
    cList->clear();

}