diff --git a/src/game/Pet.h b/src/game/Pet.h
index 303d3ba..78c5169 100644
--- a/src/game/Pet.h
+++ b/src/game/Pet.h
@@ -223,6 +223,8 @@ class Pet : public Creature
         time_t  m_resetTalentsTime;
         uint32  m_usedTalentCount;
 
+        RedirectThreatMap* getRedirectThreatMap() { return &m_redirectMap; }
+
         const uint64& GetAuraUpdateMask() const { return m_auraUpdateMask; }
         void SetAuraUpdateMask(uint8 slot) { m_auraUpdateMask |= (uint64(1) << slot); }
         void ResetAuraUpdateMask() { m_auraUpdateMask = 0; }
@@ -252,5 +254,8 @@ class Pet : public Creature
         {
             assert(false);
         }
+
+        // Map used to control threat redirection effects
+        RedirectThreatMap m_redirectMap;
 };
 #endif
diff --git a/src/game/Player.h b/src/game/Player.h
index a30471d..d0af05c 100644
--- a/src/game/Player.h
+++ b/src/game/Player.h
@@ -2021,6 +2021,8 @@ class MANGOS_DLL_SPEC Player : public Unit
         }
         void HandleFall(MovementInfo const& movementInfo);
 
+        RedirectThreatMap* getRedirectThreatMap() { return &m_redirectMap; }
+
         void BuildTeleportAckMsg( WorldPacket *data, float x, float y, float z, float ang) const;
 
         bool isMoving() const { return m_movementInfo.HasMovementFlag(movementFlagsMask); }
@@ -2444,6 +2446,9 @@ class MANGOS_DLL_SPEC Player : public Unit
 
         AchievementMgr m_achievementMgr;
         ReputationMgr  m_reputationMgr;
+
+        // Map used to control threat redirection effects
+        RedirectThreatMap m_redirectMap;
 };
 
 void AddItemsSetItem(Player*player,Item *item);
diff --git a/src/game/Spell.h b/src/game/Spell.h
index 01c2506..3c0fa46 100644
--- a/src/game/Spell.h
+++ b/src/game/Spell.h
@@ -236,6 +236,7 @@ class Spell
         void EffectSummonChangeItem(uint32 i);
         void EffectProficiency(uint32 i);
         void EffectApplyAreaAura(uint32 i);
+        void EffectRedirectThreat(uint32 i);
         void EffectSummonType(uint32 i);
         void EffectSummon(uint32 i);
         void EffectLearnSpell(uint32 i);
diff --git a/src/game/SpellAuras.cpp b/src/game/SpellAuras.cpp
index 67ece8a..2803f01 100644
--- a/src/game/SpellAuras.cpp
+++ b/src/game/SpellAuras.cpp
@@ -2140,6 +2140,20 @@ void Aura::HandleAuraDummy(bool apply, bool Real)
                         bg->RemovePlayerFromResurrectQueue(m_target->GetGUID());
                 return;
             }
+            case 34477:                                     // Misdirection - aura applied to spell caster
+            {   
+                // We must remove target to which threat is redirected
+                m_target->RemoveRedirectThreatEntry(34477);
+                return;
+            }
+            case 35079:                                     // Misdirection - aura applied to spell target
+            {
+                if (m_removeMode == AURA_REMOVE_BY_STACK)
+                    // We must remove 34477 aura from first caster due to
+                    // "Caster and target can only be affected by one Misdirection spell at a time"
+                    GetCaster()->RemoveAurasDueToSpellByCancel(34477);
+                return;
+            }
             case 45934:                                     // Dark Fiend
             {
                 // Kill target if dispelled
@@ -2276,6 +2290,21 @@ void Aura::HandleAuraDummy(bool apply, bool Real)
                             m_target->PlayDirectSound(14972, (Player *)m_target);
                     }
                     return;
+                // Tricks of the Trade - 15% damage bonus effect for redirection target
+                case 59628:
+                    if (m_target->GetTypeId() == TYPEID_PLAYER)
+                    {
+                        RedirectThreatEntry* entry = m_target->GetRedirectThreatEntry(57934);
+                        if (!entry)
+                            return;
+
+                        if (apply && entry->m_redirectTo->isAlive())
+                                caster->CastSpell(entry->m_redirectTo,57933,true);
+                        else
+                            // We must remove target to which threat is redirected
+                            m_target->RemoveRedirectThreatEntry(57934);
+                    }
+                    return;
             }
             break;
         }
@@ -4156,6 +4185,14 @@ void Aura::HandleAuraProcTriggerSpell(bool apply, bool Real)
             default: break;
         }
     }
+
+    // Vigilance. We must apply threat redirect (59665) in some aura of main spell. Don't know where it's better to do it :(
+    if (GetId() == 50720)
+        if (apply)
+            GetCaster()->CastSpell(m_target,59665,true);
+        else
+            // We must remove target to which threat is redirected
+            m_target->RemoveRedirectThreatEntry(59665);
 }
 
 void Aura::HandleAuraModStalked(bool apply, bool /*Real*/)
diff --git a/src/game/SpellEffects.cpp b/src/game/SpellEffects.cpp
index c808c1f..ee0fe09 100644
--- a/src/game/SpellEffects.cpp
+++ b/src/game/SpellEffects.cpp
@@ -187,7 +187,7 @@ pEffect SpellEffects[TOTAL_SPELL_EFFECTS]=
     &Spell::EffectProspecting,                              //127 SPELL_EFFECT_PROSPECTING              Prospecting spell
     &Spell::EffectApplyAreaAura,                            //128 SPELL_EFFECT_APPLY_AREA_AURA_FRIEND
     &Spell::EffectApplyAreaAura,                            //129 SPELL_EFFECT_APPLY_AREA_AURA_ENEMY
-    &Spell::EffectNULL,                                     //130 SPELL_EFFECT_REDIRECT_THREAT
+    &Spell::EffectRedirectThreat,                           //130 SPELL_EFFECT_REDIRECT_THREAT
     &Spell::EffectUnused,                                   //131 SPELL_EFFECT_131                      used in some test spells
     &Spell::EffectNULL,                                     //132 SPELL_EFFECT_PLAY_MUSIC               sound id in misc value (SoundEntries.dbc)
     &Spell::EffectUnlearnSpecialization,                    //133 SPELL_EFFECT_UNLEARN_SPECIALIZATION   unlearn profession specialization
@@ -3163,6 +3163,35 @@ void Spell::EffectApplyAreaAura(uint32 i)
     unitTarget->AddAura(Aur);
 }
 
+void Spell::EffectRedirectThreat(uint32 i)
+{
+    if(!unitTarget)
+        return;
+    if(!unitTarget->isAlive())
+        return;
+
+    Unit* redirectFrom = 0; Unit* redirectTo = 0;
+    // Check by ID is sufficient as such spells have no ranks
+    switch (m_spellInfo->Id)
+    {
+        // Tricks of the Trade, Misdirection
+        case 57934: case 34477:
+            redirectFrom = m_caster;
+            redirectTo = unitTarget;
+            break;
+        // Vigilance
+        case 59665:
+            redirectFrom = unitTarget;
+            redirectTo = m_caster;
+            break;
+        // No need to continue
+        default:
+            return;
+    }
+
+    redirectFrom->AddRedirectThreatEntry(redirectTo,m_spellInfo->Id,float(damage)/100.0f);
+}
+
 void Spell::EffectSummonType(uint32 i)
 {
     switch(m_spellInfo->EffectMiscValueB[i])
@@ -4883,6 +4912,15 @@ void Spell::EffectScriptEffect(uint32 effIndex)
 
                     break;
                 }
+                // Vigilance
+                case 50725:
+                    if(RedirectThreatEntry* entry = m_caster->GetRedirectThreatEntry(59665))
+                    {
+                        // We must remove Taunt cooldown from Warrior when this spell triggers
+                        if (entry->m_redirectTo->GetTypeId() == TYPEID_PLAYER)
+                            ((Player*)entry->m_redirectTo)->RemoveSpellCooldown(355,true);
+                    }
+                    return;
                 // Emblazon Runeblade
                 case 51770:
                 {
diff --git a/src/game/ThreatManager.h b/src/game/ThreatManager.h
index d569480..7801528 100644
--- a/src/game/ThreatManager.h
+++ b/src/game/ThreatManager.h
@@ -43,6 +43,23 @@ class ThreatCalcHelper
 };
 
 //==============================================================
+// Data structures to handle threat redirection cases
+
+struct RedirectThreatEntry
+{
+    RedirectThreatEntry() : m_redirectTo(0), m_redirectPct(0)
+    {}
+    RedirectThreatEntry(Unit* redirectTo, float redirectPct)
+        : m_redirectTo(redirectTo), m_redirectPct(redirectPct)
+    {}
+
+    Unit* m_redirectTo;
+    float m_redirectPct;
+};
+typedef std::map<uint32,RedirectThreatEntry*> RedirectThreatMap;
+
+//==============================================================
+
 class MANGOS_DLL_SPEC HostilReference : public Reference<Unit, ThreatManager>
 {
     public:
diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp
index 7ca8598..2c9f592 100644
--- a/src/game/Unit.cpp
+++ b/src/game/Unit.cpp
@@ -5359,6 +5359,20 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAu
                     triggered_spell_id = 32747;
                     break;
                 }
+                // Tricks of the Trade
+                case 57934:
+                {
+                    if (this->GetTypeId() != TYPEID_PLAYER)
+                        return false;
+
+                    RedirectThreatEntry* entry = this->GetRedirectThreatEntry(57934);
+                    if (!entry)
+                        return false;
+                        
+                    triggered_spell_id = 59628;
+                    target = entry->m_redirectTo;
+                    break;
+                }
             }
             // Cut to the Chase
             if (dummySpell->SpellIconID == 2909)
@@ -9595,7 +9609,11 @@ void Unit::AddThreat(Unit* pVictim, float threat, SpellSchoolMask schoolMask, Sp
 {
     // Only mobs can manage threat lists
     if(CanHaveThreatList())
-        m_ThreatManager.addThreat(pVictim, threat, schoolMask, threatSpell);
+    {   
+        float remainThreatPct = AddThreatToRedirectionTargets(pVictim,threat,schoolMask,threatSpell);
+        if (remainThreatPct > 0)
+            m_ThreatManager.addThreat(pVictim, threat * remainThreatPct, schoolMask, threatSpell);
+    }
 }
 
 //======================================================================
@@ -9748,6 +9766,72 @@ bool Unit::SelectHostilTarget()
 //======================================================================
 //======================================================================
 
+RedirectThreatMap* Unit::GetRedirectThreatMap()
+{
+    if (GetTypeId() == TYPEID_PLAYER)
+        return ((Player*)this)->getRedirectThreatMap();
+    else if (((Creature*)this)->isPet())
+        return ((Pet*)this)->getRedirectThreatMap();
+
+    return NULL;
+}
+
+void Unit::AddRedirectThreatEntry(Unit* redirectTo, uint32 spellId, float redirectPct)
+{
+    if (RedirectThreatMap* map = GetRedirectThreatMap())
+    {
+        RedirectThreatEntry* entry = new RedirectThreatEntry(redirectTo,redirectPct);
+        map->insert(std::pair<uint32,RedirectThreatEntry*>(spellId,entry));
+    }
+}
+
+void Unit::RemoveRedirectThreatEntry(uint32 spellId)
+{
+    RedirectThreatMap* map = GetRedirectThreatMap();
+    if (map)
+    {
+        RedirectThreatEntry* entry = GetRedirectThreatEntry(map,spellId);
+        if (entry)
+        {
+            delete entry;
+            map->erase(spellId);
+        }
+    }
+}
+
+RedirectThreatEntry* Unit::GetRedirectThreatEntry(uint32 spellId)
+{
+    RedirectThreatMap* map = GetRedirectThreatMap();
+    return GetRedirectThreatEntry(map,spellId);
+}
+
+RedirectThreatEntry* Unit::GetRedirectThreatEntry(RedirectThreatMap* map, uint32 spellId)
+{
+    RedirectThreatMap::iterator iter = map->find(spellId);
+    if (iter != map->end())
+        return iter->second;
+
+    return NULL;
+}
+
+float Unit::AddThreatToRedirectionTargets(Unit* pVictim, float threat, SpellSchoolMask schoolMask, SpellEntry const *threatSpell)
+{
+    float remainThreatPct = 1.0f;
+
+    // Now let's see if threat generated by pVictim must be redirected
+    RedirectThreatMap* map = pVictim->GetRedirectThreatMap();
+    if (map && !map->empty())
+        for (RedirectThreatMap::iterator iter = map->begin(); iter != map->end(); ++iter)
+        {
+            m_ThreatManager.addThreat(iter->second->m_redirectTo, threat * (iter->second->m_redirectPct), schoolMask, threatSpell);
+            remainThreatPct -= iter->second->m_redirectPct;
+        }
+
+    return remainThreatPct;
+}
+
+//======================================================================
+
 int32 Unit::CalculateSpellDamage(SpellEntry const* spellProto, uint8 effect_index, int32 effBasePoints, Unit const* target)
 {
     Player* unitPlayer = (GetTypeId() == TYPEID_PLAYER) ? (Player*)this : NULL;
diff --git a/src/game/Unit.h b/src/game/Unit.h
index fe35362..d10ab4c 100644
--- a/src/game/Unit.h
+++ b/src/game/Unit.h
@@ -1339,6 +1339,12 @@ class MANGOS_DLL_SPEC Unit : public WorldObject
         void removeHatedBy(HostilReference* /*pHostilReference*/ ) { /* nothing to do yet */ }
         HostilRefManager& getHostilRefManager() { return m_HostilRefManager; }
 
+        // Threat redirection methods
+        RedirectThreatMap* GetRedirectThreatMap();
+        void AddRedirectThreatEntry(Unit* redirectTo, uint32 spellId, float redirectPct);
+        void RemoveRedirectThreatEntry(uint32 spellId);
+        RedirectThreatEntry* GetRedirectThreatEntry(uint32 spellId);
+
         uint32 GetVisibleAura(uint8 slot)
         {
             VisibleAuraMap::const_iterator itr = m_visibleAuras.find(slot);
@@ -1547,6 +1553,9 @@ class MANGOS_DLL_SPEC Unit : public WorldObject
         bool HandleOverrideClassScriptAuraProc(Unit *pVictim, uint32 damage, Aura* triggredByAura, SpellEntry const *procSpell, uint32 cooldown);
         bool HandleMeandingAuraProc(Aura* triggeredByAura);
 
+        RedirectThreatEntry* GetRedirectThreatEntry(RedirectThreatMap* map, uint32 spellId);
+        float AddThreatToRedirectionTargets(Unit* pVictim, float threat, SpellSchoolMask schoolMask, SpellEntry const *threatSpell);
+
         uint32 m_state;                                     // Even derived shouldn't modify
         uint32 m_CombatTimer;
         uint32 m_lastManaUse;                               // msecs
