Make Configuration class stricter

- Configuration is no longer an OpenStruct. Instead, it has a whitelist
  of attributes. Trying to set non-existent attributes throws a
  NoMethodError.
- Configuration class defines the defaults instead of the Client class.
- Configuration class handles merging instead of the Client class.
- Dry up configuration logic in Client class.
- Define an Attributes module that provides a small DSL for defining
attributes, their defaults, initialization, and an #attributes method
- Configuration instances are immutable