Issue #70: use text/template for push_endpoint

* Going up a minor because a config option changed.
Remove anon struct field names

* scratching @kitcambridge's nit
Initial router refactoring.

Define a `Locator` interface for pluggable discovery services. Extract
etcd peer discovery into an `EtcdLocator` struct.

* Add `Router.{SetLocator, Locator, FormatURL}()`.
* Replace `Router.Unregister()` with `Close()`.
* Expose the etcd key prefix as `EtcdConf.Dir` and the minimum refresh
  interval as `EtcdConf.RefreshInterval`.
* Use a buffered channel as a semaphore instead of manually partitioning
  the returned contacts into buckets.
* Account for non-default HTTPS ports when constructing the etcd key.
Update the sample config.
Simplify `id.{Valid, Decode}()`.
Refactor app initialization.

This allows applications to be initialized programmatically.

* Add `PluginType` constants for the logger, proprietary pinger,
  metrics, storage adapter, router, locator, server, and server
  handler plug-ins.
* Add a `PluginLoaders` type that maps each `PluginType` to an
  initialization function.
* Extract the initialization process into `PluginLoaders#Load()`.
Add `StaticLocator`.

`EtcdConf` => `EtcdLocatorConf`. Simplify `EtcdLocator.ConfigStruct()`.
`Store`: Remove `MaxChannels` from `DbConf`.

`MaxChannels` is now a top-level option, and may be specified for all
storage adapters. Simplify `NoStore.ConfigStruct()`.
Client: Exercise the new `PluginLoaders` API.
Update the sample config.
Replace the `Host` and `Port` options with `Addr`.

Add `{Application, Router}.Addr()`.
Add `Listen{TLS}()` and `TCPKeepAliveListener`.

Unlike the `ListenAndServe()` and `ListenAndServeTLS()` functions from
the `net/http` package, `Listen()` and `ListenTLS()` do not call
`Server.Serve()`, and can listen on random ports. This is useful for
deferred initialization and testing; the server and router can now
listen for incoming connections immediately.
Use `Listen{TLS}()` in `{Serv, Router}.Init()`.

* Move the `Addr` and `Ssl{Key, Cert}File` options to `ServerConfig`.
  If the `Addr` option is omitted, random ports will be chosen for the
  server and router.
* Add `{Serv, Router}.Listener()`.
* `Application.FullHostname()` => `Serv.FullHostname()`.
* Remove `{Application, Router}.Addr()`.
Add `TestServer`.

The client tests can now automatically start a Simple Push server,
instead of relying on a hard-coded `Origin`.
Simplify `make test`.
Add license headers. Clean up godoc comments.
Review feedback.

* Extract `Locator` into a separate file.
* Use `Router.Locator()` and `Serv.FullHostname()` consistently.
* `Router.FormatURL()` => `formatURL()`.
* Clean up the `usingSSL` conditional in `Serv.Init()`.
Simplify `TestClient.notifyAll()`.
Export `Conn.Packets`.
Remove `Conn.UnregisterDecoder()`.

Re-add `Conn.decoderLock`. This allows decoders to be added
and accessed concurrently, matching the behavior of, e.g.,
`http.Transport.RegisterProtocol()`.