public final void disable(final boolean async) {
    if (!m_enabled) {
      return;
    }
    CountDownLatch enableLatch = null;
    try {
      enableLatch = enableLatchWait();
      if (!async) {
        deactivateInternal(
            ComponentConstants.DEACTIVATION_REASON_DISABLED, true, m_trackingCount.get());
      }
      disableInternal();
    } finally {
      if (!async) {
        enableLatch.countDown();
      }
      m_enabled = false;
    }

    if (async) {
      final CountDownLatch latch = enableLatch;
      m_activator.schedule(
          new Runnable() {

            long count = taskCounter.incrementAndGet();

            public void run() {
              try {
                deactivateInternal(
                    ComponentConstants.DEACTIVATION_REASON_DISABLED, true, m_trackingCount.get());
              } finally {
                latch.countDown();
              }
            }

            public String toString() {
              return "Async Deactivate: " + getComponentMetadata().getName() + " id: " + count;
            }
          });
    }
  }
  public final void enable(final boolean async) {
    if (m_enabled) {
      return;
    }
    CountDownLatch enableLatch = null;
    try {
      enableLatch = enableLatchWait();
      enableInternal();
      if (!async) {
        activateInternal(m_trackingCount.get());
      }
    } finally {
      if (!async) {
        enableLatch.countDown();
      }
      m_enabled = true;
    }

    if (async) {
      final CountDownLatch latch = enableLatch;
      m_activator.schedule(
          new Runnable() {

            long count = taskCounter.incrementAndGet();

            public void run() {
              try {
                activateInternal(m_trackingCount.get());
              } finally {
                latch.countDown();
              }
            }

            public String toString() {
              return "Async Activate: " + getComponentMetadata().getName() + " id: " + count;
            }
          });
    }
  }
  /**
   * Implements the <code>ComponentContext.disableComponent(String)</code> method by first finding
   * the component(s) for the <code>name</code> and then starting a thread to actually disable all
   * components found.
   *
   * <p>If no component matching the given name is found the thread is not started and the method
   * does nothing.
   *
   * @param name The name of the component to disable or <code>null</code> to disable all
   *     components.
   */
  public void disableComponent(final String name) {
    final ComponentHolder[] holder = getSelectedComponents(name);
    if (holder == null) {
      return;
    }

    // FELIX-2368; schedule for asynchronous enablement. According to
    //    112.5.1 the enabled state should be changed immediately but
    //    the component(s) should be deactivated asynchronously. Since
    //    we do not really handle the enabled state separately we
    //    schedule disablement and deactivation for asynchronous execution.
    schedule(
        new Runnable() {
          public void run() {
            for (int i = 0; i < holder.length; i++) {
              try {
                log(
                    LogService.LOG_DEBUG,
                    "Disabling Component",
                    holder[i].getComponentMetadata(),
                    null);
                holder[i].disableComponents();
              } catch (Throwable t) {
                log(
                    LogService.LOG_ERROR,
                    "Cannot disable component",
                    holder[i].getComponentMetadata(),
                    t);
              }
            }
          }

          public String toString() {
            return "disableComponent(" + name + ")";
          }
        });
  }