public void del(final UUID playerUUID, String effectName) {
    OfflinePlayer player = getPlayer(playerUUID, false);
    AbstractEffect effect = getEffect(playerUUID, effectName);
    if (effect == null) {
      throw new IllegalArgumentException(
          "The effect"
              + effectName
              + " were not associated to the player "
              + player.getName()
              + ".");
    }
    for (Class<? extends AbstractEventListener<?>> eventListenerClass : effect.getNeededEvents()) {
      AbstractEventListener<?> eventListener = null;
      try {
        eventListener = EventListenerManager.getInstance().getEventListener(eventListenerClass);
        if (eventListener == null) {
          throw new IllegalArgumentException("An error occured during the EventListener removal.");
        }
      } catch (InstantiationException
          | IllegalAccessException
          | InvocationTargetException
          | SecurityException e) {
        e.printStackTrace();
        throw new IllegalArgumentException(
            "An error occured during the EventListener removal: " + e.getClass().toString() + ".");
      }
      eventListener.deleteObserver(effect);
      if (eventListener.countObservers() == 0) {
        try {
          EventListenerManager.getInstance().removeIfNeeded(eventListener);
        } catch (IllegalAccessException e) {
          e.printStackTrace();
          throw new IllegalArgumentException(
              "An error occured during the EventListener removal: "
                  + e.getClass().toString()
                  + ".");
        }
      }
    }
    effect.onDisable();
    final AbstractEffect effectToDelete = effect;
    int disableDelay = effect.getDisableDelay();
    if (disableDelay > 0) {
      runTaskLater(
          new Runnable() {

            @Override
            public void run() {
              EffectManagerPlugin.getPlugin(EffectManagerPlugin.class)
                  .getPlayerEffectManager()
                  .getEffectsForPlayer(playerUUID)
                  .remove(effectToDelete);
            }
          },
          effect.getDisableDelay());
    } else {
      this.playersEffects.get(playerUUID).remove(effect);
    }
  }
  private void del(UUID playerUUID, AbstractEffect effect) {
    try {
      for (Class<? extends AbstractEventListener<?>> eventListenerClass :
          effect.getNeededEvents()) {
        AbstractEventListener<?> eventListener;

        eventListener = EventListenerManager.getInstance().getEventListener(eventListenerClass);
        EntityDamageEvent.getHandlerList();
        eventListener.deleteObserver(effect);
        if (eventListener.countObservers() == 0) {
          Class<?> eventClass = eventListener.getObservedEvent();
          Method method = eventClass.getMethod("getHandlerList");
          HandlerList hl = (HandlerList) method.invoke(null);
          hl.unregister(plugin);
        }
      }
    } catch (NoSuchMethodException
        | InstantiationException
        | IllegalAccessException
        | InvocationTargetException
        | SecurityException e) {
      e.printStackTrace();
      throw new IllegalArgumentException(
          "An error occured during the effect deletion: " + e.getClass().toString() + ".", e);
    }
    getEffectsForPlayer(playerUUID).remove(effect);
    ;
  }
  public void add(UUID playerUUID, String effectName, Boolean checkIfPlayerIsConnected)
      throws IllegalArgumentException {
    OfflinePlayer player = getPlayer(playerUUID, true);
    checkEffect(effectName);
    // verifie que ce type d'effet n'est pas deja attribue au joueur.
    AbstractEffect effect = (AbstractEffect) plugin.getEffectManager().get(effectName);
    checkEffectTypeDuplication(player.getPlayer(), effect, false);
    // recupere et si necessaire cree le(s) eventListener(s) appropries
    try {
      effect = effect.applyToPlayer(playerUUID);
    } catch (CloneNotSupportedException e) {
      throw new IllegalArgumentException(
          "An error occured during the player's effect creation " + e.getClass().toString() + ".");
    }
    for (Class<? extends AbstractEventListener<?>> eventListenerClass : effect.getNeededEvents()) {
      AbstractEventListener<?> eventListener = null;
      try {
        eventListener = EventListenerManager.getInstance().getEventListener(eventListenerClass);
        if (eventListener == null) {
          throw new IllegalArgumentException("An error occured during the EventListener creation.");
        }
      } catch (InstantiationException
          | IllegalAccessException
          | InvocationTargetException
          | SecurityException e) {
        e.printStackTrace();
        throw new IllegalArgumentException(
            "An error occured during the EventListener creation: " + e.getClass().toString() + ".");
      }

      // associe le(s) eventListener(s) approprie(s) a l effet
      eventListener.addObserver(effect);
    }

    // On rempli la map des effets du joueur avec le nouvel effet.
    if (this.playersEffects.get(playerUUID) == null) {
      this.playersEffects.put(playerUUID, new ArrayList<AbstractEffect>());
    }
    this.playersEffects.get(playerUUID).add(effect);
    effect.onEnable();
  }
 public void removeListener(IEventHandler listener) {
   synchronized (eventManagerMap) {
     for (EventListenerManager manager : eventManagerMap.values())
       manager.removeListener(listener);
   }
 }