Implement pluggable storage adapters

This pull request refactors the existing memcached storage implementation, and adds a generic `Storage` interface for custom backing stores. A `NoStore` adapter is also included for Loop.

* The previous memcached routines have been extracted into an `EmceeStore` driver that supports dynamically-sized memcached pools.
* `{Gen, Resolve}PK` have been moved to `Store.{IDsToKey, KeyToIDs}`, respectively. This allows storage adapters to define their own key marshaling and unmarshaling routines.
* `storage.getElastiCacheEndpointsTimeout()` uses a buffered channel to avoid phantom Goroutines if the request times out.
* `{Handler, Application, PropPing, Serv}.storage` => `*.store`.
* `storage` is now loaded as an extensible section. The configuration loader will panic if the loaded logger and storage plug-ins do not satisfy their respective interfaces.
* Storage adapters are now closed on exit.

Closes #31. Awaiting r+ from @jrconlin, @bbangert.
Not that it matters for this review, but I need to really re-evaluate the role of "unregister" or "deleted". 

Originally, these were to eventually report back to the prospective publisher that those channel IDs are no longer valid. If that's the case, then an ID needs to last a fairly long time (72hours +?) because there's no way of knowing when a server will send another notification. If a client gets a large number of "trash" channels, it's free to reregister and get a new UAID. Valid apps would get a new channelID they'd send out. 

Likewise, the server may want to note UAIDs that have not been picked up by a client as "dead" and start 404ing them. 

While I'd love to have zero state, we may want to keep a reasonably tiny amount for a short period.