/**
   * Wait until this Framework has completely stopped.
   *
   * <p>The stop and update methods on a Framework performs an asynchronous stop of the Framework.
   * This method can be used to wait until the asynchronous stop of this Framework has completed.
   * This method will only wait if called when this Framework is in the Bundle.STARTING,
   * Bundle.ACTIVE, or Bundle.STOPPING states. Otherwise it will return immediately.
   *
   * <p>A Framework Event is returned to indicate why this Framework has stopped.
   */
  FrameworkEvent waitForStop(long timeout) throws InterruptedException {
    SystemBundleState systemBundle = getSystemBundle();
    Bundle eventSource = systemBundle != null ? systemBundle : cachedSystemBundle;

    FrameworkEvent frameworkEvent = null;
    shutdownContainer.awaitTermination(timeout, TimeUnit.MILLISECONDS);
    if (eventSource != null) {
      int eventType =
          shutdownContainer.isShutdownComplete() ? stoppedEvent : FrameworkEvent.WAIT_TIMEDOUT;
      frameworkEvent = new FrameworkEvent(eventType, eventSource, null);
    }
    return frameworkEvent;
  }
  void shutdownManager(boolean stopForUpdate) {

    // If the Framework is not STARTING and not ACTIVE there is nothing to do
    int state = getManagerState();
    if (state != Bundle.STARTING && state != Bundle.ACTIVE) return;

    LOGGER.debugf("Stop framework");

    stoppedEvent = stopForUpdate ? FrameworkEvent.STOPPED_UPDATE : FrameworkEvent.STOPPED;
    getSystemBundle().changeState(Bundle.STOPPING);
    setManagerState(Bundle.STOPPING);

    // Move to start level 0 in the current thread
    FrameworkCoreServices coreServices = getFrameworkState().getCoreServices();
    StartLevelPlugin startLevel = coreServices.getStartLevelPlugin();
    if (startLevel != null) {
      startLevel.decreaseStartLevel(0);
    } else {
      // No Start Level Service available, stop all bundles individually...
      // All installed bundles must be stopped without changing each bundle's persistent autostart
      // setting
      for (Bundle bundle : getBundles()) {
        if (bundle.getBundleId() != 0) {
          try {
            bundle.stop(Bundle.STOP_TRANSIENT);
          } catch (Exception ex) {
            // Any exceptions that occur during bundle stopping must be wrapped in a BundleException
            // and then
            // published as a framework event of type FrameworkEvent.ERROR
            fireFrameworkError(bundle, "stopping bundle", ex);
          }
        }
      }
    }

    cachedSystemBundle = getSystemBundle();
    shutdownContainer.shutdown();
    setManagerState(Bundle.RESOLVED);
  }
 boolean hasStopped() {
   return shutdownContainer.isShutdownInitiated() || managerStopped.get();
 }