Index: /trunk/src/game/SpellMgr.h
===================================================================
--- /trunk/src/game/SpellMgr.h (revision 253)
+++ /trunk/src/game/SpellMgr.h (revision 264)
@@ -285,5 +285,5 @@
 }
 
-bool IsNoStackAuraDueToAura(uint32 spellId_1, uint32 effIndex_1, uint32 spellId_2, uint32 effIndex_2);
+//bool IsNoStackAuraDueToAura(uint32 spellId_1, uint32 effIndex_1, uint32 spellId_2, uint32 effIndex_2);
 
 inline bool IsSealSpell(SpellEntry const *spellInfo)
@@ -301,5 +301,6 @@
 
 int32 CompareAuraRanks(uint32 spellId_1, uint32 effIndex_1, uint32 spellId_2, uint32 effIndex_2);
-bool IsSingleFromSpellSpecificPerCaster(uint32 spellSpec1,uint32 spellSpec2);
+bool IsSingleFromSpellSpecificPerCaster(uint32 spellSpec1, uint32 spellSpec2);
+bool IsSingleFromSpellSpecificPerTarget(uint32 spellSpec1, uint32 spellSpec2);
 bool IsPassiveSpell(uint32 spellId);
 
@@ -769,5 +770,5 @@
         bool IsRankSpellDueToSpell(SpellEntry const *spellInfo_1,uint32 spellId_2) const;
         static bool canStackSpellRanks(SpellEntry const *spellInfo);
-        bool IsNoStackSpellDueToSpell(uint32 spellId_1, uint32 spellId_2) const;
+        bool IsNoStackSpellDueToSpell(uint32 spellId_1, uint32 spellId_2, bool sameCaster) const;
 
         SpellEntry const* SelectAuraRankForPlayerLevel(SpellEntry const* spellInfo, uint32 playerLevel) const;
Index: /trunk/src/game/Unit.cpp
===================================================================
--- /trunk/src/game/Unit.cpp (revision 257)
+++ /trunk/src/game/Unit.cpp (revision 264)
@@ -3896,14 +3896,15 @@
         if(!is_triggered_by_spell)
         {
-            SpellSpecific i_spellId_spec = GetSpellSpecific(i_spellId);
-
-            bool is_sspc = IsSingleFromSpellSpecificPerCaster(spellId_spec,i_spellId_spec);
-
-            if( is_sspc && Aur->GetCasterGUID() == (*i).second->GetCasterGUID() )
-            {
-                // cannot remove higher rank
-                if (spellmgr.IsRankSpellDueToSpell(spellProto, i_spellId))
-                    if(CompareAuraRanks(spellId, effIndex, i_spellId, i_effIndex) < 0)
-                        return false;
+            bool sameCaster = Aur->GetCasterGUID() == (*i).second->GetCasterGUID();
+            if( spellmgr.IsNoStackSpellDueToSpell(spellId, i_spellId, sameCaster) )
+            {
+                //some spells should be not removed by lower rank of them
+                // what is this spell?
+                if (!sameCaster
+                    &&(spellProto->Effect[effIndex]==SPELL_EFFECT_APPLY_AREA_AURA_PARTY)
+                    &&(spellProto->DurationIndex==21)
+                    &&(spellmgr.IsRankSpellDueToSpell(spellProto, i_spellId))
+                    &&(CompareAuraRanks(spellId, effIndex, i_spellId, i_effIndex) < 0))
+                    return false;
 
                 // Its a parent aura (create this aura in ApplyModifier)
@@ -3919,37 +3920,4 @@
                 else
                     next =  m_Auras.begin();
-            }
-            else if( !is_sspc && spellmgr.IsNoStackSpellDueToSpell(spellId, i_spellId) )
-            {
-                // Its a parent aura (create this aura in ApplyModifier)
-                if ((*i).second->IsInUse())
-                {
-                    sLog.outError("Aura (Spell %u Effect %u) is in process but attempt removed at aura (Spell %u Effect %u) adding, need add stack rule for Unit::RemoveNoStackAurasDueToAura", i->second->GetId(), i->second->GetEffIndex(),Aur->GetId(), Aur->GetEffIndex());
-                    continue;
-                }
-                RemoveAurasDueToSpell(i_spellId);
-
-                if( m_Auras.empty() )
-                    break;
-                else
-                    next =  m_Auras.begin();
-            }
-            // Potions stack aura by aura (elixirs/flask already checked)
-            else if( spellProto->SpellFamilyName == SPELLFAMILY_POTION && i_spellProto->SpellFamilyName == SPELLFAMILY_POTION )
-            {
-                if (IsNoStackAuraDueToAura(spellId, effIndex, i_spellId, i_effIndex))
-                {
-                    if(CompareAuraRanks(spellId, effIndex, i_spellId, i_effIndex) < 0)
-                        return false;                       // cannot remove higher rank
-
-                    // Its a parent aura (create this aura in ApplyModifier)
-                    if ((*i).second->IsInUse())
-                    {
-                        sLog.outError("Aura (Spell %u Effect %u) is in process but attempt removed at aura (Spell %u Effect %u) adding, need add stack rule for Unit::RemoveNoStackAurasDueToAura", i->second->GetId(), i->second->GetEffIndex(),Aur->GetId(), Aur->GetEffIndex());
-                        continue;
-                    }
-                    RemoveAura(i);
-                    next = i;
-                }
             }
         }
Index: /trunk/src/game/SpellMgr.cpp
===================================================================
--- /trunk/src/game/SpellMgr.cpp (revision 253)
+++ /trunk/src/game/SpellMgr.cpp (revision 264)
@@ -100,5 +100,5 @@
 }
 
-bool IsNoStackAuraDueToAura(uint32 spellId_1, uint32 effIndex_1, uint32 spellId_2, uint32 effIndex_2)
+/*bool IsNoStackAuraDueToAura(uint32 spellId_1, uint32 effIndex_1, uint32 spellId_2, uint32 effIndex_2)
 {
     SpellEntry const *spellInfo_1 = sSpellStore.LookupEntry(spellId_1);
@@ -114,5 +114,5 @@
 
     return true;
-}
+}*/
 
 int32 CompareAuraRanks(uint32 spellId_1, uint32 effIndex_1, uint32 spellId_2, uint32 effIndex_2)
@@ -245,4 +245,17 @@
         case SPELL_CURSE:
         case SPELL_ASPECT:
+        case SPELL_POSITIVE_SHOUT:
+        case SPELL_JUDGEMENT:
+        case SPELL_WARLOCK_CORRUPTION:
+            return spellSpec1==spellSpec2;
+        default:
+            return false;
+    }
+}
+
+bool IsSingleFromSpellSpecificPerTarget(uint32 spellSpec1,uint32 spellSpec2)
+{
+    switch(spellSpec1)
+    {
         case SPELL_TRACKER:
         case SPELL_WARLOCK_ARMOR:
@@ -250,7 +263,4 @@
         case SPELL_ELEMENTAL_SHIELD:
         case SPELL_MAGE_POLYMORPH:
-        case SPELL_POSITIVE_SHOUT:
-        case SPELL_JUDGEMENT:
-        case SPELL_WARLOCK_CORRUPTION:
             return spellSpec1==spellSpec2;
         case SPELL_BATTLE_ELIXIR:
@@ -1031,8 +1041,8 @@
 }
 
-bool SpellMgr::IsNoStackSpellDueToSpell(uint32 spellId_1, uint32 spellId_2) const
-{
-    if(spellId_1 == spellId_2) // auras due to the same spell
-        return false;
+bool SpellMgr::IsNoStackSpellDueToSpell(uint32 spellId_1, uint32 spellId_2, bool sameCaster) const
+{
+    //if(spellId_1 == spellId_2) // auras due to the same spell
+    //    return false;
 
     SpellEntry const *spellInfo_1 = sSpellStore.LookupEntry(spellId_1);
@@ -1042,8 +1052,16 @@
         return false;
 
+    SpellSpecific spellId_spec_1 = GetSpellSpecific(spellId_1);
+    SpellSpecific spellId_spec_2 = GetSpellSpecific(spellId_2);
+    if (spellId_spec_1 && spellId_spec_2)
+        if (IsSingleFromSpellSpecificPerTarget(spellId_spec_1, spellId_spec_2)
+            ||(IsSingleFromSpellSpecificPerCaster(spellId_spec_1, spellId_spec_2) && sameCaster))
+            return true;
+
     if(spellInfo_1->SpellFamilyName != spellInfo_2->SpellFamilyName)
         return false;
 
-    if(!spellInfo_1->SpellFamilyName) // generic spells
+    // generic spells
+    if(!spellInfo_1->SpellFamilyName)
     {
         if(!spellInfo_1->SpellIconID 
@@ -1051,11 +1069,46 @@
             return false;
     }
-    else if (spellInfo_1->SpellFamilyFlags != spellInfo_2->SpellFamilyFlags)
-        return false;
+
+    // if both elixirs are not battle/guardian/potions/flasks then always stack
+    else if(spellInfo_1->SpellFamilyName == SPELLFAMILY_POTION)
+    {
+        if(spellId_spec_1 || spellId_spec_2))
+            return false;
+    }
+
+    // check for class spells
+    else
+    {
+        if (spellInfo_1->SpellFamilyFlags != spellInfo_2->SpellFamilyFlags)
+            return false;
+    }
 
     for(uint32 i = 0; i < 3; ++i)
+    {
         if(spellInfo_1->Effect[i] != spellInfo_2->Effect[i]
-            || spellInfo_1->EffectApplyAuraName[i] != spellInfo_2->EffectApplyAuraName[i])
-            return false;
+            || spellInfo_1->EffectApplyAuraName[i] != spellInfo_2->EffectApplyAuraName[i]
+            || spellInfo_1->EffectMiscValue[i] != spellInfo_2->EffectMiscValue[i]) // paladin resist aura
+            return false; // need itemtype check? need an example to add that check
+
+        if(spellInfo_1->EffectApplyAuraName[i] // both spell has the same auras
+            && !sameCaster
+            && spellInfo_1->Effect[i] != SPELL_EFFECT_APPLY_AREA_AURA_PARTY) // not area auras (shaman totem)
+            // a better check may be effect == SPELL_EFFECT_APPLY_AURA
+        {
+            switch(spellInfo_1->EffectApplyAuraName[i])
+            {
+                // DOT or HOT from different casters will stack
+                case SPELL_AURA_PERIODIC_DAMAGE:
+                case SPELL_AURA_PERIODIC_HEAL:
+                case SPELL_AURA_PERIODIC_TRIGGER_SPELL:
+                case SPELL_AURA_PERIODIC_ENERGIZE:
+                case SPELL_AURA_PERIODIC_MANA_LEECH:
+                case SPELL_AURA_PERIODIC_LEECH:
+                    return false;
+                default:
+                    break;
+            }
+        }
+    }
 
     return true;
