diff --git a/README.md b/README.md
index 1cabb3549ae18830f9630c733006bd13c2e9aea7..c35c2f39275439a757cea636f33fabf5148d6e9f 100644
--- a/README.md
+++ b/README.md
@@ -266,29 +266,29 @@ Geocoding Services
 By default Geocoder uses Google's geocoding API to fetch coordinates and street addresses (FreeGeoIP is used for IP address info). However there are several other APIs supported, as well as a variety of settings. Please see the listing and comparison below for details on specific geocoding services (not all settings are supported by all services). Some common configuration options are:
 
     # config/initializers/geocoder.rb
-    Geocoder.configure do |config|
+    Geocoder.configure(
 
       # geocoding service (see below for supported options):
-      config.lookup = :yandex
+      :lookup => :yandex,
 
       # to use an API key:
-      config.api_key = "..."
+      :api_key => "...",
 
       # geocoding service request timeout, in seconds (default 3):
-      config.timeout = 5
+      :timeout => 5,
 
       # set default units to kilometers:
-      config.units = :km
+      :units => :km,
 
       # caching (see below for details):
-      config.cache = Redis.new
-      config.cache_prefix = "..."
+      :cache => Redis.new,
+      :cache_prefix => "..."
 
     end
 
 Please see lib/geocoder/configuration.rb for a complete list of configuration options. Additionally, some lookups have their own configuration options which are listed in the comparison chart below, and as of version 1.2.0 you can pass arbitrary parameters to any geocoding service. For example, to use Nominatim's `countrycodes` parameter:
 
-    Geocoder::Configuration.lookup = :nominatim
+    Geocoder.configure(:lookup => :nominatim)
     Geocoder.search("Paris", :params => {:countrycodes => "gb,de,fr,es,us"})
 
 
@@ -308,13 +308,13 @@ The following is a comparison of the supported geocoding APIs. The "Limitations"
 * **Documentation**: http://code.google.com/apis/maps/documentation/geocoding/#JSON
 * **Terms of Service**: http://code.google.com/apis/maps/terms.html#section_10_12
 * **Limitations**: "You must not use or display the Content without a corresponding Google map, unless you are explicitly permitted to do so in the Maps APIs Documentation, or through written permission from Google." "You must not pre-fetch, cache, or store any Content, except that you may store: (i) limited amounts of Content for the purpose of improving the performance of your Maps API Implementation..."
-* **Notes**: To use Google Premier set `Geocoder::Configuration.lookup = :google_premier` and `Geocoder::Configuration.api_key = [key, client, channel]`.
+* **Notes**: To use Google Premier set `Geocoder.configure(:lookup => :google_premier, :api_key => [key, client, channel])`.
 
 #### Yahoo BOSS (`:yahoo`)
 
 Yahoo BOSS is **not a free service**. As of November 17, 2012 Yahoo no longer offers a free geocoding API.
 
-* **API key**: requires OAuth consumer key and secret (set `Geocoder::Configuration.api_key = [key, secret]`)
+* **API key**: requires OAuth consumer key and secret (set `Geocoder.configure(:api_key => [key, secret])`)
 * **Key signup**: http://developer.yahoo.com/boss/geo/
 * **Quota**: unlimited, but subject to usage fees
 * **Region**: world
@@ -374,7 +374,7 @@ Yahoo BOSS is **not a free service**. As of November 17, 2012 Yahoo no longer of
 * **API key**: required for the licensed API, do not use for open tier
 * **Quota**: ?
 * **HTTP Headers**: in order to use the licensed API you can configure the http_headers to include a referer as so:
-    `Geocoder::Configuration.http_headers = { "Referer" => "http://foo.com" }`
+    `Geocoder.configure(:http_headers => { "Referer" => "http://foo.com" })`
   You can also allow a blank referer from the API management console via mapquest but it is potentially a security risk that someone else could use your API key from another domain.
 * **Region**: world
 * **SSL support**: no
@@ -400,7 +400,7 @@ Caching
 
 It's a good idea, when relying on any external service, to cache retrieved data. When implemented correctly it improves your app's response time and stability. It's easy to cache geocoding results with Geocoder, just configure a cache store:
 
-    Geocoder::Configuration.cache = Redis.new
+    Geocoder.configure(:cache => Redis.new)
 
 This example uses Redis, but the cache store can be any object that supports these methods:
 
@@ -413,7 +413,7 @@ Even a plain Ruby hash will work, though it's not a great choice (cleared out wh
 
 You can also set a custom prefix to be used for cache keys:
 
-    Geocoder::Configuration.cache_prefix = "..."
+    Geocoder.configure(:cache_prefix => "...")
 
 By default the prefix is `geocoder:`
 
@@ -477,7 +477,7 @@ Testing Apps that Use Geocoder
 
 When writing tests for an app that uses Geocoder it may be useful to avoid network calls and have Geocoder return consistent, configurable results. To do this, configure and use the `:test` lookup. For example:
 
-    Geocoder::Configuration.lookup = :test
+    Geocoder.configure(:lookup => :test)
 
     Geocoder::Lookup::Test.add_stub(
       "New York, NY", [
@@ -583,11 +583,11 @@ Error Handling
 
 By default Geocoder will rescue any exceptions raised by calls to the geocoding service and return an empty array (using warn() to inform you of the error). You can override this and implement custom error handling for certain exceptions by using the `:always_raise` option:
 
-    Geocoder::Configuration.always_raise = [SocketError, TimeoutError]
+    Geocoder.configure(:always_raise => [SocketError, TimeoutError])
 
 You can also do this to raise all exceptions:
 
-    Geocoder::Configuration.always_raise = :all
+    Geocoder.configure(:always_raise => :all)
 
 See `lib/geocoder/exceptions.rb` for a list of raise-able exceptions.
 
diff --git a/examples/autoexpire_cache.rb b/examples/autoexpire_cache.rb
index cace891197f6d237080b3734956cac5a27cd13ee..ced862b3d875a81bf701d4dc5356e3587382371a 100644
--- a/examples/autoexpire_cache.rb
+++ b/examples/autoexpire_cache.rb
@@ -25,6 +25,4 @@ class AutoexpireCache
   end
 end
 
-Geocoder.configure do |config|
-  config.cache = AutoexpireCache.new(Redis.new)
-end
+Geocoder.configure(:cache => AutoexpireCache.new(Redis.new))
diff --git a/lib/generators/geocoder/config/templates/initializer.rb b/lib/generators/geocoder/config/templates/initializer.rb
index 078cea8b47698710866279e9f43274b7ff4e40be..498e15abc5fbacb0849e2511117f8c7aaa342c3d 100644
--- a/lib/generators/geocoder/config/templates/initializer.rb
+++ b/lib/generators/geocoder/config/templates/initializer.rb
@@ -1,25 +1,21 @@
-Geocoder.configure do |config|
-  ## Configurable parameters: if you wish to change some configurable
-  ## behaviour in Geocoder, feel free to uncomment the following lines
-  ## and provide custom parameters.
+Geocoder.configure(
+  # geocoding options
+  # :timeout      => 3,           # geocoding service timeout (secs)
+  # :lookup       => :google,     # name of geocoding service (symbol)
+  # :language     => :en,         # ISO-639 language code
+  # :use_https    => false,       # use HTTPS for lookup requests? (if supported)
+  # :http_proxy   => nil,         # HTTP proxy server (user:pass@host:port)
+  # :https_proxy  => nil,         # HTTPS proxy server (user:pass@host:port)
+  # :api_key      => nil,         # API key for geocoding service
+  # :cache        => nil,         # cache object (must respond to #[], #[]=, and #keys)
+  # :cache_prefix => "geocoder:", # prefix (string) to use for all cache keys
 
-  # config.timeout      = 3           # geocoding service timeout (secs)
-  # config.lookup       = :google     # name of geocoding service (symbol)
-  # config.language     = :en         # ISO-639 language code
-  # config.use_https    = false       # use HTTPS for lookup requests? (if supported)
-  # config.http_proxy   = nil         # HTTP proxy server (user:pass@host:port)
-  # config.https_proxy  = nil         # HTTPS proxy server (user:pass@host:port)
-  # config.api_key      = nil         # API key for geocoding service
-  # config.cache        = nil         # cache object (must respond to #[], #[]=, and #keys)
-  # config.cache_prefix = "geocoder:" # prefix (string) to use for all cache keys
+  # exceptions that should not be rescued by default
+  # (if you want to implement custom error handling);
+  # supports SocketError and TimeoutError
+  # :always_raise => [],
 
-  ## exceptions that should not be rescued by default
-  ## (if you want to implement custom error handling);
-  ## supports SocketError and TimeoutError
-  # config.always_raise = []
-
-  ## Calculation options
-  # config.units     = :mi        # :km for kilometers or :mi for miles
-  # config.distances = :linear    # :spherical or :linear
+  # calculation options
+  # :units     => :mi,       # :km for kilometers or :mi for miles
+  # :distances => :linear    # :spherical or :linear
 end
-
diff --git a/lib/geocoder.rb b/lib/geocoder.rb
index 4019e84523f5f00a5ab6e31aebd233804ba5743d..b3bae2bff6f1899aff6b258e4d6b70612b959555 100644
--- a/lib/geocoder.rb
+++ b/lib/geocoder.rb
@@ -43,10 +43,8 @@ module Geocoder
   # The working Cache object, or +nil+ if none configured.
   #
   def cache
-    if @cache.nil? and store = Configuration.cache
-      @cache = Cache.new(store, Configuration.cache_prefix)
-    end
-    @cache
+    warn "WARNING: Calling Geocoder.cache is DEPRECATED. The #cache method now belongs to the Geocoder::Lookup object."
+    Geocoder::Lookup.get(Geocoder.config.lookup).send(:configuration).cache
   end
 end
 
diff --git a/lib/geocoder/calculations.rb b/lib/geocoder/calculations.rb
index 9756d035f60ce765074ad9319f38fb204c957fb9..70c8fcb350fd90732aee1c2bea9b9ece85692c62 100644
--- a/lib/geocoder/calculations.rb
+++ b/lib/geocoder/calculations.rb
@@ -40,7 +40,7 @@ module Geocoder
     # Distance spanned by one degree of latitude in the given units.
     #
     def latitude_degree_distance(units = nil)
-      units ||= Geocoder::Configuration.units
+      units ||= Geocoder.config.units
       2 * Math::PI * earth_radius(units) / 360
     end
 
@@ -49,7 +49,7 @@ module Geocoder
     # This ranges from around 69 miles at the equator to zero at the poles.
     #
     def longitude_degree_distance(latitude, units = nil)
-      units ||= Geocoder::Configuration.units
+      units ||= Geocoder.config.units
       latitude_degree_distance(units) * Math.cos(to_radians(latitude))
     end
 
@@ -67,12 +67,12 @@ module Geocoder
     # The options hash supports:
     #
     # * <tt>:units</tt> - <tt>:mi</tt> or <tt>:km</tt>
-    #   See Geocoder::Configuration to know how configure default units.
+    #   Use Geocoder.configure(:units => ...) to configure default units.
     #
     def distance_between(point1, point2, options = {})
 
       # set default options
-      options[:units] ||= Geocoder::Configuration.units
+      options[:units] ||= Geocoder.config.units
 
       # convert to coordinate arrays
       point1 = extract_coordinates(point1)
@@ -103,14 +103,14 @@ module Geocoder
     #   the spherical method is "correct" in that it returns the shortest path
     #   (one along a great circle) but the linear method is less confusing
     #   (returns due east or west when given two points with the same latitude).
-    #   See Geocoder::Configuration to know how configure default method.
+    #   Use Geocoder.configure(:distances => ...) to configure calculation method.
     #
     # Based on: http://www.movable-type.co.uk/scripts/latlong.html
     #
     def bearing_between(point1, point2, options = {})
 
       # set default options
-      options[:method] ||= Geocoder::Configuration.distances
+      options[:method] ||= Geocoder.config.distances
       options[:method] = :linear unless options[:method] == :spherical
 
       # convert to coordinate arrays
@@ -197,12 +197,12 @@ module Geocoder
     # ways of specifying the point. Also accepts an options hash:
     #
     # * <tt>:units</tt> - <tt>:mi</tt> or <tt>:km</tt>.
-    #   See Geocoder::Configuration to know how configure default units.
+    #   Use Geocoder.configure(:units => ...) to configure default units.
     #
     def bounding_box(point, radius, options = {})
       lat,lon = extract_coordinates(point)
       radius  = radius.to_f
-      units   = options[:units] || Geocoder::Configuration.units
+      units   = options[:units] || Geocoder.config.units
       [
         lat - (radius / latitude_degree_distance(units)),
         lon - (radius / longitude_degree_distance(lat, units)),
@@ -240,12 +240,12 @@ module Geocoder
     end
 
     def distance_to_radians(distance, units = nil)
-      units ||= Geocoder::Configuration.units
+      units ||= Geocoder.config.units
       distance.to_f / earth_radius(units)
     end
 
     def radians_to_distance(radians, units = nil)
-      units ||= Geocoder::Configuration.units
+      units ||= Geocoder.config.units
       radians * earth_radius(units)
     end
 
@@ -265,10 +265,10 @@ module Geocoder
 
     ##
     # Radius of the Earth in the given units (:mi or :km).
-    # See Geocoder::Configuration to know how configure default units.
+    # Use Geocoder.configure(:units => ...) to configure default units.
     #
     def earth_radius(units = nil)
-      units ||= Geocoder::Configuration.units
+      units ||= Geocoder.config.units
       units == :km ? EARTH_RADIUS : to_miles(EARTH_RADIUS)
     end
 
diff --git a/lib/geocoder/cli.rb b/lib/geocoder/cli.rb
index c2a9e5220bab97dc48e45f18eb027509f46bcca0..3aed925346cb1ef636204804b4ce8875c80628fd 100644
--- a/lib/geocoder/cli.rb
+++ b/lib/geocoder/cli.rb
@@ -16,31 +16,31 @@ module Geocoder
           "Key for geocoding API (optional for most). For Google Premier use 'key client channel' separated by spaces") do |key|
           premier_key = key.split(' ')
           if premier_key.length == 3
-            Geocoder::Configuration.api_key = premier_key
+            Geocoder.configure(:api_key => premier_key)
           else
-            Geocoder::Configuration.api_key = key
+            Geocoder.configure(:api_key => key)
           end
         end
 
         opts.on("-l <language>", "--language <language>",
           "Language of output (see API docs for valid choices)") do |language|
-          Geocoder::Configuration.language = language
+          Geocoder.configure(:language => language)
         end
 
         opts.on("-p <proxy>", "--proxy <proxy>",
           "HTTP proxy server to use (user:pass@host:port)") do |proxy|
-          Geocoder::Configuration.http_proxy = proxy
+          Geocoder.configure(:http_proxy => proxy)
         end
 
         opts.on("-s <service>", Geocoder::Lookup.all_services_except_test, "--service <service>",
           "Geocoding service: #{Geocoder::Lookup.all_services_except_test * ', '}") do |service|
-          Geocoder::Configuration.lookup = service.to_sym
-          Geocoder::Configuration.ip_lookup = service.to_sym
+          Geocoder.configure(:lookup => service.to_sym)
+          Geocoder.configure(:ip_lookup => service.to_sym)
         end
 
         opts.on("-t <seconds>", "--timeout <seconds>",
           "Maximum number of seconds to wait for API response") do |timeout|
-          Geocoder::Configuration.timeout = timeout.to_i
+          Geocoder.configure(:timeout => timeout.to_i)
         end
 
         opts.on("-j", "--json", "Print API's raw JSON response") do
diff --git a/lib/geocoder/configuration.rb b/lib/geocoder/configuration.rb
index dd426e0b1b7ad1aa1e74fe2b59a51fb4590e89b6..71811e811a7aef67fb1d184b97a99c0704df09bc 100644
--- a/lib/geocoder/configuration.rb
+++ b/lib/geocoder/configuration.rb
@@ -1,38 +1,52 @@
 require 'singleton'
+require 'geocoder/configuration_hash'
 
 module Geocoder
 
   ##
   # Provides convenient access to the Configuration singleton.
   #
-  def self.configure(&block)
+  def self.configure(options = nil, &block)
     if block_given?
+      warn "WARNING: Passing a block to Geocoder.configure is DEPRECATED. Please pass a hash instead (eg: Geocoder.configure(:units => ..., :api_key => ...))."
       block.call(Configuration.instance)
+    elsif !options.nil?
+      Configuration.instance.configure(options)
     else
+      warn "WARNING: Use of Geocoder.configure to read or write single config options is DEPRECATED. To write to the config please pass a hash (eg: Geocoder.configure(:units => ...)). To read config options please use the Geocoder.config object (eg: Geocoder.config.units)."
       Configuration.instance
     end
   end
 
   ##
-  # This class handles geocoder Geocoder configuration
-  # (geocoding service provider, caching, units of measurement, etc).
-  # Configuration can be done in two ways:
+  # Read-only access to the singleton's config data.
   #
-  # 1) Using Geocoder.configure and passing a block
-  #    (useful for configuring multiple things at once):
-  #
-  #   Geocoder.configure do |config|
-  #     config.timeout      = 5
-  #     config.lookup       = :yandex
-  #     config.api_key      = "2a9fsa983jaslfj982fjasd"
-  #     config.units        = :km
-  #   end
-  #
-  # 2) Using the Geocoder::Configuration singleton directly:
+  def self.config
+    Configuration.instance.data
+  end
+
+  ##
+  # Read-only access to lookup-specific config data.
   #
-  #   Geocoder::Configuration.language = 'pt-BR'
+  def self.config_for_lookup(lookup_name)
+    data = config.clone
+    data.reject!{ |key,value| !Configuration::OPTIONS.include?(key) }
+    if config.has_key?(lookup_name)
+      data.merge!(config[lookup_name])
+    end
+    data
+  end
+
+  ##
+  # Configuration options should be set by passing a hash to
+  # the configure method:
   #
-  # Default values are defined in Configuration#set_defaults.
+  #   Geocoder.configure(
+  #     :timeout  => 5,
+  #     :lookup   => :yandex,
+  #     :api_key  => "2a9fsa983jaslfj982fjasd",
+  #     :units    => :km
+  #   )
   #
   class Configuration
     include Singleton
@@ -54,53 +68,67 @@ module Geocoder
       :distances
     ]
 
-    attr_accessor *OPTIONS
+    attr_accessor :data
+
+    def self.set_defaults
+      instance.set_defaults
+    end
+
+    OPTIONS.each do |o|
+      define_method o do
+        @data[o]
+      end
+      define_method "#{o}=" do |value|
+        @data[o] = value
+      end
+    end
+
+    def configure(options)
+      @data.rmerge!(options)
+    end
 
     def initialize # :nodoc
+      @data = Geocoder::ConfigurationHash.new
       set_defaults
     end
 
     def set_defaults
-      @timeout      = 3           # geocoding service timeout (secs)
-      @lookup       = :google     # name of street address geocoding service (symbol)
-      @ip_lookup    = :freegeoip  # name of IP address geocoding service (symbol)
-      @language     = :en         # ISO-639 language code
-      @http_headers = {}          # HTTP headers for lookup
-      @use_https    = false       # use HTTPS for lookup requests? (if supported)
-      @http_proxy   = nil         # HTTP proxy server (user:pass@host:port)
-      @https_proxy  = nil         # HTTPS proxy server (user:pass@host:port)
-      @api_key      = nil         # API key for geocoding service
-      @cache        = nil         # cache object (must respond to #[], #[]=, and #keys)
-      @cache_prefix = "geocoder:" # prefix (string) to use for all cache keys
+
+      # geocoding options
+      @data[:timeout]      = 3           # geocoding service timeout (secs)
+      @data[:lookup]       = :google     # name of street address geocoding service (symbol)
+      @data[:ip_lookup]    = :freegeoip  # name of IP address geocoding service (symbol)
+      @data[:language]     = :en         # ISO-639 language code
+      @data[:http_headers] = {}          # HTTP headers for lookup
+      @data[:use_https]    = false       # use HTTPS for lookup requests? (if supported)
+      @data[:http_proxy]   = nil         # HTTP proxy server (user:pass@host:port)
+      @data[:https_proxy]  = nil         # HTTPS proxy server (user:pass@host:port)
+      @data[:api_key]      = nil         # API key for geocoding service
+      @data[:cache]        = nil         # cache object (must respond to #[], #[]=, and #keys)
+      @data[:cache_prefix] = "geocoder:" # prefix (string) to use for all cache keys
 
       # exceptions that should not be rescued by default
       # (if you want to implement custom error handling);
       # supports SocketError and TimeoutError
-      @always_raise = []
+      @data[:always_raise] = []
 
       # calculation options
-      @units     = :mi     # :mi or :km
-      @distances = :linear # :linear or :spherical
+      @data[:units]     = :mi      # :mi or :km
+      @data[:distances] = :linear  # :linear or :spherical
     end
 
     instance_eval(OPTIONS.map do |option|
       o = option.to_s
       <<-EOS
       def #{o}
-        instance.#{o}
+        instance.data[:#{o}]
       end
 
       def #{o}=(value)
-        instance.#{o} = value
+        instance.data[:#{o}] = value
       end
       EOS
     end.join("\n\n"))
 
-    class << self
-      def set_defaults
-        instance.set_defaults
-      end
-    end
-
   end
 end
diff --git a/lib/geocoder/configuration_hash.rb b/lib/geocoder/configuration_hash.rb
new file mode 100644
index 0000000000000000000000000000000000000000..70569c321a39de41cd05a2907ed98874589e494a
--- /dev/null
+++ b/lib/geocoder/configuration_hash.rb
@@ -0,0 +1,11 @@
+require 'hash_recursive_merge'
+
+module Geocoder
+  class ConfigurationHash < Hash
+    include HashRecursiveMerge
+
+    def method_missing(meth, *args, &block)
+      has_key?(meth) ? self[meth] : super
+    end
+  end
+end
diff --git a/lib/geocoder/lookups/base.rb b/lib/geocoder/lookups/base.rb
index c19a61da5947bc9ee73d7a74d5a003f32c4e7b64..821a87b96a8e561e3cee28a7a7f95b5e0e1b2fe4 100644
--- a/lib/geocoder/lookups/base.rb
+++ b/lib/geocoder/lookups/base.rb
@@ -23,6 +23,14 @@ module Geocoder
         fail
       end
 
+      ##
+      # Symbol which is used in configuration to refer to this Lookup.
+      #
+      def handle
+        str = self.class.to_s
+        str[str.rindex(':')+1..-1].gsub(/([a-z\d]+)([A-Z])/,'\1_\2').downcase.to_sym
+      end
+
       ##
       # Query the geocoding API and return a Geocoder::Result object.
       # Returns +nil+ on timeout or error.
@@ -61,13 +69,20 @@ module Geocoder
 
       private # -------------------------------------------------------------
 
+      ##
+      # An object with configuration data for this particular lookup.
+      #
+      def configuration
+        Geocoder.config_for_lookup(handle)
+      end
+
       ##
       # Object used to make HTTP requests.
       #
       def http_client
-        protocol = "http#{'s' if Geocoder::Configuration.use_https}"
+        protocol = "http#{'s' if configuration.use_https}"
         proxy_name = "#{protocol}_proxy"
-        if proxy = Geocoder::Configuration.send(proxy_name)
+        if proxy = configuration.send(proxy_name)
           proxy_url = protocol + '://' + proxy
           begin
             uri = URI.parse(proxy_url)
@@ -127,7 +142,7 @@ module Geocoder
       # Return false if exception not raised.
       #
       def raise_error(error, message = nil)
-        exceptions = Geocoder::Configuration.always_raise
+        exceptions = configuration.always_raise
         if exceptions == :all or exceptions.include?( error.is_a?(Class) ? error : error.class )
           raise error, message
         else
@@ -144,7 +159,7 @@ module Geocoder
         raise_error(err) or warn "Geocoding API connection cannot be established."
       rescue TimeoutError => err
         raise_error(err) or warn "Geocoding API not responding fast enough " +
-          "(see Geocoder::Configuration.timeout to set limit)."
+          "(use Geocoder.configure(:timeout => ...) to set limit)."
       end
 
       ##
@@ -165,7 +180,7 @@ module Geocoder
       # Set in configuration but not available for every service.
       #
       def protocol
-        "http" + (Geocoder::Configuration.use_https ? "s" : "")
+        "http" + (configuration.use_https ? "s" : "")
       end
 
       ##
@@ -193,17 +208,17 @@ module Geocoder
       # return the response object.
       #
       def make_api_request(query)
-        timeout(Geocoder::Configuration.timeout) do
+        timeout(configuration.timeout) do
           uri = URI.parse(query_url(query))
           client = http_client.new(uri.host, uri.port)
-          client.use_ssl = true if Geocoder::Configuration.use_https
-          client.get(uri.request_uri, Geocoder::Configuration.http_headers)
+          client.use_ssl = true if configuration.use_https
+          client.get(uri.request_uri, configuration.http_headers)
         end
       end
 
       def check_api_key_configuration!(query)
         key_parts = query.lookup.required_api_key_parts
-        if key_parts.size > Array(Geocoder::Configuration.api_key).size
+        if key_parts.size > Array(configuration.api_key).size
           parts_string = key_parts.size == 1 ? key_parts.first : key_parts
           raise Geocoder::ConfigurationError,
             "The #{query.lookup.name} API requires a key to be configured: " +
@@ -215,7 +230,10 @@ module Geocoder
       # The working Cache object.
       #
       def cache
-        Geocoder.cache
+        if @cache.nil? and store = configuration.cache
+          @cache = Cache.new(store, configuration.cache_prefix)
+        end
+        @cache
       end
 
       ##
diff --git a/lib/geocoder/lookups/bing.rb b/lib/geocoder/lookups/bing.rb
index 54dfa13d7453e3d36ddf942bf49364f4b0580ad3..c4ce5453a674a83d04aacbeb70c8a4a4c3d2f1a3 100644
--- a/lib/geocoder/lookups/bing.rb
+++ b/lib/geocoder/lookups/bing.rb
@@ -31,7 +31,7 @@ module Geocoder::Lookup
 
     def query_url_params(query)
       super.merge(
-        :key => Geocoder::Configuration.api_key,
+        :key => configuration.api_key,
         :query => query.reverse_geocode? ? nil : query.sanitized_text
       )
     end
diff --git a/lib/geocoder/lookups/geocoder_ca.rb b/lib/geocoder/lookups/geocoder_ca.rb
index 44b256c0c2803d72f850d520e480ff42aa16af8b..6c6bbf0f698d640e6b36397788372f65c2cb5a0a 100644
--- a/lib/geocoder/lookups/geocoder_ca.rb
+++ b/lib/geocoder/lookups/geocoder_ca.rb
@@ -31,7 +31,7 @@ module Geocoder::Lookup
         :geoit    => "xml",
         :jsonp    => 1,
         :callback => "test",
-        :auth     => Geocoder::Configuration.api_key
+        :auth     => configuration.api_key
       )
       if query.reverse_geocode?
         lat,lon = query.coordinates
diff --git a/lib/geocoder/lookups/google.rb b/lib/geocoder/lookups/google.rb
index b6b9302a71e4b55c153a9757303c770850c09887..43adc15cf7241a0e41ea0c59d2b018d131b32f56 100644
--- a/lib/geocoder/lookups/google.rb
+++ b/lib/geocoder/lookups/google.rb
@@ -35,7 +35,7 @@ module Geocoder::Lookup
       params = {
         (query.reverse_geocode? ? :latlng : :address) => query.sanitized_text,
         :sensor => "false",
-        :language => Geocoder::Configuration.language
+        :language => configuration.language
       }
       unless (bounds = query.options[:bounds]).nil?
         params[:bounds] = bounds.map{ |point| "%f,%f" % point }.join('|')
@@ -45,7 +45,7 @@ module Geocoder::Lookup
 
     def query_url_params(query)
       super.merge(query_url_google_params(query)).merge(
-        :key => Geocoder::Configuration.api_key
+        :key => configuration.api_key
       )
     end
 
diff --git a/lib/geocoder/lookups/google_premier.rb b/lib/geocoder/lookups/google_premier.rb
index a61cc56d87285436bb951b4a6c9dc59482778685..2bf63dc9d3b5098372fbf7bd7d512f6e43fbc598 100644
--- a/lib/geocoder/lookups/google_premier.rb
+++ b/lib/geocoder/lookups/google_premier.rb
@@ -19,8 +19,8 @@ module Geocoder::Lookup
     def query_url_params(query)
       super.merge(query_url_google_params(query)).merge(
         :key => nil, # don't use param inherited from Google lookup
-        :client => Geocoder::Configuration.api_key[1],
-        :channel => Geocoder::Configuration.api_key[2]
+        :client => configuration.api_key[1],
+        :channel => configuration.api_key[2]
       )
     end
 
@@ -30,7 +30,7 @@ module Geocoder::Lookup
     end
 
     def sign(string)
-      raw_private_key = url_safe_base64_decode(Geocoder::Configuration.api_key[0])
+      raw_private_key = url_safe_base64_decode(configuration.api_key[0])
       digest = OpenSSL::Digest::Digest.new('sha1')
       raw_signature = OpenSSL::HMAC.digest(digest, raw_private_key, string)
       url_safe_base64_encode(raw_signature)
diff --git a/lib/geocoder/lookups/mapquest.rb b/lib/geocoder/lookups/mapquest.rb
index fd5ae8c643c0228158ed8e01bf8727f869ae5904..46cc8c233a29201ab9414d77804e155c56b9b096 100644
--- a/lib/geocoder/lookups/mapquest.rb
+++ b/lib/geocoder/lookups/mapquest.rb
@@ -16,7 +16,7 @@ module Geocoder::Lookup
     private # ---------------------------------------------------------------
 
     def query_url(query)
-      key = Geocoder::Configuration.api_key
+      key = configuration.api_key
       domain = key ? "www" : "open"
       url = "#{protocol}://#{domain}.mapquestapi.com/geocoding/v1/#{search_type(query)}?"
       url + url_query_string(query)
@@ -27,7 +27,7 @@ module Geocoder::Lookup
     end
 
     def query_url_params(query)
-      key = Geocoder::Configuration.api_key
+      key = configuration.api_key
       params = { :location => query.sanitized_text }
       if key
         params[:key] = CGI.unescape(key)
diff --git a/lib/geocoder/lookups/nominatim.rb b/lib/geocoder/lookups/nominatim.rb
index f7ed5638e6237583b000481c700a1c731a8808ea..8fb7a6de32630c0bf668961e4ded5fce9d5e619e 100644
--- a/lib/geocoder/lookups/nominatim.rb
+++ b/lib/geocoder/lookups/nominatim.rb
@@ -24,7 +24,7 @@ module Geocoder::Lookup
         :format => "json",
         :polygon => "1",
         :addressdetails => "1",
-        :"accept-language" => Geocoder::Configuration.language
+        :"accept-language" => configuration.language
       )
       if query.reverse_geocode?
         lat,lon = query.coordinates
@@ -38,7 +38,8 @@ module Geocoder::Lookup
 
     def query_url(query)
       method = query.reverse_geocode? ? "reverse" : "search"
-      "#{protocol}://nominatim.openstreetmap.org/#{method}?" + url_query_string(query)
+      host = configuration[:host] || "nominatim.openstreetmap.org"
+      "#{protocol}://#{host}/#{method}?" + url_query_string(query)
     end
   end
 end
diff --git a/lib/geocoder/lookups/yahoo.rb b/lib/geocoder/lookups/yahoo.rb
index be1925df82eecb85f0c761d12399f447510812ba..43138b62d3ae06879126dd11fd5442871b387f60 100644
--- a/lib/geocoder/lookups/yahoo.rb
+++ b/lib/geocoder/lookups/yahoo.rb
@@ -38,7 +38,9 @@ module Geocoder::Lookup
       super.merge(
         :location => query.sanitized_text,
         :flags => "JXTSR",
-        :gflags => "AC#{'R' if query.reverse_geocode?}"
+        :gflags => "AC#{'R' if query.reverse_geocode?}",
+        :locale => "#{configuration.language}_US",
+        :appid => configuration.api_key
       )
     end
 
@@ -57,8 +59,8 @@ module Geocoder::Lookup
     def query_url(query)
       parsed_url = URI.parse(raw_url(query))
       o = OauthUtil.new
-      o.consumer_key = Geocoder::Configuration.api_key[0]
-      o.consumer_secret = Geocoder::Configuration.api_key[1]
+      o.consumer_key = configuration.api_key[0]
+      o.consumer_secret = configuration.api_key[1]
       base_url + o.sign(parsed_url).query_string
     end
   end
diff --git a/lib/geocoder/lookups/yandex.rb b/lib/geocoder/lookups/yandex.rb
index 7470eb0fc6ac43194162d107d107146432694948..4b306e1ef68d0eb596283c43083a60aec5ffda74 100644
--- a/lib/geocoder/lookups/yandex.rb
+++ b/lib/geocoder/lookups/yandex.rb
@@ -42,8 +42,8 @@ module Geocoder::Lookup
       super.merge(
         :geocode => q,
         :format => "json",
-        :plng => "#{Geocoder::Configuration.language}", # supports ru, uk, be
-        :key => Geocoder::Configuration.api_key
+        :plng => "#{configuration.language}", # supports ru, uk, be
+        :key => configuration.api_key
       )
     end
 
diff --git a/lib/geocoder/query.rb b/lib/geocoder/query.rb
index 1f722318e6957dafba6d8d18844ce17a25612cfb..d0f4469e6c4c719b0c5fd3dd7da8c71cd75904d2 100644
--- a/lib/geocoder/query.rb
+++ b/lib/geocoder/query.rb
@@ -42,15 +42,10 @@ module Geocoder
     # no URL parameters are specified.
     #
     def blank?
-      # check whether both coordinates given
-      if text.is_a?(Array)
-        text.compact.size < 2
-      # else assume a string
-      else
-        !!text.to_s.match(/^\s*$/) and (
-          !options[:params].is_a?(Hash) or options[:params].keys.size == 0
-        )
-      end
+      !params_given? and (
+        (text.is_a?(Array) and text.compact.size < 2) or
+        text.to_s.match(/^\s*$/)
+      )
     end
 
     ##
@@ -94,5 +89,11 @@ module Geocoder
     def reverse_geocode?
       coordinates?
     end
+
+    private # ----------------------------------------------------------------
+
+    def params_given?
+      !!(options[:params].is_a?(Hash) and options[:params].keys.size > 0)
+    end
   end
 end
diff --git a/lib/geocoder/results/nominatim.rb b/lib/geocoder/results/nominatim.rb
index 07536814ea4789b7cf16ce0a5a475f04d461885d..249d75f520cf50787668d544b3a715e53f2658ab 100644
--- a/lib/geocoder/results/nominatim.rb
+++ b/lib/geocoder/results/nominatim.rb
@@ -83,16 +83,6 @@ module Geocoder::Result
          polygonpoints display_name class type stadium]
     end
 
-    def class
-      warn "DEPRECATION WARNING: The 'class' method of Geocoder::Result::Nominatim objects is deprecated and will be removed in Geocoder version 1.2.0. Please use 'place_class' instead."
-      @data['class']
-    end
-
-    def type
-      warn "DEPRECATION WARNING: The 'type' method of Geocoder::Result::Nominatim objects is deprecated and will be removed in Geocoder version 1.2.0. Please use 'place_type' instead."
-      @data['type']
-    end
-
     response_attributes.each do |a|
       unless method_defined?(a)
         define_method a do
diff --git a/lib/geocoder/sql.rb b/lib/geocoder/sql.rb
index af0b4983a84cd6275b56da4de70fbe8514282a8e..8d390b4391180643cbdc1f533fbc4c191049f079 100644
--- a/lib/geocoder/sql.rb
+++ b/lib/geocoder/sql.rb
@@ -11,7 +11,7 @@ module Geocoder
     # http://www.scribd.com/doc/2569355/Geo-Distance-Search-with-MySQL
     #
     def full_distance(latitude, longitude, lat_attr, lon_attr, options = {})
-      units = options[:units] || Geocoder::Configuration.units
+      units = options[:units] || Geocoder.config.units
       earth = Geocoder::Calculations.earth_radius(units)
 
       "#{earth} * 2 * ASIN(SQRT(" +
@@ -32,7 +32,7 @@ module Geocoder
     # are not intended for use in production!
     #
     def approx_distance(latitude, longitude, lat_attr, lon_attr, options = {})
-      units = options[:units] || Geocoder::Configuration.units
+      units = options[:units] || Geocoder.config.units
       dx = Geocoder::Calculations.longitude_degree_distance(30, units)
       dy = Geocoder::Calculations.latitude_degree_distance(units)
 
@@ -63,7 +63,7 @@ module Geocoder
     # http://www.beginningspatial.com/calculating_bearing_one_point_another
     #
     def full_bearing(latitude, longitude, lat_attr, lon_attr, options = {})
-      case options[:bearing] || Geocoder::Configuration.distances
+      case options[:bearing] || Geocoder.config.distances
       when :linear
         "CAST(" +
           "DEGREES(ATAN2( " +
diff --git a/lib/geocoder/stores/active_record.rb b/lib/geocoder/stores/active_record.rb
index b088089f0a445bbecb85a158c8da1798d9062a56..6d93db11aed629af9a1320677b8612203da6ef3f 100644
--- a/lib/geocoder/stores/active_record.rb
+++ b/lib/geocoder/stores/active_record.rb
@@ -87,19 +87,19 @@ module Geocoder::Store
       # * +:units+   - <tt>:mi</tt> or <tt>:km</tt>; to be used.
       #   for interpreting radius as well as the +distance+ attribute which
       #   is added to each found nearby object.
-      #   See Geocoder::Configuration to know how configure default units.
+      #   Use Geocoder.configure[:units] to configure default units.
       # * +:bearing+ - <tt>:linear</tt> or <tt>:spherical</tt>.
       #   the method to be used for calculating the bearing (direction)
       #   between the given point and each found nearby point;
-      #   set to false for no bearing calculation.
-      #   See Geocoder::Configuration to know how configure default method.
+      #   set to false for no bearing calculation. Use
+      #   Geocoder.configure[:distances] to configure default calculation method.
       # * +:select+  - string with the SELECT SQL fragment (e.g. “id, name”)
       # * +:order+   - column(s) for ORDER BY SQL clause; default is distance;
       #                set to false or nil to omit the ORDER BY clause
       # * +:exclude+ - an object to exclude (used by the +nearbys+ method)
       #
       def near_scope_options(latitude, longitude, radius = 20, options = {})
-        options[:units] ||= (geocoder_options[:units] || Geocoder::Configuration.units)
+        options[:units] ||= (geocoder_options[:units] || Geocoder.config.units)
         bearing = bearing_sql(latitude, longitude, options)
         distance = distance_sql(latitude, longitude, options)
 
@@ -143,7 +143,7 @@ module Geocoder::Store
       #
       def bearing_sql(latitude, longitude, options = {})
         if !options.include?(:bearing)
-          options[:bearing] = Geocoder::Configuration.distances
+          options[:bearing] = Geocoder.config.distances
         end
         if options[:bearing]
           method_prefix = using_sqlite? ? "approx" : "full"
diff --git a/lib/hash_recursive_merge.rb b/lib/hash_recursive_merge.rb
new file mode 100644
index 0000000000000000000000000000000000000000..163566ee13c2816b93999baf4c2bc5e493510170
--- /dev/null
+++ b/lib/hash_recursive_merge.rb
@@ -0,0 +1,74 @@
+# 
+# = Hash Recursive Merge
+# 
+# Merges a Ruby Hash recursively, Also known as deep merge.
+# Recursive version of Hash#merge and Hash#merge!.
+# 
+# Category::    Ruby
+# Package::     Hash
+# Author::      Simone Carletti <weppos@weppos.net>
+# Copyright::   2007-2008 The Authors
+# License::     MIT License
+# Link::        http://www.simonecarletti.com/
+# Source::      http://gist.github.com/gists/6391/
+#
+module HashRecursiveMerge
+
+  #
+  # Recursive version of Hash#merge!
+  # 
+  # Adds the contents of +other_hash+ to +hsh+, 
+  # merging entries in +hsh+ with duplicate keys with those from +other_hash+.
+  # 
+  # Compared with Hash#merge!, this method supports nested hashes.
+  # When both +hsh+ and +other_hash+ contains an entry with the same key,
+  # it merges and returns the values from both arrays.
+  # 
+  #    h1 = {"a" => 100, "b" => 200, "c" => {"c1" => 12, "c2" => 14}}
+  #    h2 = {"b" => 254, "c" => {"c1" => 16, "c3" => 94}}
+  #    h1.rmerge!(h2)   #=> {"a" => 100, "b" => 254, "c" => {"c1" => 16, "c2" => 14, "c3" => 94}}
+  #    
+  # Simply using Hash#merge! would return
+  # 
+  #    h1.merge!(h2)    #=> {"a" => 100, "b" = >254, "c" => {"c1" => 16, "c3" => 94}}
+  # 
+  def rmerge!(other_hash)
+    merge!(other_hash) do |key, oldval, newval|
+      oldval.class == self.class ? oldval.rmerge!(newval) : newval
+    end
+  end
+
+  #
+  # Recursive version of Hash#merge
+  # 
+  # Compared with Hash#merge!, this method supports nested hashes.
+  # When both +hsh+ and +other_hash+ contains an entry with the same key,
+  # it merges and returns the values from both arrays.
+  # 
+  # Compared with Hash#merge, this method provides a different approch
+  # for merging nasted hashes.
+  # If the value of a given key is an Hash and both +other_hash+ abd +hsh
+  # includes the same key, the value is merged instead replaced with
+  # +other_hash+ value.
+  # 
+  #    h1 = {"a" => 100, "b" => 200, "c" => {"c1" => 12, "c2" => 14}}
+  #    h2 = {"b" => 254, "c" => {"c1" => 16, "c3" => 94}}
+  #    h1.rmerge(h2)    #=> {"a" => 100, "b" => 254, "c" => {"c1" => 16, "c2" => 14, "c3" => 94}}
+  #    
+  # Simply using Hash#merge would return
+  # 
+  #    h1.merge(h2)     #=> {"a" => 100, "b" = >254, "c" => {"c1" => 16, "c3" => 94}}
+  # 
+  def rmerge(other_hash)
+    r = {}
+    merge(other_hash) do |key, oldval, newval|
+      r[key] = oldval.class == self.class ? oldval.rmerge(newval) : newval
+    end
+  end
+
+end
+
+
+class Hash
+  include HashRecursiveMerge
+end
diff --git a/test/cache_test.rb b/test/cache_test.rb
index f505b805db0863bbc9c6fc8168b7cb6457b0785a..edd45bbfae62464244570da05ad58195b5ef1e31 100644
--- a/test/cache_test.rb
+++ b/test/cache_test.rb
@@ -4,9 +4,9 @@ require 'test_helper'
 class CacheTest < Test::Unit::TestCase
 
   def test_second_occurrence_of_request_is_cache_hit
-    Geocoder::Configuration.cache = {}
+    Geocoder.configure(:cache => {})
     Geocoder::Lookup.all_services_except_test.each do |l|
-      Geocoder::Configuration.lookup = l
+      Geocoder.configure(:lookup => l)
       set_api_key!(l)
       results = Geocoder.search("Madison Square Garden")
       assert !results.first.cache_hit,
diff --git a/test/calculations_test.rb b/test/calculations_test.rb
index 902d8d680f8926bb89115b383b89acf72f07bbe3..104d237ffcfe3614099b6ea7bdafc4402044b11f 100644
--- a/test/calculations_test.rb
+++ b/test/calculations_test.rb
@@ -3,10 +3,10 @@ require 'test_helper'
 
 class CalculationsTest < Test::Unit::TestCase
   def setup
-    Geocoder.configure do |config|
-      config.units  = :mi
-      config.distances = :linear
-    end
+    Geocoder.configure(
+      :units => :mi,
+      :distances => :linear
+    )
   end
 
   # --- degree distance ---
diff --git a/test/configuration_test.rb b/test/configuration_test.rb
index 4137fbf44bf2a8fc6f7e8561f17234944f70e107..7aad1d7f9059c0813e360c8528de5b5503f83290 100644
--- a/test/configuration_test.rb
+++ b/test/configuration_test.rb
@@ -7,69 +7,44 @@ class ConfigurationTest < Test::Unit::TestCase
   end
 
   def test_exception_raised_on_bad_lookup_config
-    Geocoder::Configuration.lookup = :stoopid
+    Geocoder.configure(:lookup => :stoopid)
     assert_raises Geocoder::ConfigurationError do
       Geocoder.search "something dumb"
     end
   end
 
-  # --- class method configuration ---
-  def test_configurated_by_class_method
-    Geocoder::Configuration.units = :mi
-    distance = Geocoder::Calculations.distance_between([0,0], [0,1]).round
-    assert_not_equal 111, distance
-    assert_equal      69, distance
-
-    Geocoder::Configuration.units = :km
-    distance = Geocoder::Calculations.distance_between([0,0], [0,1]).round
-    assert_equal    111, distance
-    assert_not_equal 69, distance
-
-    Geocoder::Configuration.distances = :spherical
-    angle = Geocoder::Calculations.bearing_between([50,-85], [40.750354, -73.993371]).round
-    assert_equal     136, angle
-    assert_not_equal 130, angle
+  def test_setting_with_class_method
+    Geocoder::Configuration.units = :test
+    assert_equal :test, Geocoder.config.units
+  end
 
-    Geocoder::Configuration.distances = :linear
-    angle = Geocoder::Calculations.bearing_between([50,-85], [40.750354, -73.993371]).round
-    assert_not_equal 136, angle
-    assert_equal     130, angle
+  def test_setting_with_configure_method
+    Geocoder.configure(:units => :test)
+    assert_equal :test, Geocoder.config.units
   end
 
-  # --- Geocoder#configure distances configuration ---
-  def test_geocoder_configuration
-    # DSL
+  def test_setting_with_block_syntax
+    orig = $VERBOSE; $VERBOSE = nil
     Geocoder.configure do |config|
-      config.units  = :mi
-      config.distances = :linear
+      config.units = :test
     end
+    assert_equal :test, Geocoder.config.units
+  ensure
+    $VERBOSE = orig
+  end
 
-    assert_equal Geocoder::Configuration.units, :mi
-    distance = Geocoder::Calculations.distance_between([0,0], [0,1]).round
-    assert_not_equal 111, distance
-    assert_equal      69, distance
-
-    assert_equal Geocoder::Configuration.distances, :linear
-    angle = Geocoder::Calculations.bearing_between([50,-85], [40.750354, -73.993371]).round
-    assert_not_equal 136, angle
-    assert_equal     130, angle
-
-    # Direct
-    Geocoder.configure.units  = :km
-    Geocoder.configure.distances = :spherical
-
-    assert_equal Geocoder::Configuration.units, :km
-    distance = Geocoder::Calculations.distance_between([0,0], [0,1]).round
-    assert_equal    111, distance
-    assert_not_equal 69, distance
-
-    assert_equal Geocoder::Configuration.distances, :spherical
-    angle = Geocoder::Calculations.bearing_between([50,-85], [40.750354, -73.993371]).round
-    assert_equal     136, angle
-    assert_not_equal 130, angle
+  def test_config_for_lookup
+    Geocoder.configure(
+      :timeout => 5,
+      :api_key => "aaa",
+      :google => {
+        :timeout => 2
+      }
+    )
+    assert_equal 2, Geocoder.config_for_lookup(:google).timeout
+    assert_equal "aaa", Geocoder.config_for_lookup(:google).api_key
   end
 
-  # Geocoder per-model configuration
   def test_model_configuration
     Landmark.reverse_geocoded_by :latitude, :longitude, :method => :spherical, :units => :km
     assert_equal :km,        Landmark.geocoder_options[:units]
@@ -90,7 +65,7 @@ class ConfigurationTest < Test::Unit::TestCase
     v.longitude = 0
 
     # method option > global configuration
-    Geocoder.configure.units  = :km
+    Geocoder.configure(:units => :km)
     assert_equal 69, v.distance_to([0,1], :mi).round
 
     # per-model configuration > global configuration
diff --git a/test/error_handling_test.rb b/test/error_handling_test.rb
index 01f5f73305a22c39954bd2e984d427496229adc5..b4f28774ea90b6624a005b138ee5ce4409411038 100644
--- a/test/error_handling_test.rb
+++ b/test/error_handling_test.rb
@@ -4,14 +4,14 @@ require 'test_helper'
 class ErrorHandlingTest < Test::Unit::TestCase
 
   def teardown
-    Geocoder::Configuration.always_raise = []
+    Geocoder.configure(:always_raise => [])
   end
 
   def test_does_not_choke_on_timeout
     # keep test output clean: suppress timeout warning
     orig = $VERBOSE; $VERBOSE = nil
     Geocoder::Lookup.all_services_except_test.each do |l|
-      Geocoder::Configuration.lookup = l
+      Geocoder.configure(:lookup => l)
       set_api_key!(l)
       assert_nothing_raised { Geocoder.search("timeout") }
     end
@@ -20,7 +20,7 @@ class ErrorHandlingTest < Test::Unit::TestCase
   end
 
   def test_always_raise_timeout_error
-    Geocoder::Configuration.always_raise = [TimeoutError]
+    Geocoder.configure(:always_raise => [TimeoutError])
     Geocoder::Lookup.all_services_except_test.each do |l|
       lookup = Geocoder::Lookup.get(l)
       set_api_key!(l)
@@ -31,7 +31,7 @@ class ErrorHandlingTest < Test::Unit::TestCase
   end
 
   def test_always_raise_socket_error
-    Geocoder::Configuration.always_raise = [SocketError]
+    Geocoder.configure(:always_raise => [SocketError])
     Geocoder::Lookup.all_services_except_test.each do |l|
       lookup = Geocoder::Lookup.get(l)
       set_api_key!(l)
diff --git a/test/https_test.rb b/test/https_test.rb
index aba96acf7e53aea456c91ba503659a5f23160c2a..3a922bf4d63278a2608bf3c288d33f6c09b2f73d 100644
--- a/test/https_test.rb
+++ b/test/https_test.rb
@@ -4,7 +4,7 @@ require 'test_helper'
 class HttpsTest < Test::Unit::TestCase
 
   def test_uses_https_for_secure_query
-    Geocoder::Configuration.use_https = true
+    Geocoder.configure(:use_https => true)
     g = Geocoder::Lookup::Google.new
     assert_match /^https:/, g.send(:query_url, Geocoder::Query.new("test"))
   end
diff --git a/test/integration/smoke_test.rb b/test/integration/smoke_test.rb
index b0c805e61759fc9695c14bde1c0c8eca8d0d1802..0b7cf2fbabe3c9cd31cab65ddcd135ca5e62b24b 100644
--- a/test/integration/smoke_test.rb
+++ b/test/integration/smoke_test.rb
@@ -14,13 +14,13 @@ class SmokeTest < Test::Unit::TestCase
   end
 
   def test_simple_zip_code_search_with_ssl
-    Geocoder::Configuration.use_https = true
+    Geocoder.configure(:use_https => true)
     result = Geocoder.search "27701"
     assert_not_nil (r = result.first)
     assert_equal "Durham", r.city
     assert_equal "North Carolina", r.state
   ensure
-    Geocoder::Configuration.use_https = false
+    Geocoder.configure(:use_https => false)
   end
 
 end
diff --git a/test/lookup_test.rb b/test/lookup_test.rb
index 4c9a00478a879694992d7abf1b6f84a9086f75f6..d4b9fd34ea8b109f1b9754e36c621c2f93fc46b8 100644
--- a/test/lookup_test.rb
+++ b/test/lookup_test.rb
@@ -14,7 +14,7 @@ class LookupTest < Test::Unit::TestCase
 
   def test_does_not_choke_on_nil_address
     Geocoder::Lookup.all_services.each do |l|
-      Geocoder::Configuration.lookup = l
+      Geocoder.configure(:lookup => l)
       assert_nothing_raised { Venue.new("Venue", nil).geocode }
     end
   end
@@ -25,22 +25,26 @@ class LookupTest < Test::Unit::TestCase
   end
 
   def test_google_api_key
-    Geocoder::Configuration.api_key = "MY_KEY"
+    Geocoder.configure(:api_key => "MY_KEY")
     g = Geocoder::Lookup::Google.new
     assert_match "key=MY_KEY", g.send(:query_url, Geocoder::Query.new("Madison Square Garden, New York, NY  10001, United States"))
   end
 
   def test_geocoder_ca_showpostal
-    Geocoder::Configuration.api_key = "MY_KEY"
+    Geocoder.configure(:api_key => "MY_KEY")
     g = Geocoder::Lookup::GeocoderCa.new
     assert_match "showpostal=1", g.send(:query_url, Geocoder::Query.new("Madison Square Garden, New York, NY  10001, United States"))
   end
 
   def test_raises_configuration_error_on_missing_key
     assert_raises Geocoder::ConfigurationError do
-      Geocoder::Configuration.lookup = :bing
-      Geocoder::Configuration.api_key = nil
+      Geocoder.configure(:lookup => :bing, :api_key => nil)
       Geocoder.search("Madison Square Garden, New York, NY  10001, United States")
     end
   end
+
+  def test_handle
+    assert_equal :google, Geocoder::Lookup::Google.new.handle
+    assert_equal :geocoder_ca, Geocoder::Lookup::GeocoderCa.new.handle
+  end
 end
diff --git a/test/proxy_test.rb b/test/proxy_test.rb
index d701fdce39d2663d5732379676d6960e2268c796..654b8160c0dd8c89fb3affbda21a8bebc423aedd 100644
--- a/test/proxy_test.rb
+++ b/test/proxy_test.rb
@@ -4,7 +4,7 @@ require 'test_helper'
 class ProxyTest < Test::Unit::TestCase
 
   def test_uses_proxy_when_specified
-    Geocoder::Configuration.http_proxy = 'localhost'
+    Geocoder.configure(:http_proxy => 'localhost')
     lookup = Geocoder::Lookup::Google.new
     assert lookup.send(:http_client).proxy_class?
   end
@@ -15,7 +15,7 @@ class ProxyTest < Test::Unit::TestCase
   end
 
   def test_exception_raised_on_bad_proxy_url
-    Geocoder::Configuration.http_proxy = ' \\_O< Quack Quack'
+    Geocoder.configure(:http_proxy => ' \\_O< Quack Quack')
     assert_raise Geocoder::ConfigurationError do
       Geocoder::Lookup::Google.new.send(:http_client)
     end
diff --git a/test/result_test.rb b/test/result_test.rb
index f826648dd743cde17c0c2a8d29d87f0d39406029..abd6816882e3207b192945d6550ff18f437bc6bf 100644
--- a/test/result_test.rb
+++ b/test/result_test.rb
@@ -5,7 +5,7 @@ class ResultTest < Test::Unit::TestCase
 
   def test_result_has_required_attributes
     Geocoder::Lookup.all_services_except_test.each do |l|
-      Geocoder::Configuration.lookup = l
+      Geocoder.configure(:lookup => l)
       set_api_key!(l)
       result = Geocoder.search([45.423733, -75.676333]).first
       assert_result_has_required_attributes(result)
@@ -16,7 +16,7 @@ class ResultTest < Test::Unit::TestCase
   private # ------------------------------------------------------------------
 
   def assert_result_has_required_attributes(result)
-    m = "Lookup #{Geocoder::Configuration.lookup} does not support %s attribute."
+    m = "Lookup #{Geocoder.config.lookup} does not support %s attribute."
     assert result.coordinates.is_a?(Array),    m % "coordinates"
     assert result.latitude.is_a?(Float),       m % "latitude"
     assert result.longitude.is_a?(Float),      m % "longitude"
diff --git a/test/services_test.rb b/test/services_test.rb
index d33a648f16f6e8cab7a1eea80f3e19e825f5b2fb..20a4f403f8e7ac4c1d2cf968b357855d420465b4 100644
--- a/test/services_test.rb
+++ b/test/services_test.rb
@@ -59,7 +59,7 @@ class ServicesTest < Test::Unit::TestCase
   # --- Google Premier ---
 
   def test_google_premier_result_components
-    Geocoder::Configuration.lookup = :google_premier
+    Geocoder.configure(:lookup => :google_premier)
     set_api_key!(:google_premier)
     result = Geocoder.search("Madison Square Garden, New York, NY").first
     assert_equal "Manhattan",
@@ -67,7 +67,7 @@ class ServicesTest < Test::Unit::TestCase
   end
 
   def test_google_premier_query_url
-    Geocoder::Configuration.api_key = ["deadbeef", "gme-test", "test-dev"]
+    Geocoder.configure(:api_key => ["deadbeef", "gme-test", "test-dev"])
     assert_equal "http://maps.googleapis.com/maps/api/geocode/json?address=Madison+Square+Garden%2C+New+York%2C+NY&channel=test-dev&client=gme-test&language=en&sensor=false&signature=doJvJqX7YJzgV9rJ0DnVkTGZqTg=",
       Geocoder::Lookup::GooglePremier.new.send(:query_url, Geocoder::Query.new("Madison Square Garden, New York, NY"))
   end
@@ -76,13 +76,13 @@ class ServicesTest < Test::Unit::TestCase
   # --- Yahoo ---
 
   def test_yahoo_no_results
-    Geocoder::Configuration.lookup = :yahoo
+    Geocoder.configure(:lookup => :yahoo)
     set_api_key!(:yahoo)
     assert_equal [], Geocoder.search("no results")
   end
 
   def test_yahoo_error
-    Geocoder::Configuration.lookup = :yahoo
+    Geocoder.configure(:lookup => :yahoo)
     set_api_key!(:yahoo)
     # keep test output clean: suppress timeout warning
     orig = $VERBOSE; $VERBOSE = nil
@@ -92,14 +92,14 @@ class ServicesTest < Test::Unit::TestCase
   end
 
   def test_yahoo_result_components
-    Geocoder::Configuration.lookup = :yahoo
+    Geocoder.configure(:lookup => :yahoo)
     set_api_key!(:yahoo)
     result = Geocoder.search("madison square garden").first
     assert_equal "10001", result.postal_code
   end
 
   def test_yahoo_address_formatting
-    Geocoder::Configuration.lookup = :yahoo
+    Geocoder.configure(:lookup => :yahoo)
     set_api_key!(:yahoo)
     result = Geocoder.search("madison square garden").first
     assert_equal "Madison Square Garden, New York, NY 10001, United States", result.address
@@ -111,7 +111,7 @@ class ServicesTest < Test::Unit::TestCase
   def test_yandex_with_invalid_key
     # keep test output clean: suppress timeout warning
     orig = $VERBOSE; $VERBOSE = nil
-    Geocoder::Configuration.lookup = :yandex
+    Geocoder.configure(:lookup => :yandex)
     set_api_key!(:yandex)
     assert_equal [], Geocoder.search("invalid key")
   ensure
@@ -122,7 +122,7 @@ class ServicesTest < Test::Unit::TestCase
   # --- Geocoder.ca ---
 
   def test_geocoder_ca_result_components
-    Geocoder::Configuration.lookup = :geocoder_ca
+    Geocoder.configure(:lookup => :geocoder_ca)
     set_api_key!(:geocoder_ca)
     result = Geocoder.search([45.423733, -75.676333]).first
     assert_equal "CA", result.country_code
@@ -146,7 +146,7 @@ class ServicesTest < Test::Unit::TestCase
   # --- Bing ---
 
   def test_bing_result_components
-    Geocoder::Configuration.lookup = :bing
+    Geocoder.configure(:lookup => :bing)
     set_api_key!(:bing)
     result = Geocoder.search("Madison Square Garden, New York, NY").first
     assert_equal "Madison Square Garden, NY", result.address
@@ -155,7 +155,7 @@ class ServicesTest < Test::Unit::TestCase
   end
 
   def test_bing_no_results
-    Geocoder::Configuration.lookup = :bing
+    Geocoder.configure(:lookup => :bing)
     set_api_key!(:bing)
     results = Geocoder.search("no results")
     assert_equal 0, results.length
@@ -164,25 +164,31 @@ class ServicesTest < Test::Unit::TestCase
   # --- Nominatim ---
 
   def test_nominatim_result_components
-    Geocoder::Configuration.lookup = :nominatim
+    Geocoder.configure(:lookup => :nominatim)
     set_api_key!(:nominatim)
     result = Geocoder.search("Madison Square Garden, New York, NY").first
     assert_equal "10001", result.postal_code
   end
 
   def test_nominatim_address_formatting
-    Geocoder::Configuration.lookup = :nominatim
+    Geocoder.configure(:lookup => :nominatim)
     set_api_key!(:nominatim)
     result = Geocoder.search("Madison Square Garden, New York, NY").first
     assert_equal "Madison Square Garden, West 31st Street, Long Island City, New York City, New York, 10001, United States of America",
       result.address
   end
 
+  def test_nominatim_host_config
+    Geocoder.configure(:lookup => :nominatim, :nominatim => {:host => "local.com"})
+    lookup = Geocoder::Lookup::Nominatim.new
+    query = Geocoder::Query.new("Bluffton, SC")
+    assert_match %r(http://local\.com), lookup.send(:query_url, query)
+  end
+
   # --- MapQuest ---
 
   def test_api_route
-    Geocoder::Configuration.lookup = :mapquest
-    Geocoder::Configuration.api_key = "abc123"
+    Geocoder.configure(:lookup => :mapquest, :api_key => "abc123")
     lookup = Geocoder::Lookup::Mapquest.new
     query = Geocoder::Query.new("Bluffton, SC")
     res = lookup.send(:query_url, query)
@@ -191,14 +197,14 @@ class ServicesTest < Test::Unit::TestCase
   end
 
   def test_mapquest_result_components
-    Geocoder::Configuration.lookup = :mapquest
+    Geocoder.configure(:lookup => :mapquest)
     set_api_key!(:mapquest)
     result = Geocoder.search("Madison Square Garden, New York, NY").first
     assert_equal "10001", result.postal_code
   end
 
   def test_mapquest_address_formatting
-    Geocoder::Configuration.lookup = :mapquest
+    Geocoder.configure(:lookup => :mapquest)
     set_api_key!(:mapquest)
     result = Geocoder.search("Madison Square Garden, New York, NY").first
     assert_equal "46 West 31st Street, New York, NY, 10001, US",
diff --git a/test/test_helper.rb b/test/test_helper.rb
index bff1219907fc5343f6426f114a9290135e195a05..5c93eb1ba3da487e2cd0eaca3ed3980340d34ca9 100644
--- a/test/test_helper.rb
+++ b/test/test_helper.rb
@@ -334,6 +334,6 @@ class Test::Unit::TestCase
     else
       key = nil
     end
-    Geocoder::Configuration.api_key = key
+    Geocoder.configure(:api_key => key)
   end
 end
diff --git a/test/test_mode_test.rb b/test/test_mode_test.rb
index 0bece98b0935edd9a3a717cfa10904601c219f75..9e80726a29f32fd81db741af141ecdf1b7569e40 100644
--- a/test/test_mode_test.rb
+++ b/test/test_mode_test.rb
@@ -3,13 +3,13 @@ require 'test_helper'
 class TestModeTest < Test::Unit::TestCase
 
   def setup
-    @_original_lookup = Geocoder::Configuration.lookup
-    Geocoder::Configuration.lookup = :test
+    @_original_lookup = Geocoder.config.lookup
+    Geocoder.configure(:lookup => :test)
   end
 
   def teardown
     Geocoder::Lookup::Test.reset
-    Geocoder::Configuration.lookup = @_original_lookup
+    Geocoder.configure(:lookup => @_original_lookup)
   end
 
   def test_search_with_known_stub