Handles registration of a plugin hook in the global registries.

        `hook_type`
            Type of hook to register ('event', 'command', or 'option')
        `key`
            Unique key associated with `hook_type` and `plugin`.
            Value depends on type::
                'command' - Name of the command

                'event'   - Name of the event to associate with plugin:
                                ('task_start', 'task_run', 'task_end')

                'option'  - Option name for task config file. Name should be
                            prefixed with block name if it has one:
                            (e.g. apps_startpath)
        `plugin_cls`
            ``Plugin`` class.
        `properties`
            Dictionary with properties related to provided plugin and key.

        Note, upon registration of any hooks, the plugin will also be
        registered in the master plugin registry.

def register(hook_type, key, plugin_cls, properties=None):
    """ Handles registration of a plugin hook in the global registries.

        `hook_type`
            Type of hook to register ('event', 'command', or 'option')
        `key`
            Unique key associated with `hook_type` and `plugin`.
            Value depends on type::
                'command' - Name of the command

                'event'   - Name of the event to associate with plugin:
                                ('task_start', 'task_run', 'task_end')

                'option'  - Option name for task config file. Name should be
                            prefixed with block name if it has one:
                            (e.g. apps_startpath)
        `plugin_cls`
            ``Plugin`` class.
        `properties`
            Dictionary with properties related to provided plugin and key.

        Note, upon registration of any hooks, the plugin will also be
        registered in the master plugin registry.
        """

    def fetch_plugin():
        """ This function is used as a lazy evaluation of fetching the
            specified plugin. This is required, because at the time of
            registration of hooks (metaclass creation), the plugin class won't
            exist yet in the class namespace, which is required for the
            `Registry.get()` method. One benefit of this implementation is that
            we can reference the same object instance in each of the hook
            registries instead of making a new instance of the plugin for every
            registry that links to the same plugin.
            """
        return _registered.get(plugin_cls.name)[0]  # extended, strip type info

    # type information for plugin in main registry
    type_info = {}

    # register a command for plugin
    if hook_type == 'command':
        _command_hooks.register(key, fetch_plugin)
        type_info['command'] = True

    # register event chain for plugin
    elif hook_type == 'event':
        if not key in _event_hooks:
            _event_hooks[key] = []
        _event_hooks[key].append((plugin_cls.name, fetch_plugin))
        type_info['event'] = True

    # register an option for plugin
    elif hook_type == 'option':
        _option_hooks.register(key, fetch_plugin, properties or {})
        type_info['option'] = True

    else:
        return

    # register this class in main registry
    _registered.register(plugin_cls.name, plugin_cls, type_info)