diff --git a/src/game/Spell.cpp b/src/game/Spell.cpp
index 51eb568..74f9b58 100644
--- a/src/game/Spell.cpp
+++ b/src/game/Spell.cpp
@@ -1122,9 +1122,7 @@ void Spell::DoSpellHitOnUnit(Unit *unit, const uint32 effectMask)
         return;
 
     // Recheck immune (only for delayed spells)
-    if( m_spellInfo->speed && (
-        unit->IsImmunedToDamage(GetSpellSchoolMask(m_spellInfo)) ||
-        unit->IsImmunedToSpell(m_spellInfo)))
+    if( m_spellInfo->speed && unit->IsImmunedToSpell(m_spellInfo))
     {
         m_caster->SendSpellMiss(unit, m_spellInfo->Id, SPELL_MISS_IMMUNE);
         return;
@@ -3847,14 +3845,15 @@ SpellCastResult Spell::CheckCast(bool strict)
                 if(m_caster->IsHostileTo(target))
                     return SPELL_FAILED_BAD_TARGETS;
             }
-            else
+            else if (!IsDispelSpell(m_spellInfo))
             {
                 if(m_caster->IsFriendlyTo(target))
                     return SPELL_FAILED_BAD_TARGETS;
             }
         }
 
-        if(IsPositiveSpell(m_spellInfo->Id))
+        // Dispel spells are considered negative, so let's do explicit check
+        if(IsPositiveSpell(m_spellInfo->Id) || (IsDispelSpell(m_spellInfo) && m_caster->IsFriendlyTo(target)))
             if(target->IsImmunedToSpell(m_spellInfo))
                 return SPELL_FAILED_TARGET_AURASTATE;
 
diff --git a/src/game/SpellEffects.cpp b/src/game/SpellEffects.cpp
index dd501c0..991f27d 100644
--- a/src/game/SpellEffects.cpp
+++ b/src/game/SpellEffects.cpp
@@ -3367,8 +3367,22 @@ void Spell::EffectDispel(uint32 i)
         // Dispell N = damage buffs (or while exist buffs for dispel)
         for (int32 count=0; count < damage && list_size > 0; ++count)
         {
+            Aura *aur = NULL;
+            // Effects granting full immunity have highest priority during dispel
+            for (std::vector<Aura *>::const_iterator iter = dispel_list.begin(), next; iter != dispel_list.end(); iter = next)
+            {
+                next = iter;
+                ++next;
+                if (next == dispel_list.end() || (*iter)->GetId() != (*next)->GetId())
+                    if (GetAllSpellImmunityMask((*iter)->GetSpellProto()) == SPELL_SCHOOL_MASK_ALL)
+                    {
+                        aur = (*iter);
+                        break;
+                    }
+            }
             // Random select buff for dispel
-            Aura *aur = dispel_list[urand(0, list_size-1)];
+            if (!aur)
+                aur = dispel_list[urand(0, list_size-1)];
 
             SpellEntry const* spellInfo = aur->GetSpellProto();
             // Base dispel chance
diff --git a/src/game/SpellMgr.cpp b/src/game/SpellMgr.cpp
index 5ae4bd9..f6a3d47 100644
--- a/src/game/SpellMgr.cpp
+++ b/src/game/SpellMgr.cpp
@@ -306,6 +306,9 @@ bool IsPositiveEffect(uint32 spellId, uint32 effIndex)
 
     switch(spellproto->Effect[effIndex])
     {
+        // consider dispel as always negative effect (explicit check will be performed later)
+        case SPELL_EFFECT_DISPEL:
+            return false;
         // always positive effects (check before target checks that provided non-positive result in some case for positive effects)
         case SPELL_EFFECT_HEAL:
         case SPELL_EFFECT_LEARN_SPELL:
diff --git a/src/game/SpellMgr.h b/src/game/SpellMgr.h
index a6d238e..e06a073 100644
--- a/src/game/SpellMgr.h
+++ b/src/game/SpellMgr.h
@@ -263,6 +263,15 @@ inline SpellSchoolMask GetSpellSchoolMask(SpellEntry const* spellInfo)
     return SpellSchoolMask(spellInfo->SchoolMask);
 }
 
+inline SpellSchoolMask GetAllSpellImmunityMask(SpellEntry const* spellInfo)
+{
+    uint32 mask = 0;
+    for (int i=0; i< 3; ++i)
+        if (spellInfo->EffectMiscValue[i] && spellInfo->EffectApplyAuraName[i] == SPELL_AURA_SCHOOL_IMMUNITY)
+            mask |= spellInfo->EffectMiscValue[i];
+    return SpellSchoolMask(mask);
+}
+
 inline uint32 GetSpellMechanicMask(SpellEntry const* spellInfo, int32 effect)
 {
     uint32 mask = 0;
diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp
index 3bdb02d..87a65dd 100644
--- a/src/game/Unit.cpp
+++ b/src/game/Unit.cpp
@@ -2649,9 +2649,10 @@ SpellMissInfo Unit::SpellHitResult(Unit *pVictim, SpellEntry const *spell, bool
     if (IsPositiveSpell(spell->Id))
         return SPELL_MISS_NONE;
 
-    // Check for immune
-    if (pVictim->IsImmunedToDamage(GetSpellSchoolMask(spell)))
-        return SPELL_MISS_IMMUNE;
+    // Dispel is positive when casted on friendly target and negative otherwise
+    if (IsDispelSpell(spell))
+        if (this->IsFriendlyTo(pVictim))
+            return SPELL_MISS_NONE;
 
     // Try victim reflect spell
     if (CanReflect)
@@ -8418,6 +8419,10 @@ bool Unit::IsImmunedToSpell(SpellEntry const* spellInfo)
     //TODO add spellEffect immunity checks!, player with flag in bg is imune to imunity buffs from other friendly players!
     //SpellImmuneList const& dispelList = m_spellImmune[IMMUNITY_EFFECT];
 
+    // Priest's Mass Dispel can not be immuned (but can be resisted)
+    if (spellInfo->SpellFamilyName == SPELLFAMILY_PRIEST && spellInfo->SpellFamilyFlags == UI64LIT(0x8000000000))
+        return false;
+
     SpellImmuneList const& dispelList = m_spellImmune[IMMUNITY_DISPEL];
     for(SpellImmuneList::const_iterator itr = dispelList.begin(); itr != dispelList.end(); ++itr)
         if(itr->type == spellInfo->Dispel)
@@ -8435,12 +8440,13 @@ bool Unit::IsImmunedToSpell(SpellEntry const* spellInfo)
 
     SpellImmuneList const& mechanicList = m_spellImmune[IMMUNITY_MECHANIC];
     for(SpellImmuneList::const_iterator itr = mechanicList.begin(); itr != mechanicList.end(); ++itr)
-    {
         if(itr->type == spellInfo->Mechanic)
-        {
             return true;
-        }
-    }
+
+    SpellImmuneList const& damageList = m_spellImmune[IMMUNITY_DAMAGE];
+    for (SpellImmuneList::const_iterator itr = damageList.begin(); itr != damageList.end(); ++itr)
+        if(itr->type & GetSpellSchoolMask(spellInfo))
+            return true;
 
     return false;
 }
