Index: trunk/src/shared/Database/Database.h
===================================================================
--- trunk/src/shared/Database/Database.h (revision 102)
+++ trunk/src/shared/Database/Database.h (revision 173)
@@ -62,12 +62,20 @@
         template<class Class, typename ParamType1>
             bool AsyncQuery(Class *object, void (Class::*method)(QueryResult*, ParamType1), ParamType1 param1, const char *sql);
+        template<class Class, typename ParamType1, typename ParamType2>
+            bool AsyncQuery(Class *object, void (Class::*method)(QueryResult*, ParamType1, ParamType2), ParamType1 param1, ParamType2 param2, const char *sql);
         template<typename ParamType1>
             bool AsyncQuery(void (*method)(QueryResult*, ParamType1), ParamType1 param1, const char *sql);
+        template<typename ParamType1, typename ParamType2>
+            bool AsyncQuery(void (*method)(QueryResult*, ParamType1, ParamType2), ParamType1 param1, ParamType2 param2, const char *sql);
         template<class Class>
             bool AsyncPQuery(Class *object, void (Class::*method)(QueryResult*), const char *format,...) ATTR_PRINTF(4,5);
         template<class Class, typename ParamType1>
             bool AsyncPQuery(Class *object, void (Class::*method)(QueryResult*, ParamType1), ParamType1 param1, const char *format,...) ATTR_PRINTF(5,6);
+        template<class Class, typename ParamType1, typename ParamType2>
+            bool AsyncPQuery(Class *object, void (Class::*method)(QueryResult*, ParamType1, ParamType2), ParamType1 param1, ParamType2 param2, const char *format,...) ATTR_PRINTF(5,6);
         template<typename ParamType1>
             bool AsyncPQuery(void (*method)(QueryResult*, ParamType1), ParamType1 param1, const char *format,...) ATTR_PRINTF(5,6);
+        template<typename ParamType1, typename ParamType2>
+            bool AsyncPQuery(void (*method)(QueryResult*, ParamType1, ParamType2), ParamType1 param1, ParamType2 param2, const char *format,...) ATTR_PRINTF(5,6);
         template<class Class>
             bool DelayQueryHolder(Class *object, void (Class::*method)(QueryResult*, SqlQueryHolder*), SqlQueryHolder *holder);
Index: trunk/src/shared/Database/DatabaseImpl.h
===================================================================
--- trunk/src/shared/Database/DatabaseImpl.h (revision 102)
+++ trunk/src/shared/Database/DatabaseImpl.h (revision 173)
@@ -48,4 +48,16 @@
 }
 
+template<class Class, typename ParamType1, typename ParamType2>
+bool
+Database::AsyncQuery(Class *object, void (Class::*method)(QueryResult*, ParamType1, ParamType2), ParamType1 param1, ParamType2 param2, const char *sql)
+{
+    if (!sql) return false;
+    ZThread::ThreadImpl * queryThread = ZThread::ThreadImpl::current();
+    QueryQueues::iterator itr = m_queryQueues.find(queryThread);
+    if (itr == m_queryQueues.end()) return false;
+    m_threadBody->Delay(new SqlQuery(sql, new Trinity::QueryCallback<Class, ParamType1, ParamType2>(object, method, (QueryResult*)NULL, param1, param2), itr->second));
+    return true;
+}
+
 template<typename ParamType1>
 bool
@@ -60,4 +72,16 @@
 }
 
+template<typename ParamType1, typename ParamType2>
+bool
+Database::AsyncQuery(void (*method)(QueryResult*, ParamType1, ParamType2), ParamType1 param1, ParamType2 param2, const char *sql)
+{
+    if (!sql) return false;
+    ZThread::ThreadImpl * queryThread = ZThread::ThreadImpl::current();
+    QueryQueues::iterator itr = m_queryQueues.find(queryThread);
+    if (itr == m_queryQueues.end()) return false;
+    m_threadBody->Delay(new SqlQuery(sql, new Trinity::SQueryCallback<ParamType1, ParamType2>(method, (QueryResult*)NULL, param1, param2), itr->second));
+    return true;
+}
+
 template<class Class>
 bool
@@ -102,4 +126,25 @@
 }
 
+template<class Class, typename ParamType1, typename ParamType2>
+bool
+Database::AsyncPQuery(Class *object, void (Class::*method)(QueryResult*, ParamType1, ParamType2), ParamType1 param1, ParamType2 param2, const char *format,...)
+{
+    if(!format) return false;
+
+    va_list ap;
+    char szQuery [MAX_QUERY_LEN];
+    va_start(ap, format);
+    int res = vsnprintf( szQuery, MAX_QUERY_LEN, format, ap );
+    va_end(ap);
+
+    if(res==-1)
+    {
+        sLog.outError("SQL Query truncated (and not execute) for format: %s",format);
+        return false;
+    }
+
+    return AsyncQuery(object, method, param1, param2, szQuery);
+}
+
 template<typename ParamType1>
 bool
@@ -123,4 +168,24 @@
 }
 
+template<typename ParamType1, typename ParamType2>
+bool
+Database::AsyncPQuery(void (*method)(QueryResult*, ParamType1, ParamType2), ParamType1 param1, ParamType2 param2, const char *format,...)
+{
+    if(!format) return false;
+
+    va_list ap;
+    char szQuery [MAX_QUERY_LEN];
+    va_start(ap, format);
+    int res = vsnprintf( szQuery, MAX_QUERY_LEN, format, ap );
+    va_end(ap);
+
+    if(res==-1)
+    {
+        sLog.outError("SQL Query truncated (and not execute) for format: %s",format);
+        return false;
+    }
+
+    return AsyncQuery(method, param1, param2, szQuery);
+}
 
 template<class Class>
Index: trunk/src/game/Guild.cpp
===================================================================
--- trunk/src/game/Guild.cpp (revision 102)
+++ trunk/src/game/Guild.cpp (revision 173)
@@ -113,6 +113,15 @@
 bool Guild::AddMember(uint64 plGuid, uint32 plRank)
 {
-    if(Player::GetGuildIdFromDB(plGuid) != 0)               // player already in guild
+    Player* pl = objmgr.GetPlayer(plGuid);
+    if(pl)
+    {
+        if(pl->GetGuildId() != 0)
         return false;
+    }
+    else
+    {
+        if(Player::GetGuildIdFromDB(plGuid) != 0)           // player already in guild
+        return false;
+    }
 
     // remove all player signs from another petitions
@@ -143,5 +152,4 @@
         Id, GUID_LOPART(plGuid), newmember.RankId, dbPnote.c_str(), dbOFFnote.c_str());
 
-    Player* pl = objmgr.GetPlayer(plGuid);
     if(pl)
     {
@@ -675,4 +683,13 @@
 
     CharacterDatabase.PExecute("UPDATE guild_rank SET rights='%u' WHERE rid='%u' AND guildid='%u'", rights, (rankId+1), Id);
+}
+
+int32 Guild::GetRank(uint32 LowGuid)
+{
+    MemberList::iterator itr = members.find(LowGuid);
+    if (itr==members.end())
+        return -1;
+        
+    return itr->second.RankId;
 }
 
Index: trunk/src/game/Transports.cpp
===================================================================
--- trunk/src/game/Transports.cpp (revision 102)
+++ trunk/src/game/Transports.cpp (revision 173)
@@ -117,5 +117,5 @@
 
     // check transport data DB integrity
-    result = WorldDatabase.PQuery("SELECT gameobject.guid,gameobject.id,transports.name FROM gameobject,transports WHERE gameobject.id = transports.entry");
+    result = WorldDatabase.Query("SELECT gameobject.guid,gameobject.id,transports.name FROM gameobject,transports WHERE gameobject.id = transports.entry");
     if(result)                                              // wrong data found
     {
Index: trunk/src/game/InstanceSaveMgr.cpp
===================================================================
--- trunk/src/game/InstanceSaveMgr.cpp (revision 102)
+++ trunk/src/game/InstanceSaveMgr.cpp (revision 173)
@@ -272,5 +272,5 @@
     // first, obtain total instance set
     std::set< uint32 > InstanceSet;
-    QueryResult *result = CharacterDatabase.PQuery("SELECT id FROM instance");
+    QueryResult *result = CharacterDatabase.Query("SELECT id FROM instance");
     if( result )
     {
@@ -285,5 +285,5 @@
 
     // creature_respawn
-    result = WorldDatabase.PQuery("SELECT DISTINCT(instance) FROM creature_respawn WHERE instance <> 0");
+    result = WorldDatabase.Query("SELECT DISTINCT(instance) FROM creature_respawn WHERE instance <> 0");
     if( result )
     {
@@ -299,5 +299,5 @@
 
     // gameobject_respawn
-    result = WorldDatabase.PQuery("SELECT DISTINCT(instance) FROM gameobject_respawn WHERE instance <> 0");
+    result = WorldDatabase.Query("SELECT DISTINCT(instance) FROM gameobject_respawn WHERE instance <> 0");
     if( result )
     {
@@ -328,5 +328,5 @@
     // any associations to ids not in this table are assumed to be
     // cleaned already in CleanupInstances
-    QueryResult *result = CharacterDatabase.PQuery("SELECT id FROM instance");
+    QueryResult *result = CharacterDatabase.Query("SELECT id FROM instance");
     if( result )
     {
@@ -378,5 +378,5 @@
     typedef std::map<uint32, std::pair<uint32, uint64> > ResetTimeMapType;
     ResetTimeMapType InstResetTime;
-    QueryResult *result = CharacterDatabase.PQuery("SELECT id, map, resettime FROM instance WHERE resettime > 0");
+    QueryResult *result = CharacterDatabase.Query("SELECT id, map, resettime FROM instance WHERE resettime > 0");
     if( result )
     {
@@ -394,5 +394,5 @@
 
         // update reset time for normal instances with the max creature respawn time + X hours
-        result = WorldDatabase.PQuery("SELECT MAX(respawntime), instance FROM creature_respawn WHERE instance > 0 GROUP BY instance");
+        result = WorldDatabase.Query("SELECT MAX(respawntime), instance FROM creature_respawn WHERE instance > 0 GROUP BY instance");
         if( result )
         {
Index: trunk/src/game/Level3.cpp
===================================================================
--- trunk/src/game/Level3.cpp (revision 169)
+++ trunk/src/game/Level3.cpp (revision 173)
@@ -2005,7 +2005,36 @@
     sLog.outDetail(GetTrinityString(LANG_ADDITEMSET), itemsetId);
 
-    QueryResult *result = WorldDatabase.PQuery("SELECT entry FROM item_template WHERE itemset = %u",itemsetId);
-
-    if(!result)
+    bool found = false;
+    for (uint32 id = 0; id < sItemStorage.MaxEntry; id++)
+    {
+        ItemPrototype const *pProto = sItemStorage.LookupEntry<ItemPrototype>(id);
+        if (!pProto)
+            continue;
+
+        if (pProto->ItemSet == itemsetId)
+        {
+            found = true;
+            ItemPosCountVec dest;
+            uint8 msg = plTarget->CanStoreNewItem( NULL_BAG, NULL_SLOT, dest, pProto->ItemId, 1 );
+            if (msg == EQUIP_ERR_OK)
+            {
+                Item* item = plTarget->StoreNewItem( dest, pProto->ItemId, true);
+                // remove binding (let GM give it to another player later)
+                if (pl==plTarget)
+                    item->SetBinding( false );
+
+            pl->SendNewItem(item,1,false,true);
+            if (pl!=plTarget)
+                plTarget->SendNewItem(item,1,true,false);
+            }
+            else
+            {
+                pl->SendEquipError( msg, NULL, NULL );
+                PSendSysMessage(LANG_ITEM_CANNOT_CREATE, pProto->ItemId, 1);
+            }
+        }
+    }
+
+    if (!found)
     {
         PSendSysMessage(LANG_NO_ITEMS_FROM_ITEMSET_FOUND,itemsetId);
@@ -2014,34 +2043,4 @@
         return false;
     }
-
-    do
-    {
-        Field *fields = result->Fetch();
-        uint32 itemId = fields[0].GetUInt32();
-
-        ItemPosCountVec dest;
-        uint8 msg = plTarget->CanStoreNewItem( NULL_BAG, NULL_SLOT, dest, itemId, 1 );
-        if( msg == EQUIP_ERR_OK )
-        {
-            Item* item = plTarget->StoreNewItem( dest, itemId, true);
-
-            // remove binding (let GM give it to another player later)
-            if(pl==plTarget)
-                item->SetBinding( false );
-
-            pl->SendNewItem(item,1,false,true);
-            if(pl!=plTarget)
-                plTarget->SendNewItem(item,1,true,false);
-        }
-        else
-        {
-            pl->SendEquipError( msg, NULL, NULL );
-            PSendSysMessage(LANG_ITEM_CANNOT_CREATE, itemId, 1);
-        }
-
-    }while( result->NextRow() );
-
-    delete result;
-
     return true;
 }
@@ -4766,14 +4765,16 @@
 
     // check item starting quest (it can work incorrectly if added without item in inventory)
-    QueryResult *result = WorldDatabase.PQuery("SELECT entry FROM item_template WHERE startquest = '%u' LIMIT 1",entry);
-    if(result)
-    {
-        Field* fields = result->Fetch();
-        uint32 item_id = fields[0].GetUInt32();
-        delete result;
-
-        PSendSysMessage(LANG_COMMAND_QUEST_STARTFROMITEM, entry,item_id);
-        SetSentErrorMessage(true);
-        return false;
+    for (uint32 id = 0; id < sItemStorage.MaxEntry; id++)
+    {
+        ItemPrototype const *pProto = sItemStorage.LookupEntry<ItemPrototype>(id);
+        if (!pProto)
+            continue;
+
+        if (pProto->StartQuest == entry)
+        {
+            PSendSysMessage(LANG_COMMAND_QUEST_STARTFROMITEM, entry, pProto->ItemId);
+            SetSentErrorMessage(true);
+            return false;
+        }
     }
 
Index: trunk/src/game/SkillDiscovery.cpp
===================================================================
--- trunk/src/game/SkillDiscovery.cpp (revision 102)
+++ trunk/src/game/SkillDiscovery.cpp (revision 173)
@@ -55,5 +55,5 @@
 
     //                                                 0        1         2
-    QueryResult *result = WorldDatabase.PQuery("SELECT spellId, reqSpell, chance FROM skill_discovery_template");
+    QueryResult *result = WorldDatabase.Query("SELECT spellId, reqSpell, chance FROM skill_discovery_template");
 
     if (result)
Index: trunk/src/game/SkillExtraItems.cpp
===================================================================
--- trunk/src/game/SkillExtraItems.cpp (revision 102)
+++ trunk/src/game/SkillExtraItems.cpp (revision 173)
@@ -60,5 +60,5 @@
 
     //                                                 0        1                       2                       3
-    QueryResult *result = WorldDatabase.PQuery("SELECT spellId, requiredSpecialization, additionalCreateChance, additionalMaxNum FROM skill_extra_item_template");
+    QueryResult *result = WorldDatabase.Query("SELECT spellId, requiredSpecialization, additionalCreateChance, additionalMaxNum FROM skill_extra_item_template");
 
     if (result)
Index: trunk/src/game/SocialMgr.h
===================================================================
--- trunk/src/game/SocialMgr.h (revision 139)
+++ trunk/src/game/SocialMgr.h (revision 173)
@@ -148,5 +148,5 @@
         // Packet management
         void MakeFriendStatusPacket(FriendsResult result, uint32 friend_guid, WorldPacket *data);
-        void SendFriendStatus(Player *player, FriendsResult result, uint32 friend_guid, std::string name, bool broadcast);
+        void SendFriendStatus(Player *player, FriendsResult result, uint32 friend_guid, bool broadcast);
         void BroadcastToFriendListers(Player *player, WorldPacket *packet);
         // Loading
Index: trunk/src/game/MiscHandler.cpp
===================================================================
--- trunk/src/game/MiscHandler.cpp (revision 139)
+++ trunk/src/game/MiscHandler.cpp (revision 173)
@@ -22,4 +22,5 @@
 #include "Language.h"
 #include "Database/DatabaseEnv.h"
+#include "Database/DatabaseImpl.h"
 #include "WorldPacket.h"
 #include "Opcodes.h"
@@ -650,10 +651,7 @@
     sLog.outDebug( "WORLD: Received CMSG_ADD_FRIEND" );
 
-    std::string friendName  = GetTrinityString(LANG_FRIEND_IGNORE_UNKNOWN);
+    std::string friendName = GetTrinityString(LANG_FRIEND_IGNORE_UNKNOWN);
     std::string friendNote;
-    FriendsResult friendResult = FRIEND_NOT_FOUND;
-    Player *pFriend     = NULL;
-    uint64 friendGuid   = 0;
-
+    
     recv_data >> friendName;
 
@@ -671,48 +669,49 @@
         GetPlayer()->GetName(), friendName.c_str() );
 
-    friendGuid = objmgr.GetPlayerGUIDByName(friendName);
-
+    CharacterDatabase.AsyncPQuery(&WorldSession::HandleAddFriendOpcodeCallBack, GetAccountId(), friendNote, "SELECT guid, race FROM characters WHERE name = '%s'", friendName.c_str());
+}
+
+void WorldSession::HandleAddFriendOpcodeCallBack(QueryResult *result, uint32 accountId, std::string friendNote)
+{
+    if(!result)
+        return;
+        
+    uint64 friendGuid = MAKE_NEW_GUID((*result)[0].GetUInt32(), 0, HIGHGUID_PLAYER);
+    uint32 team = Player::TeamForRace((*result)[1].GetUInt8());
+    
+    delete result;
+    
+    WorldSession * session = sWorld.FindSession(accountId);
+    if(!session)
+        return;
+        
+    FriendsResult friendResult = FRIEND_NOT_FOUND;
     if(friendGuid)
     {
-        pFriend = ObjectAccessor::FindPlayer(friendGuid);
-        if(pFriend==GetPlayer())
+        if(friendGuid==session->GetPlayer()->GetGUID())
             friendResult = FRIEND_SELF;
-        else if(GetPlayer()->GetTeam()!=objmgr.GetPlayerTeamByGUID(friendGuid) && !sWorld.getConfig(CONFIG_ALLOW_TWO_SIDE_ADD_FRIEND) && GetSecurity() < SEC_MODERATOR)
+        else if(session->GetPlayer()->GetTeam() != team && !sWorld.getConfig(CONFIG_ALLOW_TWO_SIDE_ADD_FRIEND) && session->GetSecurity() < SEC_MODERATOR)
             friendResult = FRIEND_ENEMY;
-        else if(GetPlayer()->GetSocial()->HasFriend(GUID_LOPART(friendGuid)))
+        else if(session->GetPlayer()->GetSocial()->HasFriend(GUID_LOPART(friendGuid)))
             friendResult = FRIEND_ALREADY;
-    }
-
-    if (friendGuid && friendResult==FRIEND_NOT_FOUND)
-    {
-        if( pFriend && pFriend->IsInWorld() && pFriend->IsVisibleGloballyFor(GetPlayer()))
-            friendResult = FRIEND_ADDED_ONLINE;
         else
-            friendResult = FRIEND_ADDED_OFFLINE;
-
-        if(!_player->GetSocial()->AddToSocialList(GUID_LOPART(friendGuid), false))
+        {
+            Player* pFriend = ObjectAccessor::FindPlayer(friendGuid);
+            if( pFriend && pFriend->IsInWorld() && pFriend->IsVisibleGloballyFor(session->GetPlayer()))
+                friendResult = FRIEND_ADDED_ONLINE;
+            else
+                friendResult = FRIEND_ADDED_OFFLINE;
+                
+        if(!session->GetPlayer()->GetSocial()->AddToSocialList(GUID_LOPART(friendGuid), false))
         {
             friendResult = FRIEND_LIST_FULL;
-            sLog.outDebug( "WORLD: %s's friend list is full.", GetPlayer()->GetName());
-        }
-
-        _player->GetSocial()->SetFriendNote(GUID_LOPART(friendGuid), friendNote);
-
-        sLog.outDebug( "WORLD: %s Guid found '%u'.", friendName.c_str(), GUID_LOPART(friendGuid));
-    }
-    else if(friendResult==FRIEND_ALREADY)
-    {
-        sLog.outDebug( "WORLD: %s Guid Already a Friend.", friendName.c_str() );
-    }
-    else if(friendResult==FRIEND_SELF)
-    {
-        sLog.outDebug( "WORLD: %s Guid can't add himself.", friendName.c_str() );
-    }
-    else
-    {
-        sLog.outDebug( "WORLD: %s Guid not found.", friendName.c_str() );
-    }
-
-    sSocialMgr.SendFriendStatus(GetPlayer(), friendResult, GUID_LOPART(friendGuid), friendName, false);
+            sLog.outDebug( "WORLD: %s's friend list is full.", session->GetPlayer()->GetName());
+        }
+
+            session->GetPlayer()->GetSocial()->SetFriendNote(GUID_LOPART(friendGuid), friendNote);
+        }
+    }
+
+    sSocialMgr.SendFriendStatus(session->GetPlayer(), friendResult, GUID_LOPART(friendGuid), false);
 
     sLog.outDebug( "WORLD: Sent (SMSG_FRIEND_STATUS)" );
@@ -731,5 +730,5 @@
     _player->GetSocial()->RemoveFromSocialList(GUID_LOPART(FriendGUID), false);
 
-    sSocialMgr.SendFriendStatus(GetPlayer(), FRIEND_REMOVED, GUID_LOPART(FriendGUID), "", false);
+    sSocialMgr.SendFriendStatus(GetPlayer(), FRIEND_REMOVED, GUID_LOPART(FriendGUID), false);
 
     sLog.outDebug( "WORLD: Sent motd (SMSG_FRIEND_STATUS)" );
@@ -743,6 +742,4 @@
 
     std::string IgnoreName = GetTrinityString(LANG_FRIEND_IGNORE_UNKNOWN);
-    FriendsResult ignoreResult = FRIEND_IGNORE_NOT_FOUND;
-    uint64 IgnoreGuid = 0;
 
     recv_data >> IgnoreName;
@@ -756,38 +753,38 @@
         GetPlayer()->GetName(), IgnoreName.c_str() );
 
-    IgnoreGuid = objmgr.GetPlayerGUIDByName(IgnoreName);
-
+    CharacterDatabase.AsyncPQuery(&WorldSession::HandleAddIgnoreOpcodeCallBack, GetAccountId(), "SELECT guid FROM characters WHERE name = '%s'", IgnoreName.c_str());
+}
+
+void WorldSession::HandleAddIgnoreOpcodeCallBack(QueryResult *result, uint32 accountId)
+{
+    if(!result)
+        return;
+    
+    uint64 IgnoreGuid = MAKE_NEW_GUID((*result)[0].GetUInt32(), 0, HIGHGUID_PLAYER);
+    
+    delete result;
+    
+    WorldSession * session = sWorld.FindSession(accountId);
+    if(!session)
+        return;
+        
+    FriendsResult ignoreResult = FRIEND_IGNORE_NOT_FOUND;
     if(IgnoreGuid)
     {
-        if(IgnoreGuid==GetPlayer()->GetGUID())
+        if(IgnoreGuid==session->GetPlayer()->GetGUID())              //not add yourself
             ignoreResult = FRIEND_IGNORE_SELF;
+            else if( session->GetPlayer()->GetSocial()->HasIgnore(GUID_LOPART(IgnoreGuid)) )
+                ignoreResult = FRIEND_IGNORE_ALREADY;
         else
         {
-            if( GetPlayer()->GetSocial()->HasIgnore(GUID_LOPART(IgnoreGuid)) )
-                ignoreResult = FRIEND_IGNORE_ALREADY;
-        }
-    }
-
-    if (IgnoreGuid && ignoreResult == FRIEND_IGNORE_NOT_FOUND)
-    {
-        ignoreResult = FRIEND_IGNORE_ADDED;
-
-        if(!_player->GetSocial()->AddToSocialList(GUID_LOPART(IgnoreGuid), true))
+            ignoreResult = FRIEND_IGNORE_ADDED;
+
+        // ignore list full
+        if(!session->GetPlayer()->GetSocial()->AddToSocialList(GUID_LOPART(IgnoreGuid), true))
             ignoreResult = FRIEND_IGNORE_FULL;
-    }
-    else if(ignoreResult==FRIEND_IGNORE_ALREADY)
-    {
-        sLog.outDebug( "WORLD: %s Guid Already Ignored.", IgnoreName.c_str() );
-    }
-    else if(ignoreResult==FRIEND_IGNORE_SELF)
-    {
-        sLog.outDebug( "WORLD: %s Guid can't add himself.", IgnoreName.c_str() );
-    }
-    else
-    {
-        sLog.outDebug( "WORLD: %s Guid not found.", IgnoreName.c_str() );
-    }
-
-    sSocialMgr.SendFriendStatus(GetPlayer(), ignoreResult, GUID_LOPART(IgnoreGuid), "", false);
+        }
+    }
+
+    sSocialMgr.SendFriendStatus(session->GetPlayer(), ignoreResult, GUID_LOPART(IgnoreGuid), false);
 
     sLog.outDebug( "WORLD: Sent (SMSG_FRIEND_STATUS)" );
@@ -806,5 +803,5 @@
     _player->GetSocial()->RemoveFromSocialList(GUID_LOPART(IgnoreGUID), true);
 
-    sSocialMgr.SendFriendStatus(GetPlayer(), FRIEND_IGNORE_REMOVED, GUID_LOPART(IgnoreGUID), "", false);
+    sSocialMgr.SendFriendStatus(GetPlayer(), FRIEND_IGNORE_REMOVED, GUID_LOPART(IgnoreGUID), false);
 
     sLog.outDebug( "WORLD: Sent motd (SMSG_FRIEND_STATUS)" );
Index: trunk/src/game/WorldSession.h
===================================================================
--- trunk/src/game/WorldSession.h (revision 152)
+++ trunk/src/game/WorldSession.h (revision 173)
@@ -282,6 +282,8 @@
         void HandleFriendListOpcode(WorldPacket& recvPacket);
         void HandleAddFriendOpcode(WorldPacket& recvPacket);
+        static void HandleAddFriendOpcodeCallBack(QueryResult *result, uint32 accountId, std::string friendNote);
         void HandleDelFriendOpcode(WorldPacket& recvPacket);
         void HandleAddIgnoreOpcode(WorldPacket& recvPacket);
+        static void HandleAddIgnoreOpcodeCallBack(QueryResult *result, uint32 accountId);
         void HandleDelIgnoreOpcode(WorldPacket& recvPacket);
         void HandleSetFriendNoteOpcode(WorldPacket& recvPacket);
Index: trunk/src/game/Unit.cpp
===================================================================
--- trunk/src/game/Unit.cpp (revision 172)
+++ trunk/src/game/Unit.cpp (revision 173)
@@ -238,7 +238,9 @@
     for (uint32 i = 0; i < CURRENT_MAX_SPELL; i++)
     {
-                                                            // spell may be safely deleted now
-        if (m_currentSpells[i]) m_currentSpells[i]->SetDeletable(true);
-        m_currentSpells[i] = NULL;
+        if (m_currentSpells[i])
+        {
+            m_currentSpells[i]->SetReferencedFromCurrent(false);
+            m_currentSpells[i] = NULL;
+        }
     }
 
@@ -3164,5 +3166,5 @@
         if (m_currentSpells[i] && m_currentSpells[i]->getState() == SPELL_STATE_FINISHED)
         {
-            m_currentSpells[i]->SetDeletable(true);         // spell may be safely deleted now
+            m_currentSpells[i]->SetReferencedFromCurrent(false);
             m_currentSpells[i] = NULL;                      // remove pointer
         }
@@ -3277,5 +3279,4 @@
     uint32 CSpellType = pSpell->GetCurrentContainer();
 
-    pSpell->SetDeletable(false);                            // spell will not be deleted until gone from current pointers
     if (pSpell == m_currentSpells[CSpellType]) return;      // avoid breaking self
 
@@ -3334,8 +3335,9 @@
     // current spell (if it is still here) may be safely deleted now
     if (m_currentSpells[CSpellType])
-        m_currentSpells[CSpellType]->SetDeletable(true);
+        m_currentSpells[CSpellType]->SetReferencedFromCurrent(false);
 
     // set new current spell
     m_currentSpells[CSpellType] = pSpell;
+    pSpell->SetReferencedFromCurrent(true);
 }
 
@@ -3355,5 +3357,5 @@
         if (m_currentSpells[spellType]->getState() != SPELL_STATE_FINISHED)
             m_currentSpells[spellType]->cancel();
-        m_currentSpells[spellType]->SetDeletable(true);
+        m_currentSpells[spellType]->SetReferencedFromCurrent(false);
         m_currentSpells[spellType] = NULL;
     }
@@ -3391,5 +3393,5 @@
             (withDelayed || m_currentSpells[CURRENT_GENERIC_SPELL]->getState() != SPELL_STATE_DELAYED) )
             m_currentSpells[CURRENT_GENERIC_SPELL]->cancel();
-        m_currentSpells[CURRENT_GENERIC_SPELL]->SetDeletable(true);
+        m_currentSpells[CURRENT_GENERIC_SPELL]->SetReferencedFromCurrent(false);
         m_currentSpells[CURRENT_GENERIC_SPELL] = NULL;
     }
@@ -3405,5 +3407,5 @@
             (withDelayed || m_currentSpells[CURRENT_AUTOREPEAT_SPELL]->getState() != SPELL_STATE_DELAYED) )
             m_currentSpells[CURRENT_AUTOREPEAT_SPELL]->cancel();
-        m_currentSpells[CURRENT_AUTOREPEAT_SPELL]->SetDeletable(true);
+        m_currentSpells[CURRENT_AUTOREPEAT_SPELL]->SetReferencedFromCurrent(false);
         m_currentSpells[CURRENT_AUTOREPEAT_SPELL] = NULL;
     }
@@ -3414,5 +3416,5 @@
         if (m_currentSpells[CURRENT_CHANNELED_SPELL]->getState() != SPELL_STATE_FINISHED)
             m_currentSpells[CURRENT_CHANNELED_SPELL]->cancel();
-        m_currentSpells[CURRENT_CHANNELED_SPELL]->SetDeletable(true);
+        m_currentSpells[CURRENT_CHANNELED_SPELL]->SetReferencedFromCurrent(false);
         m_currentSpells[CURRENT_CHANNELED_SPELL] = NULL;
     }
@@ -9861,5 +9863,5 @@
     {
         InterruptNonMeleeSpells(true);
-        m_Events.KillAllEvents();
+        m_Events.KillAllEvents(false);                      // non-delatable (currently casted spells) will not deleted ans will deleated at call in Map::RemoveAllObjectsInRemoveList
         CombatStop();
         ClearComboPointHolders();
Index: trunk/src/game/SocialMgr.cpp
===================================================================
--- trunk/src/game/SocialMgr.cpp (revision 139)
+++ trunk/src/game/SocialMgr.cpp (revision 173)
@@ -238,5 +238,5 @@
 }
 
-void SocialMgr::SendFriendStatus(Player *player, FriendsResult result, uint32 friend_guid, std::string name, bool broadcast)
+void SocialMgr::SendFriendStatus(Player *player, FriendsResult result, uint32 friend_guid, bool broadcast)
 {
     FriendInfo fi;
Index: trunk/src/game/Spell.h
===================================================================
--- trunk/src/game/Spell.h (revision 145)
+++ trunk/src/game/Spell.h (revision 173)
@@ -397,6 +397,7 @@
         bool IsRangedAttackResetSpell() const { return !m_IsTriggeredSpell && IsRangedSpell() && (m_spellInfo->InterruptFlags & SPELL_INTERRUPT_FLAG_AUTOATTACK); }
 
-        bool IsDeletable() const { return m_deletable; }
-        void SetDeletable(bool deletable) { m_deletable = deletable; }
+        bool IsDeletable() const { return !m_referencedFromCurrentSpell && !m_executedCurrently; }
+        void SetReferencedFromCurrent(bool yes) { m_referencedFromCurrentSpell = yes; }
+        void SetExecutedCurrently(bool yes) { m_executedCurrently = yes; }
         uint64 GetDelayStart() const { return m_delayStart; }
         void SetDelayStart(uint64 m_time) { m_delayStart = m_time; }
@@ -450,5 +451,6 @@
 
         // These vars are used in both delayed spell system and modified immediate spell system
-        bool m_deletable;                                   // is the spell pending deletion or must be updated till permitted to delete?
+        bool m_referencedFromCurrentSpell;                  // mark as references to prevent deleted and access by dead pointers
+        bool m_executedCurrently;                           // mark as executed to prevent deleted and access by dead pointers
         bool m_needSpellLog;                                // need to send spell log?
         uint8 m_applyMultiplierMask;                        // by effect: damage multiplier needed?
@@ -657,4 +659,5 @@
         virtual bool Execute(uint64 e_time, uint32 p_time);
         virtual void Abort(uint64 e_time);
+        virtual bool IsDeletable() const;
     protected:
         Spell* m_Spell;
Index: trunk/src/game/Level2.cpp
===================================================================
--- trunk/src/game/Level2.cpp (revision 168)
+++ trunk/src/game/Level2.cpp (revision 173)
@@ -1796,11 +1796,26 @@
     else
     {
+        QueryResult *result = CharacterDatabase.PQuery("SELECT totaltime FROM characters WHERE guid = '%u'", targetGUID);
+        if (!result)
+        {
+            SendSysMessage(LANG_PLAYER_NOT_FOUND);
+            SetSentErrorMessage(true);
+            return false;
+        }
+        Field *fields = result->Fetch();
+        total_player_time = fields[0].GetUInt32();
+        delete result;
+        
+        Tokens data;
+        if (!Player::LoadValuesArrayFromDB(data,targetGUID))
+        {
+            SendSysMessage(LANG_PLAYER_NOT_FOUND);
+            SetSentErrorMessage(true);
+            return false;
+        }
+        
+        money = Player::GetUInt32ValueFromArray(data, PLAYER_FIELD_COINAGE);
+        level = Player::GetUInt32ValueFromArray(data, UNIT_FIELD_LEVEL);
         accId = objmgr.GetPlayerAccountIdByGUID(targetGUID);
-        WorldSession session(0,NULL,SEC_PLAYER,0,0,LOCALE_enUS);
-        Player plr(&session);                               // use fake session for temporary load
-        plr.MinimalLoadFromDB(NULL, targetGUID);
-        money = plr.GetMoney();
-        total_player_time = plr.GetTotalPlayedTime();
-        level = plr.getLevel();
     }
 
@@ -3384,5 +3399,5 @@
             getline (infile,line);
             //cout << line << endl;
-            QueryResult *result = WorldDatabase.PQuery(line.c_str());
+            QueryResult *result = WorldDatabase.Query(line.c_str());
             delete result;
         }
Index: trunk/src/game/CharacterHandler.cpp
===================================================================
--- trunk/src/game/CharacterHandler.cpp (revision 168)
+++ trunk/src/game/CharacterHandler.cpp (revision 173)
@@ -635,5 +635,5 @@
 
     // friend status
-    sSocialMgr.SendFriendStatus(pCurrChar, FRIEND_ONLINE, pCurrChar->GetGUIDLow(), "", true);
+    sSocialMgr.SendFriendStatus(pCurrChar, FRIEND_ONLINE, pCurrChar->GetGUIDLow(), true);
 
     // Place character in world (and load zone) before some object loading
Index: trunk/src/game/WorldSession.cpp
===================================================================
--- trunk/src/game/WorldSession.cpp (revision 168)
+++ trunk/src/game/WorldSession.cpp (revision 173)
@@ -380,5 +380,5 @@
 
         ///- Broadcast a logout message to the player's friends
-        sSocialMgr.SendFriendStatus(_player, FRIEND_OFFLINE, _player->GetGUIDLow(), "", true);
+        sSocialMgr.SendFriendStatus(_player, FRIEND_OFFLINE, _player->GetGUIDLow(), true);
 
         ///- Delete the player object
Index: trunk/src/game/Guild.h
===================================================================
--- trunk/src/game/Guild.h (revision 102)
+++ trunk/src/game/Guild.h (revision 173)
@@ -327,4 +327,5 @@
             return ((GetRankRights(rankId) & right) != GR_RIGHT_EMPTY) ? true : false;
         }
+        int32 GetRank(uint32 LowGuid);
 
         void Roster(WorldSession *session);
Index: trunk/src/game/SpellAuras.cpp
===================================================================
--- trunk/src/game/SpellAuras.cpp (revision 162)
+++ trunk/src/game/SpellAuras.cpp (revision 173)
@@ -3483,5 +3483,5 @@
                 {
                     currentSpell->cancel();
-                    currentSpell->SetDeletable(true);
+                    currentSpell->SetReferencedFromCurrent(false);
                     m_target->m_currentSpells[i] = NULL;
                 }
Index: trunk/src/game/Spell.cpp
===================================================================
--- trunk/src/game/Spell.cpp (revision 168)
+++ trunk/src/game/Spell.cpp (revision 173)
@@ -288,5 +288,6 @@
     m_magnetPair.first = false;
     m_magnetPair.second = NULL;
-    m_deletable = true;
+    m_referencedFromCurrentSpell = false;
+    m_executedCurrently = false;
     m_delayAtDamageCount = 0;
 
@@ -2202,4 +2203,6 @@
 void Spell::cast(bool skipCheck)
 {
+    SetExecutedCurrently(true);
+    
     uint8 castResult = 0;
 
@@ -2211,4 +2214,5 @@
     {
         cancel();
+        SetExecutedCurrently(false);
         return;
     }
@@ -2222,4 +2226,5 @@
         SendCastResult(castResult);
         finish(false);
+        SetExecutedCurrently(false);
         return;
     }
@@ -2233,4 +2238,5 @@
             SendCastResult(castResult);
             finish(false);
+            SetExecutedCurrently(false);
             return;
         }
@@ -2278,5 +2284,8 @@
 
     if(m_spellState == SPELL_STATE_FINISHED)                // stop cast if spell marked as finish somewhere in Take*/FillTargetMap
-        return;
+    {
+        SetExecutedCurrently(false);
+        return;
+    }
 
     SendCastResult(castResult);
@@ -2310,4 +2319,6 @@
         handle_immediate();
     }
+    
+    SetExecutedCurrently(false);
 }
 
@@ -5127,2 +5138,7 @@
         m_Spell->cancel();
 }
+
+bool SpellEvent::IsDeletable() const
+{
+    return m_Spell->IsDeletable();
+}
Index: trunk/src/game/GuildHandler.cpp
===================================================================
--- trunk/src/game/GuildHandler.cpp (revision 102)
+++ trunk/src/game/GuildHandler.cpp (revision 173)
@@ -165,7 +165,18 @@
         return;
 
+    guild = objmgr.GetGuildById(GetPlayer()->GetGuildId());
+    if(!guild)
+    {
+        SendGuildCommandResult(GUILD_CREATE_S, "", GUILD_PLAYER_NOT_IN_GUILD);
+        return;
+    }
+    
+    if(!guild->HasRankRight(GetPlayer()->GetRank(), GR_RIGHT_REMOVE))
+    {
+        SendGuildCommandResult(GUILD_INVITE_S, "", GUILD_PERMISSIONS);
+        return;
+    }
+    
     player = ObjectAccessor::Instance().FindPlayerByName(plName.c_str());
-    guild = objmgr.GetGuildById(GetPlayer()->GetGuildId());
-
     if(player)
     {
@@ -179,19 +190,7 @@
     }
 
-    if(!guild)
-    {
-        SendGuildCommandResult(GUILD_CREATE_S, "", GUILD_PLAYER_NOT_IN_GUILD);
-        return;
-    }
-
     if(!plGuid)
     {
         SendGuildCommandResult(GUILD_INVITE_S, plName, GUILD_PLAYER_NOT_FOUND);
-        return;
-    }
-
-    if(!guild->HasRankRight(GetPlayer()->GetRank(), GR_RIGHT_REMOVE))
-    {
-        SendGuildCommandResult(GUILD_INVITE_S, "", GUILD_PERMISSIONS);
         return;
     }
@@ -297,9 +296,4 @@
 
     std::string plName;
-    uint64 plGuid;
-    uint32 plGuildId;
-    uint32 plRankId;
-    Player *player;
-    Guild *guild;
 
     //sLog.outDebug("WORLD: Received CMSG_GUILD_PROMOTE");
@@ -309,20 +303,6 @@
     if(!normalizePlayerName(plName))
         return;
-
-    player = ObjectAccessor::Instance().FindPlayerByName(plName.c_str());
-    guild = objmgr.GetGuildById(GetPlayer()->GetGuildId());
-    if(player)
-    {
-        plGuid = player->GetGUID();
-        plGuildId = player->GetGuildId();
-        plRankId = player->GetRank();
-    }
-    else
-    {
-        plGuid = objmgr.GetPlayerGUIDByName(plName);
-        plGuildId = Player::GetGuildIdFromDB(plGuid);
-        plRankId = Player::GetRankFromDB(plGuid);
-    }
-
+        
+    Guild* guild = objmgr.GetGuildById(GetPlayer()->GetGuildId());
     if(!guild)
     {
@@ -330,5 +310,13 @@
         return;
     }
-    else if(!plGuid)
+    if(!guild->HasRankRight(GetPlayer()->GetRank(), GR_RIGHT_PROMOTE))
+    {
+        SendGuildCommandResult(GUILD_INVITE_S, "", GUILD_PERMISSIONS);
+        return;
+    }
+    
+    uint64 plGuid = objmgr.GetPlayerGUIDByName(plName);
+    
+    if(!plGuid)
     {
         SendGuildCommandResult(GUILD_INVITE_S, plName, GUILD_PLAYER_NOT_FOUND);
@@ -340,22 +328,13 @@
         return;
     }
-    else if(GetPlayer()->GetGuildId() != plGuildId)
+    
+    int32 plRankId = guild->GetRank(GUID_LOPART(plGuid));
+    if(plRankId == -1)
     {
         SendGuildCommandResult(GUILD_INVITE_S, plName, GUILD_PLAYER_NOT_IN_GUILD_S);
         return;
     }
-    else if(!guild->HasRankRight(GetPlayer()->GetRank(), GR_RIGHT_PROMOTE))
-    {
-        SendGuildCommandResult(GUILD_INVITE_S, "", GUILD_PERMISSIONS);
-        return;
-    }
-    else if((plRankId-1) == 0 || (plRankId-1) < this->GetPlayer()->GetRank())
-        return;
-
-    if(plRankId < 1)
-    {
-        SendGuildCommandResult(GUILD_INVITE_S, "", GUILD_INTERNAL);
-        return;
-    }
+    if(plRankId < 2 || (plRankId-1) < GetPlayer()->GetRank())
+        return;
 
     uint32 newRankId = plRankId < guild->GetNrRanks() ? plRankId-1 : guild->GetNrRanks()-1;
@@ -379,9 +358,4 @@
 
     std::string plName;
-    uint64 plGuid;
-    uint32 plGuildId;
-    uint32 plRankId;
-    Player *player;
-    Guild *guild;
 
     //sLog.outDebug("WORLD: Received CMSG_GUILD_DEMOTE");
@@ -392,18 +366,5 @@
         return;
 
-    player = ObjectAccessor::Instance().FindPlayerByName(plName.c_str());
-    guild = objmgr.GetGuildById(GetPlayer()->GetGuildId());
-    if(player)
-    {
-        plGuid = player->GetGUID();
-        plGuildId = player->GetGuildId();
-        plRankId = player->GetRank();
-    }
-    else
-    {
-        plGuid = objmgr.GetPlayerGUIDByName(plName);
-        plGuildId = Player::GetGuildIdFromDB(plGuid);
-        plRankId = Player::GetRankFromDB(plGuid);
-    }
+    Guild* guild = objmgr.GetGuildById(GetPlayer()->GetGuildId());
 
     if(!guild)
@@ -412,4 +373,12 @@
         return;
     }
+    
+    if(!guild->HasRankRight(GetPlayer()->GetRank(), GR_RIGHT_DEMOTE))
+    {
+        SendGuildCommandResult(GUILD_INVITE_S, "", GUILD_PERMISSIONS);
+        return;
+    }
+    
+    uint64 plGuid = objmgr.GetPlayerGUIDByName(plName);
 
     if( !plGuid )
@@ -425,13 +394,8 @@
     }
 
-    if(GetPlayer()->GetGuildId() != plGuildId)
+    int32 plRankId = guild->GetRank(GUID_LOPART(plGuid));
+    if(plRankId == -1)
     {
         SendGuildCommandResult(GUILD_INVITE_S, plName, GUILD_PLAYER_NOT_IN_GUILD_S);
-        return;
-    }
-
-    if(!guild->HasRankRight(GetPlayer()->GetRank(), GR_RIGHT_DEMOTE))
-    {
-        SendGuildCommandResult(GUILD_INVITE_S, "", GUILD_PERMISSIONS);
         return;
     }
@@ -536,4 +500,18 @@
     if(!normalizePlayerName(name))
         return;
+        
+    guild = objmgr.GetGuildById(oldLeader->GetGuildId());
+    
+    if(!guild)
+    {
+        SendGuildCommandResult(GUILD_CREATE_S, "", GUILD_PLAYER_NOT_IN_GUILD);
+        return;
+    }
+    
+    if(oldLeader->GetGUID() != guild->GetLeader())
+    {
+        SendGuildCommandResult(GUILD_INVITE_S, "", GUILD_PERMISSIONS);
+        return;
+    }
 
     newLeader = ObjectAccessor::Instance().FindPlayerByName(name.c_str());
@@ -548,12 +526,5 @@
         newLeaderGuild = Player::GetGuildIdFromDB(newLeaderGUID);
     }
-    guild = objmgr.GetGuildById(oldLeader->GetGuildId());
-
-    if(!guild)
-    {
-        SendGuildCommandResult(GUILD_CREATE_S, "", GUILD_PLAYER_NOT_IN_GUILD);
-        return;
-    }
-    else if(!newLeaderGUID)
+    if(!newLeaderGUID)
     {
         SendGuildCommandResult(GUILD_INVITE_S, name, GUILD_PLAYER_NOT_FOUND);
@@ -563,9 +534,4 @@
     {
         SendGuildCommandResult(GUILD_INVITE_S, name, GUILD_PLAYER_NOT_IN_GUILD_S);
-        return;
-    }
-    if(oldLeader->GetGUID() != guild->GetLeader())
-    {
-        SendGuildCommandResult(GUILD_INVITE_S, "", GUILD_PERMISSIONS);
         return;
     }
@@ -636,6 +602,18 @@
         return;
 
+    guild = objmgr.GetGuildById(GetPlayer()->GetGuildId());
+    if(!guild)
+    {
+        SendGuildCommandResult(GUILD_CREATE_S, "", GUILD_PLAYER_NOT_IN_GUILD);
+        return;
+    }
+    
+    if(!guild->HasRankRight(GetPlayer()->GetRank(), GR_RIGHT_EPNOTE))
+    {
+        SendGuildCommandResult(GUILD_INVITE_S, "", GUILD_PERMISSIONS);
+        return;
+    }
+    
     player = ObjectAccessor::Instance().FindPlayerByName(name.c_str());
-    guild = objmgr.GetGuildById(GetPlayer()->GetGuildId());
     if(player)
     {
@@ -649,10 +627,5 @@
     }
 
-    if(!guild)
-    {
-        SendGuildCommandResult(GUILD_CREATE_S, "", GUILD_PLAYER_NOT_IN_GUILD);
-        return;
-    }
-    else if(!plGuid)
+    if(!plGuid)
     {
         SendGuildCommandResult(GUILD_INVITE_S, name, GUILD_PLAYER_NOT_FOUND);
@@ -662,9 +635,4 @@
     {
         SendGuildCommandResult(GUILD_INVITE_S, name, GUILD_PLAYER_NOT_IN_GUILD_S);
-        return;
-    }
-    if(!guild->HasRankRight(GetPlayer()->GetRank(), GR_RIGHT_EPNOTE))
-    {
-        SendGuildCommandResult(GUILD_INVITE_S, "", GUILD_PERMISSIONS);
         return;
     }
@@ -693,6 +661,17 @@
         return;
 
+    guild = objmgr.GetGuildById(GetPlayer()->GetGuildId());
+    if(!guild)
+    {
+        SendGuildCommandResult(GUILD_CREATE_S, "", GUILD_PLAYER_NOT_IN_GUILD);
+        return;
+    }
+    if(!guild->HasRankRight(GetPlayer()->GetRank(), GR_RIGHT_EOFFNOTE))
+    {
+        SendGuildCommandResult(GUILD_INVITE_S, "", GUILD_PERMISSIONS);
+        return;
+    }
+    
     player = ObjectAccessor::Instance().FindPlayerByName(plName.c_str());
-    guild = objmgr.GetGuildById(GetPlayer()->GetGuildId());
     if(player)
     {
@@ -706,10 +685,5 @@
     }
 
-    if(!guild)
-    {
-        SendGuildCommandResult(GUILD_CREATE_S, "", GUILD_PLAYER_NOT_IN_GUILD);
-        return;
-    }
-    else if( !plGuid )
+    if( !plGuid )
     {
         SendGuildCommandResult(GUILD_INVITE_S, plName, GUILD_PLAYER_NOT_FOUND);
@@ -719,9 +693,4 @@
     {
         SendGuildCommandResult(GUILD_INVITE_S, plName, GUILD_PLAYER_NOT_IN_GUILD_S);
-        return;
-    }
-    if(!guild->HasRankRight(GetPlayer()->GetRank(), GR_RIGHT_EOFFNOTE))
-    {
-        SendGuildCommandResult(GUILD_INVITE_S, "", GUILD_PERMISSIONS);
         return;
     }
Index: trunk/src/game/Creature.cpp
===================================================================
--- trunk/src/game/Creature.cpp (revision 168)
+++ trunk/src/game/Creature.cpp (revision 173)
@@ -854,14 +854,17 @@
             return;
     }
-    uint32 textid=GetGossipTextId( action, zoneid);
-    if(textid==0)
-        textid=GetNpcTextId();
 
     switch (gossip->Action)
     {
         case GOSSIP_OPTION_GOSSIP:
+        {
+            uint32 textid = GetGossipTextId(action, zoneid);
+            if (textid == 0)
+                textid=GetNpcTextId();
+
             player->PlayerTalkClass->CloseGossip();
             player->PlayerTalkClass->SendTalking(textid);
             break;
+		}
         case GOSSIP_OPTION_OUTDOORPVP:
             sOutdoorPvPMgr.HandleGossipOption(player, GetGUID(), option);
Index: trunk/src/game/ObjectMgr.cpp
===================================================================
--- trunk/src/game/ObjectMgr.cpp (revision 168)
+++ trunk/src/game/ObjectMgr.cpp (revision 173)
@@ -2729,5 +2729,5 @@
     uint32 count = 0;
     //                                                     0         1              2           3           4              5      6      7      8      9      10     11     12     13      14          15
-    QueryResult *result = CharacterDatabase.PQuery("SELECT mainTank, mainAssistant, lootMethod, looterGuid, lootThreshold, icon1, icon2, icon3, icon4, icon5, icon6, icon7, icon8, isRaid, difficulty, leaderGuid FROM groups");
+    QueryResult *result = CharacterDatabase.Query("SELECT mainTank, mainAssistant, lootMethod, looterGuid, lootThreshold, icon1, icon2, icon3, icon4, icon5, icon6, icon7, icon8, isRaid, difficulty, leaderGuid FROM groups");
 
     if( !result )
@@ -2771,5 +2771,5 @@
     leaderGuid = 0;
     //                                        0           1          2         3
-    result = CharacterDatabase.PQuery("SELECT memberGuid, assistant, subgroup, leaderGuid FROM group_member ORDER BY leaderGuid");
+    result = CharacterDatabase.Query("SELECT memberGuid, assistant, subgroup, leaderGuid FROM group_member ORDER BY leaderGuid");
     if(!result)
     {
@@ -2824,5 +2824,5 @@
     group = NULL;
     leaderGuid = 0;
-    result = CharacterDatabase.PQuery(
+    result = CharacterDatabase.Query(
         //      0           1    2         3          4           5
         "SELECT leaderGuid, map, instance, permanent, difficulty, resettime, "
@@ -3692,5 +3692,5 @@
 void ObjectMgr::LoadPetCreateSpells()
 {
-    QueryResult *result = WorldDatabase.PQuery("SELECT entry, Spell1, Spell2, Spell3, Spell4 FROM petcreateinfo_spell");
+    QueryResult *result = WorldDatabase.Query("SELECT entry, Spell1, Spell2, Spell3, Spell4 FROM petcreateinfo_spell");
     if(!result)
     {
@@ -4072,5 +4072,5 @@
 void ObjectMgr::LoadItemTexts()
 {
-    QueryResult *result = CharacterDatabase.PQuery("SELECT id, text FROM item_text");
+    QueryResult *result = CharacterDatabase.Query("SELECT id, text FROM item_text");
 
     uint32 count = 0;
@@ -4155,5 +4155,5 @@
     mPageTextLocaleMap.clear();
     
-    QueryResult *result = WorldDatabase.PQuery("SELECT entry,text_loc1,text_loc2,text_loc3,text_loc4,text_loc5,text_loc6,text_loc7,text_loc8 FROM locales_page_text");
+    QueryResult *result = WorldDatabase.Query("SELECT entry,text_loc1,text_loc2,text_loc3,text_loc4,text_loc5,text_loc6,text_loc7,text_loc8 FROM locales_page_text");
 
     if(!result)
@@ -5711,5 +5711,5 @@
     uint32 count = 0;
     //                                                     0           1           2           3            4    5     6     7            8         10
-    QueryResult *result = CharacterDatabase.PQuery("SELECT position_x, position_y, position_z, orientation, map, data, time, corpse_type, instance, guid FROM corpse WHERE corpse_type <> 0");
+    QueryResult *result = CharacterDatabase.Query("SELECT position_x, position_y, position_z, orientation, map, data, time, corpse_type, instance, guid FROM corpse WHERE corpse_type <> 0");
 
     if( !result )
@@ -6075,5 +6075,5 @@
     m_ReservedNames.clear();                                // need for reload case
 
-    QueryResult *result = WorldDatabase.PQuery("SELECT name FROM reserved_name");
+    QueryResult *result = WorldDatabase.Query("SELECT name FROM reserved_name");
 
     uint32 count = 0;
@@ -6962,5 +6962,5 @@
     std::set<uint32> skip_trainers;
 
-    QueryResult *result = WorldDatabase.PQuery("SELECT entry, spell,spellcost,reqskill,reqskillvalue,reqlevel FROM npc_trainer");
+    QueryResult *result = WorldDatabase.Query("SELECT entry, spell,spellcost,reqskill,reqskillvalue,reqlevel FROM npc_trainer");
 
     if( !result )
@@ -7053,5 +7053,5 @@
     std::set<uint32> skip_vendors;
 
-    QueryResult *result = WorldDatabase.PQuery("SELECT entry, item, maxcount, incrtime, ExtendedCost FROM npc_vendor");
+    QueryResult *result = WorldDatabase.Query("SELECT entry, item, maxcount, incrtime, ExtendedCost FROM npc_vendor");
     if( !result )
     {
@@ -7099,5 +7099,5 @@
     m_mCacheNpcTextIdMap.clear();
 
-    QueryResult* result = WorldDatabase.PQuery("SELECT npc_guid, textid FROM npc_gossip");
+    QueryResult* result = WorldDatabase.Query("SELECT npc_guid, textid FROM npc_gossip");
     if( !result )
     {
Index: trunk/src/game/Map.cpp
===================================================================
--- trunk/src/game/Map.cpp (revision 149)
+++ trunk/src/game/Map.cpp (revision 173)
@@ -1358,4 +1358,7 @@
             break;
         case TYPEID_UNIT:
+            // in case triggred sequence some spell can continue casting after prev CleanupsBeforeDelete call
+            // make sure that like sources auras/etc removed before destructor start
+            ((Creature*)obj)->CleanupsBeforeDelete ();
             Remove((Creature*)obj,true);
             break;
Index: trunk/src/game/SpellMgr.cpp
===================================================================
--- trunk/src/game/SpellMgr.cpp (revision 160)
+++ trunk/src/game/SpellMgr.cpp (revision 173)
@@ -1459,5 +1459,5 @@
     mSpellChainsNext.clear();                               // need for reload case
 
-    QueryResult *result = WorldDatabase.PQuery("SELECT spell_id, prev_spell, first_spell, rank, req_spell FROM spell_chain");
+    QueryResult *result = WorldDatabase.Query("SELECT spell_id, prev_spell, first_spell, rank, req_spell FROM spell_chain");
     if(result == NULL)
     {
@@ -1666,5 +1666,5 @@
     mSpellLearnSpells.clear();                              // need for reload case
 
-    QueryResult *result = WorldDatabase.PQuery("SELECT entry, SpellID FROM spell_learn_spell");
+    QueryResult *result = WorldDatabase.Query("SELECT entry, SpellID FROM spell_learn_spell");
     if(!result)
     {
Index: trunk/src/framework/Utilities/EventProcessor.cpp
===================================================================
--- trunk/src/framework/Utilities/EventProcessor.cpp (revision 102)
+++ trunk/src/framework/Utilities/EventProcessor.cpp (revision 173)
@@ -29,5 +29,5 @@
 EventProcessor::~EventProcessor()
 {
-    KillAllEvents();
+    KillAllEvents(true);
 }
 
@@ -61,5 +61,5 @@
 }
 
-void EventProcessor::KillAllEvents()
+void EventProcessor::KillAllEvents(bool force)
 {
     // prevent event insertions
@@ -67,13 +67,23 @@
 
     // first, abort all existing events
-    for (EventList::iterator i = m_events.begin(); i != m_events.end(); ++i)
+    for (EventList::iterator i = m_events.begin(); i != m_events.end();)
     {
-        i->second->to_Abort = true;
-        i->second->Abort(m_time);
-        delete i->second;
+        EventList::iterator i_old = i;
+        ++i;
+        
+        i_old->second->to_Abort = true;
+        i_old->second->Abort(m_time);
+        if(force || i_old->second->IsDeletable())
+        {
+            delete i_old->second;
+            
+            if(!force)                                      // need per-element cleanup
+                m_events.erase (i_old);
+        }
     }
 
-    // clear event list
-    m_events.clear();
+    // fast clear event list (in force case)
+    if(force)
+        m_events.clear();
 }
 
Index: trunk/src/framework/Utilities/EventProcessor.h
===================================================================
--- trunk/src/framework/Utilities/EventProcessor.h (revision 102)
+++ trunk/src/framework/Utilities/EventProcessor.h (revision 173)
@@ -40,4 +40,6 @@
         // e_time is execution time, p_time is update interval
         virtual bool Execute(uint64 /*e_time*/, uint32 /*p_time*/) { return true; }
+        
+        virtual bool IsDeletable() const { return true; }   // this event can be safely deleted
 
         virtual void Abort(uint64 /*e_time*/) {}            // this method executes when the event is aborted
@@ -60,5 +62,5 @@
 
         void Update(uint32 p_time);
-        void KillAllEvents();
+        void KillAllEvents(bool force);
         void AddEvent(BasicEvent* Event, uint64 e_time, bool set_addtime = true);
         uint64 CalculateTime(uint64 t_offset);
