def create_plugin(namespace, plugin_type, provider, options = {}, &code) # :yields: type_info, options
    namespace   = namespace.to_sym
    plugin_type = sanitize_id(plugin_type)
    provider    = sanitize_id(provider)
    options     = Util::Data.clone(options)
    plugin      = nil
    result      = nil

    unless plugin_type_defined?(namespace, plugin_type)
      return plugin
    end

    if type_info = Util::Data.clone(loaded_plugin(namespace, plugin_type, provider))
      ids             = array(type_info[:class].register_ids).flatten
      instance_config = Config.new(options, {}, true, false)
      ensure_new      = instance_config.delete(:new, false)

      instance_options = Util::Data.subset(instance_config.export, ids, true)
      instance_name    = "#{provider}_" + Nucleon.sha1(instance_options)
      plugin           = get([ :active_info, namespace, plugin_type, instance_name ])

      if ensure_new || ! ( instance_name && plugin )
        type_info[:instance_name] = instance_name

        result  = code.call(type_info, options) if code
        options = result if result.is_a?(Hash)

        options[:meta] = Config.new(type_info, {}, true, false).import(hash(options[:meta]))

        options.delete(:new)

        plugin = type_info[:class].new(namespace, plugin_type, provider, options)
        set([ :active_info, namespace, plugin_type, instance_name ], plugin)

        @instance_map.append([ namespace, plugin_type, plugin.plugin_name.to_sym ], instance_name.to_sym)
      end
    end
    plugin
  end
def create_plugin(namespace, plugin_type, provider, options = {}, &code) # :yields: type_info, options
    namespace   = namespace.to_sym
    plugin_type = sanitize_id(plugin_type)
    provider    = sanitize_id(provider)
    options     = Util::Data.clone(options)
    plugin      = nil
    result      = nil

    unless plugin_type_defined?(namespace, plugin_type)
      return plugin
    end

    if type_info = Util::Data.clone(loaded_plugin(namespace, plugin_type, provider))
      ids             = array(type_info[:class].register_ids).flatten
      instance_config = Config.new(options, {}, true, false)
      ensure_new      = instance_config.delete(:new, false)

      instance_options = Util::Data.subset(instance_config.export, ids, true)
      instance_name    = "#{provider}_" + Nucleon.sha1(instance_options)
      plugin           = get([ :active_info, namespace, plugin_type, instance_name ])

      if ensure_new || ! ( instance_name && plugin )
        type_info[:instance_name] = instance_name

        result  = code.call(type_info, options) if code
        options = result if result.is_a?(Hash)

        options[:meta] = Config.new(type_info, {}, true, false).import(hash(options[:meta]))

        options.delete(:new)

        plugin = type_info[:class].new(namespace, plugin_type, provider, options)
        set([ :active_info, namespace, plugin_type, instance_name ], plugin)

        @instance_map.append([ namespace, plugin_type, plugin.plugin_name.to_sym ], instance_name.to_sym)
      end
    end
    plugin
  end
*****************************************************************************
 Active plugin accessor / modifiers
 Create a new plugin instance of a specified provider

 * *Parameters*
   - [String, Symbol] *namespace*  Namespace that contains plugin types
   - [String, Symbol] *plugin_type*  Plugin type name of provider
   - [String, Symbol] *provider*  Plugin provider to return load information
   - [Hash] *options*  Create options (plugin initialization configurations)

 * *Returns*
   - [nil, Nucleon::Plugin::Base]  Returns plugin instance (inherited from Nucleon::Plugin::Base)

 * *Errors*

 * *Yields*
   - [nil, Hash<Symbol|ANY>]  *type_info*  Provider load information if it has been loaded
   - [Hash] *options*  Create options (plugin initialization configurations)

 See:
 - Nucleon::Plugin::Base
 - Nucleon::Config#get
 - Nucleon::Config#set

 See also:
 - #sanitize_id
 - #plugin_type_defined?
 - #loaded_plugin
 - Nucleon::Config
 - Nucleon::Config::array
 - Nucleon::Util::Data::subset
 - Nucleon::Facade#sha1