/** {@inheritDoc} */
  @Override
  public AtmosphereResource<?, ?> removeAtmosphereResource(AtmosphereResource r) {

    if (destroyed.get())
      throw new IllegalStateException("This Broadcaster has been destroyed and cannot be used");

    if (!resources.contains(r)) {
      return null;
    }
    resources.remove(r);

    // Will help preventing OOM.
    if (resources.isEmpty()) {
      notifyEmptyListener();
      if (lifeCyclePolicy.getLifeCyclePolicy()
          == BroadcasterLifeCyclePolicy.ATMOSPHERE_RESOURCE_POLICY.EMPTY) {
        releaseExternalResources();
      } else if (lifeCyclePolicy.getLifeCyclePolicy()
          == BroadcasterLifeCyclePolicy.ATMOSPHERE_RESOURCE_POLICY.EMPTY_DESTROY) {
        notifyDestroyListener();
        BroadcasterFactory.getDefault().remove(this, name);
        destroy();
      }
    }
    return r;
  }
  /** {@inheritDoc} */
  @Override
  public void setBroadcasterLifeCyclePolicy(final BroadcasterLifeCyclePolicy lifeCyclePolicy) {
    this.lifeCyclePolicy = lifeCyclePolicy;
    if (currentLifecycleTask != null) {
      currentLifecycleTask.cancel(false);
    }

    if (lifeCyclePolicy.getLifeCyclePolicy()
            == BroadcasterLifeCyclePolicy.ATMOSPHERE_RESOURCE_POLICY.IDLE
        || lifeCyclePolicy.getLifeCyclePolicy()
            == BroadcasterLifeCyclePolicy.ATMOSPHERE_RESOURCE_POLICY.IDLE_DESTROY) {

      int time = lifeCyclePolicy.getTimeout();
      if (time == -1) {
        throw new IllegalStateException("BroadcasterLifeCyclePolicy time is not set");
      }

      final AtomicReference<Future<?>> ref = new AtomicReference<Future<?>>();
      currentLifecycleTask =
          bc.getScheduledExecutorService()
              .scheduleAtFixedRate(
                  new Runnable() {

                    @Override
                    public void run() {
                      try {
                        if (resources.isEmpty()) {
                          notifyEmptyListener();
                          notifyIdleListener();

                          if (lifeCyclePolicy.getLifeCyclePolicy()
                              == BroadcasterLifeCyclePolicy.ATMOSPHERE_RESOURCE_POLICY.IDLE) {
                            releaseExternalResources();
                            logger.debug("Applying BroadcasterLifeCyclePolicy IDLE policy");
                          } else {
                            notifyDestroyListener();

                            destroy();
                            /**
                             * The value may be null if the timeout is too low. Hopefully next
                             * execution will cancel the task properly.
                             */
                            if (ref.get() != null) {
                              currentLifecycleTask.cancel(true);
                            }

                            logger.debug("Applying BroadcasterLifeCyclePolicy IDLE_DESTROY policy");
                          }
                        }
                      } catch (Throwable t) {
                        logger.warn("Scheduled BroadcasterLifeCyclePolicy exception", t);
                      }
                    }
                  },
                  time,
                  time,
                  lifeCyclePolicy.getTimeUnit());
      ref.set(currentLifecycleTask);
    }
  }