/**
   * @param ctx Kernal context.
   * @param cfg Ignite configuration.
   * @param providers Plugin providers.
   */
  @SuppressWarnings("TypeMayBeWeakened")
  public IgnitePluginProcessor(
      GridKernalContext ctx, IgniteConfiguration cfg, List<PluginProvider> providers) {
    super(ctx);

    ExtensionRegistryImpl registry = new ExtensionRegistryImpl();

    for (PluginProvider provider : providers) {
      GridPluginContext pluginCtx = new GridPluginContext(ctx, cfg);

      if (F.isEmpty(provider.name())) throw new IgniteException("Plugin name can not be empty.");

      if (plugins.containsKey(provider.name()))
        throw new IgniteException("Duplicated plugin name: " + provider.name());

      plugins.put(provider.name(), provider);

      pluginCtxMap.put(provider, pluginCtx);

      provider.initExtensions(pluginCtx, registry);

      if (provider.plugin() == null) throw new IgniteException("Plugin is null.");
    }

    extensions = registry.createExtensionMap();
  }
  /** Print plugins information. */
  private void ackPluginsInfo() {
    U.quietAndInfo(log, "Configured plugins:");

    if (plugins.isEmpty()) {
      U.quietAndInfo(log, "  ^-- None");
      U.quietAndInfo(log, "");
    } else {
      for (PluginProvider plugin : plugins.values()) {
        U.quietAndInfo(log, "  ^-- " + plugin.name() + " " + plugin.version());
        U.quietAndInfo(log, "  ^-- " + plugin.copyright());
        U.quietAndInfo(log, "");
      }
    }
  }