Migrating from 1.0.1 or prior
=============================

(This is primarily for internal use, but if anybody external used this before we rewrote it, well,
here you go)

Plugins
-------

=== Handlers and magic functions are gone

Handlers are no longer exported as a separate entity - just export functions now.  You are strongly
encouraged to export functions in a namespaced way, but only plugin-manager's internal hooks
actually require this.  Other apps may or may not use namespacing.

Built-in methods like onEnable and onDisable are now expected to be exported as methods under a
"plugin" object.  This should make them feel a lot less like special-case code.

=== Conversion example:

Old:
```javascript
  handlers = {}
  handlers.userLogin = function() {}
  
  module.exports = exports;
  exports.handlers = handlers;
  exports.onEnable = function() {}
```

New:

```javascript
  // Export an empty object to start
  var hook = {};
  module.exports = exports = hook;
  
  // Set up objects for namespaces
  hook.plugin = {};
  hook.user = {};
  
  hook.plugin.enable = function() { }
  hook.user.login = function() { }
```

Application exposing hooks
--------------------------

=== Validations

Validating hook names is still allowed, but doesn't result in a failure to enable a module.  A
plugin module's exports are crawled deeply and all functions are aliased in order to allow for
useful namespaces.  Since this could result in test-only functions or functions that are exposed
for other uses (command-line someday?), invalid functions are sent to the caller, but they don't
prevent the module from being enabled.

=== `invoke(moduleName, hookName, args)` and `invokeAll(hookName, args)`

There are now two ways to call plugins.  `invokeAll` is much like the old `emit` method, calling
all handlers for the given hook.  `invoke` takes a module name and calls the hook only for the given
module.

If you had been wrapping plugin hook methods with a check on the plugin name, consider refactoring
to use `invoke` instead.

=== Hook names

If hooks are named with a period in them, namespacing is assumed (a period isn't typically used in
a function identifier, after all).  For instance, `invokeAll("foo.bar.baz", data)` will be the same as
calling `plugin.foo.bar.baz(data)` for each plugin enabled.
