/** @param effect */
  public void addEffect(Effect effect) {
    Map<String, Effect> mapToUpdate = getMapForEffect(effect);

    Effect existingEffect = mapToUpdate.get(effect.getStack());
    if (existingEffect != null) {
      // Check stack level
      if (existingEffect.getSkillStackLvl() > effect.getSkillStackLvl()) return;

      // Check skill level (when stack level same)
      if (existingEffect.getSkillStackLvl() == effect.getSkillStackLvl()
          && existingEffect.getSkillLevel() > effect.getSkillLevel()) return;

      existingEffect.endEffect();
    }

    if (effect.isToggle() && mapToUpdate.size() >= 3) {
      Iterator<Effect> iter = mapToUpdate.values().iterator();
      Effect nextEffect = iter.next();
      nextEffect.endEffect();
      iter.remove();
    }

    mapToUpdate.put(effect.getStack(), effect);
    effect.startEffect(false);

    if (!effect.isPassive()) {
      broadCastEffects();
    }
  }
 /**
  * Removes all effects from controllers and ends them appropriately Passive effect will not be
  * removed
  */
 public void removeAllEffects() {
   for (Effect effect : abnormalEffectMap.values()) {
     effect.endEffect();
   }
   abnormalEffectMap.clear();
   for (Effect effect : noshowEffects.values()) {
     effect.endEffect();
   }
   noshowEffects.clear();
 }
 /**
  * @see TargetSlot
  * @param targetSlot
  */
 public void removeAbnormalEffectsByTargetSlot(SkillTargetSlot targetSlot) {
   for (Effect effect : abnormalEffectMap.values()) {
     if (effect.getTargetSlot() == targetSlot.ordinal()) {
       effect.endEffect();
       abnormalEffectMap.remove(effect.getStack());
     }
   }
 }
 /**
  * Removes the effect by skillid.
  *
  * @param skillid
  */
 public void removePassiveEffect(int skillid) {
   for (Effect effect : passiveEffectMap.values()) {
     if (effect.getSkillId() == skillid) {
       effect.endEffect();
       passiveEffectMap.remove(effect.getStack());
     }
   }
 }
 /** @param skillid */
 public void removeNoshowEffect(int skillid) {
   for (Effect effect : noshowEffects.values()) {
     if (effect.getSkillId() == skillid) {
       effect.endEffect();
       noshowEffects.remove(effect.getStack());
     }
   }
 }
 /** @param effectId */
 public void removeEffectByEffectId(int effectId) {
   for (Effect effect : abnormalEffectMap.values()) {
     if (effect.containsEffectId(effectId)) {
       effect.endEffect();
       abnormalEffectMap.remove(effect.getStack());
     }
   }
 }
  /**
   * @param skillType
   * @param value
   */
  public void removeEffectBySkillType(SkillType skillType, int value) {
    for (Effect effect : abnormalEffectMap.values()) {
      if (value == 0) break;

      if (effect.getSkillType() == skillType) {
        effect.endEffect();
        abnormalEffectMap.remove(effect.getStack());
        value--;
      }
    }
  }
 /**
  * Removes the effect by SkillSetException Number.
  *
  * @param SkillSetException Number
  */
 public void removeEffectBySetNumber(final int setNumber) {
   for (Effect effect : abnormalEffectMap.values()) {
     if (effect.getSkillSetException() == setNumber) {
       effect.endEffect();
       abnormalEffectMap.remove(effect.getStack());
     }
   }
   for (Effect effect : passiveEffectMap.values()) {
     if (effect.getSkillSetException() == setNumber) {
       effect.endEffect();
       passiveEffectMap.remove(effect.getStack());
     }
   }
   for (Effect effect : noshowEffects.values()) {
     if (effect.getSkillSetException() == setNumber) {
       effect.endEffect();
       noshowEffects.remove(effect.getStack());
     }
   }
 }
  /**
   * @param targetSlot
   * @param count
   */
  public void removeEffectByTargetSlot(SkillTargetSlot targetSlot, int count) {
    for (Effect effect : abnormalEffectMap.values()) {
      if (count == 0) break;

      if (effect.getTargetSlot() == targetSlot.ordinal()) {
        if (targetSlot == SkillTargetSlot.BUFF && effect.getTargetSlotLevel() > 1) continue;
        effect.endEffect();
        abnormalEffectMap.remove(effect.getStack());
        count--;
      }
    }
  }
  /**
   * @param dispelCat
   * @param targetSlot
   * @param count
   */
  public void removeEffectByDispelCat(
      DispelCategoryType dispelCat, SkillTargetSlot targetSlot, int count) {
    for (Effect effect : abnormalEffectMap.values()) {
      if (count == 0) break;
      if (effect.getTargetSlot() == targetSlot.ordinal()) {
        boolean remove = false;
        switch (dispelCat) {
          case ALL:
            if (effect.getDispelCat() == DispelCategoryType.ALL
                || effect.getDispelCat() == DispelCategoryType.DEBUFF_MENTAL
                || effect.getDispelCat() == DispelCategoryType.DEBUFF_PHYSICAL) remove = true;
            break;
          case DEBUFF_MENTAL:
            if (effect.getDispelCat() == DispelCategoryType.ALL
                || effect.getDispelCat() == DispelCategoryType.DEBUFF_MENTAL) remove = true;
            break;
          case DEBUFF_PHYSICAL:
            if (effect.getDispelCat() == DispelCategoryType.ALL
                || effect.getDispelCat() == DispelCategoryType.DEBUFF_PHYSICAL) remove = true;
            break;
          case BUFF:
            if (effect.getDispelCat() == DispelCategoryType.BUFF && effect.getTargetSlotLevel() < 1)
              remove = true;
            break;
          case STUN:
            if (effect.getDispelCat() == DispelCategoryType.STUN) remove = true;
            break;
        }

        if (remove) {
          effect.endEffect();
          abnormalEffectMap.remove(effect.getStack());
          count--;
        }
      }
    }
  }