private void processCapabilityProviders(List<ManifestElement> manifestElementList) {

    manifestElementList
        .stream()
        .filter(
            manifestElement ->
                CapabilityProvider.class.getName().equals(getObjectClassName(manifestElement)))
        .map(
            manifestElement -> {
              // Processing CapabilityProvider OSGi service
              String providedCapabilityName =
                  getManifestElementAttribute(CAPABILITY_NAME, manifestElement, false);

              if (logger.isDebugEnabled()) {
                logger.debug(
                    "Creating a CapabilityProviderCapability from manifest element in "
                        + "bundle({}:{}), with CapabilityName - {}. ",
                    manifestElement.getBundle().getSymbolicName(),
                    manifestElement.getBundle().getVersion(),
                    providedCapabilityName);
              }

              return new CapabilityProviderCapability(
                  getObjectClassName(manifestElement),
                  Capability.CapabilityType.OSGi_SERVICE,
                  providedCapabilityName,
                  manifestElement.getBundle());
            })
        .forEach(capability -> startupComponentManager.addExpectedCapabilityProvider(capability));
  }
  /**
   * Process Provide-Capability headers and populate a counter which keep all the expected service
   * counts. Register timers to track the service availability as well as pending service
   * registrations.
   *
   * <p>If there are no RequireCapabilityListener instances then this method returns.
   *
   * @param bundleContext OSGi bundle context of the Carbon.core bundle
   * @throws Exception if the service component activation fails
   */
  @Activate
  public void start(BundleContext bundleContext) throws Exception {
    try {

      logger.debug("Initialize - Startup Order Resolver.");

      // 1) Process OSGi manifest headers to calculate the expected list required capabilities.
      processManifestHeaders(Arrays.asList(bundleContext.getBundles()), supportedManifestHeaders);

      // 2) Check for any startup components with pending required capabilities.
      if (startupComponentManager.getPendingComponents().size() == 0) {
        // There are no registered RequiredCapabilityListener
        // Clear all the populated maps.
        startupComponentManager = null;
        osgiServiceTracker = null;
        return;
      }

      // 3) Register capability trackers to get notified when required capabilities are available.
      startCapabilityTrackers();

      // 4) Schedule a time task to check for startup components with zero pending required
      // capabilities.
      scheduleCapabilityListenerTimer();

      // 5) Start a timer to track pending capabilities, pending CapabilityProvider services,
      // pending RequiredCapabilityLister services.
      schedulePendingCapabilityTimerTask();

    } catch (Throwable e) {
      logger.error("Error occurred in Startup Order Resolver.", e);
    }
  }
 /**
  * Process all the Startup-Component manifest header elements. Creates {@code StartupComponent}
  * instances for each and every ManifestElement.
  *
  * @param manifestElementList a list of {@code ManifestElement} whose header name is
  *     Startup-Component.
  */
 private void processStartupComponents(List<ManifestElement> manifestElementList) {
   // Create StartupComponents from the manifest elements.
   List<StartupComponent> startupComponentList =
       manifestElementList
           .stream()
           .map(StartupOrderResolverUtils::getStartupComponentBean)
           .collect(Collectors.toList());
   startupComponentManager.addComponents(startupComponentList);
 }
  private void notifySatisfiableComponents() {
    startupComponentManager
        .getSatisfiableComponents()
        .forEach(
            startupComponent -> {
              String componentName = startupComponent.getName();

              synchronized (componentName.intern()) {
                startupComponentManager.removeSatisfiedComponent(startupComponent);
                RequiredCapabilityListener capabilityListener = startupComponent.getListener();

                if (logger.isDebugEnabled()) {
                  logger.debug(
                      "Notifying RequiredCapabilityListener of component {} from bundle({}:{}) "
                          + "since all the required capabilities are available",
                      componentName,
                      startupComponent.getBundle().getSymbolicName(),
                      startupComponent.getBundle().getVersion());
                }

                capabilityListener.onAllRequiredCapabilitiesAvailable();
              }
            });
  }
  /**
   * Process all the Provide-Capability Manifest header elements to get a list of required
   * Capabilities.
   *
   * <p>At the moment this methods process manifest elements with the namespace osgi.service.
   *
   * @param manifestElementList partitioned manifest elements by the header name.
   */
  private void processOSGiServiceCapabilities(List<ManifestElement> manifestElementList) {
    // Handle CapabilityProvider OSGi services
    processCapabilityProviders(manifestElementList);

    // Handle other OSGi service capabilities
    manifestElementList
        .stream()
        .filter(
            manifestElement ->
                !CapabilityProvider.class.getName().equals(getObjectClassName(manifestElement))
                    && !RequiredCapabilityListener.class
                        .getName()
                        .equals(getObjectClassName(manifestElement)))
        // Creating a Capability from the manifestElement
        .flatMap(
            manifestElement -> {
              String capabilityName = getObjectClassName(manifestElement);

              String serviceCountStr =
                  getManifestElementAttribute(SERVICE_COUNT, manifestElement, false);

              int serviceCount = 1;
              if (serviceCountStr != null) {
                try {
                  serviceCount = Integer.parseInt(serviceCountStr.trim());
                } catch (NumberFormatException e) {
                  throw new StartOrderResolverException(
                      "Invalid value for serviceCount manifest attribute "
                          + "in bundle("
                          + manifestElement.getBundle().getSymbolicName()
                          + ":"
                          + manifestElement.getBundle().getVersion()
                          + ")",
                      e);
                }
              }

              // Create specifed  number of OSGi service components and adding them to a list.
              List<OSGiServiceCapability> osgiServiceCapabilityList = new ArrayList<>(serviceCount);
              IntStream.range(0, serviceCount)
                  .forEach(
                      count -> {
                        OSGiServiceCapability osgiServiceCapability =
                            new OSGiServiceCapability(
                                capabilityName,
                                Capability.CapabilityType.OSGi_SERVICE,
                                manifestElement.getBundle());

                        // Check whether a dependent-component-key or dependent-component-name
                        // property is specified.
                        String dependentComponentName =
                            getManifestElementAttribute(
                                DEPENDENT_COMPONENT_NAME, manifestElement, false);

                        if (dependentComponentName != null && !dependentComponentName.equals("")) {
                          osgiServiceCapability.setDependentComponentName(
                              dependentComponentName.trim());
                        }
                        osgiServiceCapabilityList.add(osgiServiceCapability);
                      });

              return osgiServiceCapabilityList.stream();
            })
        .forEach(
            capability -> {
              if (capability.getDependentComponentName() != null) {
                startupComponentManager.addRequiredOSGiServiceCapabilityToComponent(
                    capability.getDependentComponentName(), capability.getName());
              }
              startupComponentManager.addExpectedRequiredCapability(capability);
            });
  }