diff --git a/lib/generators/geocoder/config/config_generator.rb b/lib/generators/geocoder/config/config_generator.rb
new file mode 100644
index 0000000000000000000000000000000000000000..3fe3b3c17fecaeb026c87013e0a63f24c05333a8
--- /dev/null
+++ b/lib/generators/geocoder/config/config_generator.rb
@@ -0,0 +1,14 @@
+require 'rails/generators'
+
+module Geocoder
+  class ConfigGenerator < Rails::Generators::Base
+    source_root File.expand_path("../templates", __FILE__)
+
+    desc "This generator creates an initializer file at config/initializers, " +
+         "with the default configuration options for Geocoder."
+    def add_initializer
+      template "initializer.rb", "config/initializers/geocoder.rb"
+    end
+  end
+end
+
diff --git a/lib/generators/geocoder/config/templates/initializer.rb b/lib/generators/geocoder/config/templates/initializer.rb
new file mode 100644
index 0000000000000000000000000000000000000000..0401d015895507530bd4545573d9f3c6c0de8357
--- /dev/null
+++ b/lib/generators/geocoder/config/templates/initializer.rb
@@ -0,0 +1,25 @@
+Geocoder.configure do
+  ## Configurable parameters: if you wish to change some configurable
+  ## behaviour in Geocoder, feel free to uncomment the following lines
+  ## and provide custom parameters.
+
+  # 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
+  # config.always_raise = []
+
+  ## Calculation options
+  # config.units  = :mi        # :km for kilometers or :mi for miles
+  # config.method = :linear    # :spherical or :linear
+end
+
diff --git a/lib/geocoder.rb b/lib/geocoder.rb
index 692551e8998938ad58aaa4adf3583664c99ccb39..0882f15e3281c62d5438d96928eba7426cb0a036 100644
--- a/lib/geocoder.rb
+++ b/lib/geocoder.rb
@@ -10,6 +10,17 @@ require "geocoder/models/mongo_mapper" if defined?(::MongoMapper)
 module Geocoder
   extend self
 
+  # This method can be used to change some functional aspects, like,
+  # the geocoding service provider, or the units of calculations.
+  # Please see {include:Configuration}
+  def configure(&block)
+    if block_given?
+      module_eval(&block)
+    else
+      Configuration.instance
+    end
+  end
+
   ##
   # Search for information about an address or a set of coordinates.
   #
@@ -70,6 +81,10 @@ module Geocoder
 
   private # -----------------------------------------------------------------
 
+  def config # :nodoc
+    Configuration.instance
+  end
+
   ##
   # Get a Lookup object (which communicates with the remote geocoding API).
   # Takes a search query and returns an IP or street address Lookup
@@ -131,3 +146,4 @@ if defined?(Rails)
   require "geocoder/railtie"
   Geocoder::Railtie.insert
 end
+
diff --git a/lib/geocoder/calculations.rb b/lib/geocoder/calculations.rb
index 06beb8df7bcf0c7099c305a13b9d62cf20b08f70..a01b89158c6072919ee1d61fb3001915c443d692 100644
--- a/lib/geocoder/calculations.rb
+++ b/lib/geocoder/calculations.rb
@@ -27,7 +27,8 @@ module Geocoder
     ##
     # Distance spanned by one degree of latitude in the given units.
     #
-    def latitude_degree_distance(units = :mi)
+    def latitude_degree_distance(units = nil)
+      units ||= Geocoder::Configuration.units
       2 * Math::PI * earth_radius(units) / 360
     end
 
@@ -35,7 +36,8 @@ module Geocoder
     # Distance spanned by one degree of longitude at the given latitude.
     # This ranges from around 69 miles at the equator to zero at the poles.
     #
-    def longitude_degree_distance(latitude, units = :mi)
+    def longitude_degree_distance(latitude, units = nil)
+      units ||= Geocoder::Configuration.units
       latitude_degree_distance(units) * Math.cos(to_radians(latitude))
     end
 
@@ -52,12 +54,13 @@ module Geocoder
     #
     # The options hash supports:
     #
-    # * <tt>:units</tt> - <tt>:mi</tt> (default) or <tt>:km</tt>
+    # * <tt>:units</tt> - <tt>:mi</tt> or <tt>:km</tt>
+    #   See Geocoder::Configuration to know how configure default units.
     #
     def distance_between(point1, point2, options = {})
 
       # set default options
-      options[:units] ||= :mi
+      options[:units] ||= Geocoder::Configuration.units
 
       # convert to coordinate arrays
       point1 = extract_coordinates(point1)
@@ -84,17 +87,18 @@ module Geocoder
     # See Geocoder::Calculations.distance_between for
     # ways of specifying the points. Also accepts an options hash:
     #
-    # * <tt>:method</tt> - <tt>:linear</tt> (default) or <tt>:spherical</tt>;
+    # * <tt>:method</tt> - <tt>:linear</tt> or <tt>:spherical</tt>;
     #   the spherical method is "correct" in that it returns the shortest path
-    #   (one along a great circle) but the linear method is the default as it
-    #   is less confusing (returns due east or west when given two points with
-    #   the same latitude)
+    #   (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.
     #
     # 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] = :linear unless options[:method] == :spherical
 
       # convert to coordinate arrays
@@ -180,12 +184,13 @@ module Geocoder
     # See Geocoder::Calculations.distance_between for
     # ways of specifying the point. Also accepts an options hash:
     #
-    # * <tt>:units</tt> - <tt>:mi</tt> (default) or <tt>:km</tt>
+    # * <tt>:units</tt> - <tt>:mi</tt> or <tt>:km</tt>.
+    #   See Geocoder::Configuration to know how configure default units.
     #
     def bounding_box(point, radius, options = {})
       lat,lon = extract_coordinates(point)
       radius  = radius.to_f
-      units   = options[:units] || :mi
+      units   = options[:units] || Geocoder::Configuration.units
       [
         lat - (radius / latitude_degree_distance(units)),
         lon - (radius / longitude_degree_distance(lat, units)),
@@ -222,11 +227,13 @@ module Geocoder
       end
     end
 
-    def distance_to_radians(distance, units = :mi)
+    def distance_to_radians(distance, units = nil)
+      units ||= Geocoder::Configuration.units
       distance.to_f / earth_radius(units)
     end
 
-    def radians_to_distance(radians, units = :mi)
+    def radians_to_distance(radians, units = nil)
+      units ||= Geocoder::Configuration.units
       radians * earth_radius(units)
     end
 
@@ -245,9 +252,11 @@ module Geocoder
     end
 
     ##
-    # Radius of the Earth in the given units (:mi or :km). Default is :mi.
+    # Radius of the Earth in the given units (:mi or :km).
+    # See Geocoder::Configuration to know how configure default units.
     #
-    def earth_radius(units = :mi)
+    def earth_radius(units = nil)
+      units ||= Geocoder::Configuration.units
       units == :km ? EARTH_RADIUS : to_miles(EARTH_RADIUS)
     end
 
@@ -295,3 +304,4 @@ module Geocoder
     end
   end
 end
+
diff --git a/lib/geocoder/configuration.rb b/lib/geocoder/configuration.rb
index a534a39eb89089d6cf4f21678f67777937ae2742..b0d4d6a5dc09e3737d7fddc266b7d8c3d3fb9fef 100644
--- a/lib/geocoder/configuration.rb
+++ b/lib/geocoder/configuration.rb
@@ -1,61 +1,114 @@
-module Geocoder
-  class Configuration
+require 'singleton'
 
-    def self.options_and_defaults
-      [
-        # geocoding service timeout (secs)
-        [:timeout, 3],
-
-        # name of geocoding service (symbol)
-        [:lookup, :google],
+module Geocoder
 
-        # ISO-639 language code
-        [:language, :en],
+  # This class handle the configuration process of Geocoder gem, and can be used
+  # to change some functional aspects, like, the geocoding service provider, or
+  # the units of calculations.
+  #
+  # == Geocoder Configuration
+  #
+  # The configuration of Geocoder can be done in to ways:
+  # @example Using +Geocoder#configure+ method:
+  #
+  #   Geocoder.configure do
+  #     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
+  #     config.always_raise = []
+  #
+  #     # Calculation options
+  #     config.units  = :mi        # :km for kilometers or :mi for miles
+  #     config.method = :linear    # :spherical or :linear
+  #   end
+  #
+  # @example Using +Geocoder::Configuration+ class directly, like in:
+  #
+  #   Geocoder::Configuration.language = 'pt-BR'
+  #
+  # == Notes
+  #
+  # All configurations are optional, the default values were shown in the first
+  # example (with +Geocoder#configure+).
 
-        # use HTTPS for lookup requests? (if supported)
-        [:use_https, false],
-        
-        # optionally supply the headers for the HTTP request, e.g. User-Agent
-        [:request_headers, {}],
+  class Configuration
+    include Singleton
 
-        # HTTP proxy server (user:pass@host:port)
-        [:http_proxy, nil],
+    OPTIONS = [
+      :timeout,
+      :lookup,
+      :language,
+      :http_headers,
+      :use_https,
+      :http_proxy,
+      :https_proxy,
+      :api_key,
+      :cache,
+      :cache_prefix,
+      :always_raise,
+      :units,
+      :distances
+    ]
 
-        # HTTPS proxy server (user:pass@host:port)
-        [:https_proxy, nil],
+    attr_accessor *OPTIONS
 
-        # API key for geocoding service
-        # for Google Premier use a 3-element array: [key, client, channel]
-        [:api_key, nil],
+    def initialize  # :nodoc
+      set_defaults
+    end
 
-        # cache object (must respond to #[], #[]=, and #keys)
-        [:cache, nil],
+    # This method will set the configuration options to the default values
+    def set_defaults
+      @timeout      = 3           # geocoding service timeout (secs)
+      @lookup       = :google     # name of 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
 
-        # prefix (string) to use for all cache keys
-        [:cache_prefix, "geocoder:"],
+      # 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
-        [:always_raise, []]
-      ]
+      # calculation options
+      @units     = :mi     # :mi or :km
+      @distances = :linear # :linear or :spherical
     end
 
-    # define getters and setters for all configuration settings
-    self.options_and_defaults.each do |option, default|
-      class_eval(<<-END, __FILE__, __LINE__ + 1)
-
-        @@#{option} = default unless defined? @@#{option}
-
-        def self.#{option}
-          @@#{option}
-        end
+    # Delegates getters and setters for all configuration settings,
+    # and +set_defaults+ to the singleton instance.
+    instance_eval(OPTIONS.map do |option|
+      o = option.to_s
+      <<-EOS
+      def #{o}
+        instance.#{o}
+      end
 
-        def self.#{option}=(obj)
-          @@#{option} = obj
-        end
+      def #{o}=(value)
+        instance.#{o} = value
+      end
+      EOS
+    end.join("\n\n"))
 
-      END
+    class << self
+      # This method will set the configuration options to the default values
+      def set_defaults
+        instance.set_defaults
+      end
     end
   end
 end
diff --git a/lib/geocoder/lookups/base.rb b/lib/geocoder/lookups/base.rb
index 1d6e164c45bb3267aa467c3416cd62b765847e3d..d24b912a7e50bcd9ba9280f698237f049febb8e3 100644
--- a/lib/geocoder/lookups/base.rb
+++ b/lib/geocoder/lookups/base.rb
@@ -145,7 +145,7 @@ module Geocoder
           unless cache and body = cache[url]
             client = http_client.new(uri.host, uri.port)
             client.use_ssl = true if Geocoder::Configuration.use_https
-            response = client.get(uri.request_uri, Geocoder::Configuration.request_headers)
+            response = client.get(uri.request_uri, Geocoder::Configuration.http_headers)
             body = response.body
             if cache and (200..399).include?(response.code.to_i)
               cache[url] = body
diff --git a/lib/geocoder/models/active_record.rb b/lib/geocoder/models/active_record.rb
index 67a17106accb7e66632091aac450bed5ceb2f699..29bbe5f406d5534ffc674599c28d4c86340f10ce 100644
--- a/lib/geocoder/models/active_record.rb
+++ b/lib/geocoder/models/active_record.rb
@@ -14,7 +14,9 @@ module Geocoder
           :user_address  => address_attr,
           :latitude      => options[:latitude]  || :latitude,
           :longitude     => options[:longitude] || :longitude,
-          :geocode_block => block
+          :geocode_block => block,
+          :units         => options[:units],
+          :method        => options[:method]
         )
       end
 
@@ -27,7 +29,9 @@ module Geocoder
           :fetched_address => options[:address] || :address,
           :latitude        => latitude_attr,
           :longitude       => longitude_attr,
-          :reverse_block   => block
+          :reverse_block   => block,
+          :units         => options[:units],
+          :method        => options[:method]
         )
       end
 
@@ -39,3 +43,4 @@ module Geocoder
     end
   end
 end
+
diff --git a/lib/geocoder/models/base.rb b/lib/geocoder/models/base.rb
index 836233162770542dc063784b4d448c8324792708..34853a5b7af77a6bb1b692d2d053858b7e7784d1 100644
--- a/lib/geocoder/models/base.rb
+++ b/lib/geocoder/models/base.rb
@@ -12,7 +12,9 @@ module Geocoder
         if defined?(@geocoder_options)
           @geocoder_options
         elsif superclass.respond_to?(:geocoder_options)
-          superclass.geocoder_options
+          superclass.geocoder_options || { }
+        else
+          { }
         end
       end
 
@@ -24,7 +26,6 @@ module Geocoder
         fail
       end
 
-
       private # ----------------------------------------------------------------
 
       def geocoder_init(options)
@@ -38,3 +39,4 @@ module Geocoder
     end
   end
 end
+
diff --git a/lib/geocoder/models/mongo_base.rb b/lib/geocoder/models/mongo_base.rb
index 58cad07aacc7b3524b4c2b5dd2834a9972d96e6f..b64443ab9abd237a22e65e7a4221bc884a343342 100644
--- a/lib/geocoder/models/mongo_base.rb
+++ b/lib/geocoder/models/mongo_base.rb
@@ -16,7 +16,9 @@ module Geocoder
           :geocode       => true,
           :user_address  => address_attr,
           :coordinates   => options[:coordinates] || :coordinates,
-          :geocode_block => block
+          :geocode_block => block,
+          :units         => options[:units],
+          :method        => options[:method]
         )
       end
 
@@ -28,7 +30,9 @@ module Geocoder
           :reverse_geocode => true,
           :fetched_address => options[:address] || :address,
           :coordinates     => coordinates_attr,
-          :reverse_block   => block
+          :reverse_block   => block,
+          :units         => options[:units],
+          :method        => options[:method]
         )
       end
 
@@ -36,7 +40,7 @@ module Geocoder
 
       def geocoder_init(options)
         unless geocoder_initialized?
-          @geocoder_options = {}
+          @geocoder_options = { }
           require "geocoder/stores/#{geocoder_file_name}"
           include Geocoder::Store.const_get(geocoder_module_name)
         end
@@ -51,3 +55,4 @@ module Geocoder
     end
   end
 end
+
diff --git a/lib/geocoder/stores/active_record.rb b/lib/geocoder/stores/active_record.rb
index 6701f244e3288bfb2f797fee86c3bb8c241405a5..a10bc2cae016538d0cf5124cd4ae9819261c7117 100644
--- a/lib/geocoder/stores/active_record.rb
+++ b/lib/geocoder/stores/active_record.rb
@@ -75,16 +75,18 @@ module Geocoder::Store
 
       ##
       # Get options hash suitable for passing to ActiveRecord.find to get
-      # records within a radius (in miles) of the given point.
+      # records within a radius (in kilometers) of the given point.
       # Options hash may include:
       #
-      # * +:units+   - <tt>:mi</tt> (default) or <tt>:km</tt>; to be used
+      # * +: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
-      # * +:bearing+ - <tt>:linear</tt> (default) or <tt>:spherical</tt>;
+      #   is added to each found nearby object.
+      #   See Geocoder::Configuration to know how 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
+      #   set to false for no bearing calculation.
+      #   See Geocoder::Configuration to know how configure default method.
       # * +:select+  - string with the SELECT SQL fragment (e.g. “id, name”)
       # * +:order+   - column(s) for ORDER BY SQL clause; default is distance
       # * +:exclude+ - an object to exclude (used by the +nearbys+ method)
@@ -116,7 +118,9 @@ module Geocoder::Store
       def full_near_scope_options(latitude, longitude, radius, options)
         lat_attr = geocoder_options[:latitude]
         lon_attr = geocoder_options[:longitude]
-        options[:bearing] = :linear unless options.include?(:bearing)
+        options[:bearing] ||= (options[:method] ||
+                               geocoder_options[:method] ||
+                               Geocoder::Configuration.distances)
         bearing = case options[:bearing]
         when :linear
           "CAST(" +
@@ -138,7 +142,7 @@ module Geocoder::Store
             ")) + 360 " +
           "AS decimal) % 360"
         end
-
+        options[:units] ||= (geocoder_options[:units] || Geocoder::Configuration.units)
         distance = full_distance_from_sql(latitude, longitude, options)
         conditions = ["#{distance} <= ?", radius]
         default_near_scope_options(latitude, longitude, radius, options).merge(
@@ -191,7 +195,11 @@ module Geocoder::Store
       def approx_near_scope_options(latitude, longitude, radius, options)
         lat_attr = geocoder_options[:latitude]
         lon_attr = geocoder_options[:longitude]
-        options[:bearing] = :linear unless options.include?(:bearing)
+        unless options.include?(:bearing)
+          options[:bearing] = (options[:method] || \
+                               geocoder_options[:method] || \
+                               Geocoder::Configuration.distances)
+        end
         if options[:bearing]
           bearing = "CASE " +
             "WHEN (#{lat_attr} >= #{latitude} AND #{lon_attr} >= #{longitude}) THEN  45.0 " +
@@ -204,6 +212,7 @@ module Geocoder::Store
         end
 
         distance = approx_distance_from_sql(latitude, longitude, options)
+        options[:units] ||= (geocoder_options[:units] || Geocoder::Configuration.units)
 
         b = Geocoder::Calculations.bounding_box([latitude, longitude], radius, options)
         conditions = [
@@ -297,3 +306,4 @@ module Geocoder::Store
     alias_method :fetch_address, :reverse_geocode
   end
 end
+
diff --git a/lib/geocoder/stores/base.rb b/lib/geocoder/stores/base.rb
index f7726c645153738566b4d8468e2e506720a6704b..a9d578f4f55ab521aa0074342f912bb694d9477f 100644
--- a/lib/geocoder/stores/base.rb
+++ b/lib/geocoder/stores/base.rb
@@ -20,9 +20,10 @@ module Geocoder
       # Calculate the distance from the object to an arbitrary point.
       # See Geocoder::Calculations.distance_between for ways of specifying
       # the point. Also takes a symbol specifying the units
-      # (:mi or :km; default is :mi).
+      # (:mi or :km; can be specified in Geocoder configuration).
       #
-      def distance_to(point, units = :mi)
+      def distance_to(point, units = nil)
+        units ||= self.class.geocoder_options[:units]
         return nil unless geocoded?
         Geocoder::Calculations.distance_between(
           to_coordinates, point, :units => units)
@@ -36,6 +37,7 @@ module Geocoder
       # ways of specifying the point.
       #
       def bearing_to(point, options = {})
+        options[:method] ||= self.class.geocoder_options[:method]
         return nil unless geocoded?
         Geocoder::Calculations.bearing_between(
           to_coordinates, point, options)
@@ -47,6 +49,7 @@ module Geocoder
       # ways of specifying the point.
       #
       def bearing_from(point, options = {})
+        options[:method] ||= self.class.geocoder_options[:method]
         return nil unless geocoded?
         Geocoder::Calculations.bearing_between(
           point, to_coordinates, options)
@@ -78,7 +81,6 @@ module Geocoder
         fail
       end
 
-
       private # --------------------------------------------------------------
 
       ##
@@ -114,3 +116,4 @@ module Geocoder
     end
   end
 end
+
diff --git a/lib/geocoder/stores/mongo_base.rb b/lib/geocoder/stores/mongo_base.rb
index 29054e486f25987c56cfa2dcda63d91c71bd6fc5..13ae12fd02dc5eebd08378a14b28a0440e958c43 100644
--- a/lib/geocoder/stores/mongo_base.rb
+++ b/lib/geocoder/stores/mongo_base.rb
@@ -20,6 +20,7 @@ module Geocoder::Store
 
           radius  = args.size > 0 ? args.shift : 20
           options = args.size > 0 ? args.shift : {}
+          options[:units] ||= geocoder_options[:units]
 
           # Use BSON::OrderedHash if Ruby's hashes are unordered.
           # Conditions must be in order required by indexes (see mongo gem).
@@ -30,7 +31,7 @@ module Geocoder::Store
           conds[field] = empty.clone
           conds[field]["$nearSphere"]  = coords.reverse
           conds[field]["$maxDistance"] = \
-            Geocoder::Calculations.distance_to_radians(radius, options[:units] || :mi)
+            Geocoder::Calculations.distance_to_radians(radius, options[:units])
 
           if obj = options[:exclude]
             conds[:_id.ne] = obj.id
@@ -81,3 +82,4 @@ module Geocoder::Store
     end
   end
 end
+
diff --git a/test/calculations_test.rb b/test/calculations_test.rb
index 74816e20be8d84ae50394c718029dcfeb06382b7..b1451dd4b6ea3b9bef8343b4ddc4d05e6d25604c 100644
--- a/test/calculations_test.rb
+++ b/test/calculations_test.rb
@@ -2,7 +2,12 @@
 require 'test_helper'
 
 class CalculationsTest < Test::Unit::TestCase
-
+  def setup
+    Geocoder.configure do
+      config.units  = :mi
+      config.distances = :linear
+    end
+  end
 
   # --- degree distance ---
 
@@ -174,3 +179,4 @@ class CalculationsTest < Test::Unit::TestCase
     assert_in_delta 2.0 / 3, result.last, 1E-5
   end
 end
+
diff --git a/test/configuration_test.rb b/test/configuration_test.rb
index 4c4e668186218874e10611f24cd2f899f667ab79..0b03814374677971dea88ebf3a0c51887feadb73 100644
--- a/test/configuration_test.rb
+++ b/test/configuration_test.rb
@@ -2,6 +2,9 @@
 require 'test_helper'
 
 class ConfigurationTest < Test::Unit::TestCase
+  def setup
+    Geocoder::Configuration.set_defaults
+  end
 
   def test_exception_raised_on_bad_lookup_config
     Geocoder::Configuration.lookup = :stoopid
@@ -10,4 +13,91 @@ class ConfigurationTest < Test::Unit::TestCase
     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
+
+    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
+  end
+
+  # --- Geocoder#configure distances configuration ---
+  def test_geocoder_configuration
+    # DSL
+    Geocoder.configure do
+      config.units  = :mi
+      config.distances = :linear
+    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
+  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]
+    assert_equal :spherical, Landmark.geocoder_options[:method]
+
+    v = Landmark.new(*landmark_params(:msg))
+    v.latitude  = 0
+    v.longitude = 0
+    assert_equal 111, v.distance_to([0,1]).round
+    v.latitude  = 40.750354
+    v.longitude = -73.993371
+    assert_equal 136, v.bearing_from([50,-85]).round
+  end
+
+  def test_configuration_chain
+    v = Landmark.new(*landmark_params(:msg))
+    v.latitude  = 0
+    v.longitude = 0
+
+    # method option > global configuration
+    Geocoder.configure.units  = :km
+    assert_equal 69, v.distance_to([0,1], :mi).round
+
+    # per-model configuration > global configuration
+    Landmark.reverse_geocoded_by :latitude, :longitude, :method => :spherical, :units => :mi
+    assert_equal 69, v.distance_to([0,1]).round
+
+    # method option > per-model configuration
+    assert_equal 111, v.distance_to([0,1], :km).round
+  end
 end
diff --git a/test/custom_block_test.rb b/test/custom_block_test.rb
index 8fab62e819aa6ff05a1b706e185ab7aba92008fc..0f4789d163dc80ab40016016571848f623525499 100644
--- a/test/custom_block_test.rb
+++ b/test/custom_block_test.rb
@@ -29,3 +29,4 @@ class CustomBlockTest < Test::Unit::TestCase
     assert_nil e.address
   end
 end
+
diff --git a/test/mongoid_test.rb b/test/mongoid_test.rb
index 2703f4f91209391fa7d7c6f2df5a9fb71281efc3..29c015ecbf40b6dd10c5197730570513de92ba27 100644
--- a/test/mongoid_test.rb
+++ b/test/mongoid_test.rb
@@ -19,4 +19,15 @@ class MongoidTest < Test::Unit::TestCase
     p = Place.near(location)
     assert_equal p.selector[:location]['$nearSphere'], location.reverse
   end
+
+  def test_model_configuration
+    p = Place.new(*venue_params(:msg))
+    p.location = [0, 0]
+
+    Place.geocoded_by :address, :coordinates => :location, :units => :km
+    assert_equal 111, p.distance_to([0,1]).round
+
+    Place.geocoded_by :address, :coordinates => :location, :units => :mi
+    assert_equal 69, p.distance_to([0,1]).round
+  end
 end
diff --git a/test/test_helper.rb b/test/test_helper.rb
index 2a863274c2147c245931702e445e01b7bc1ff6b3..f0c1dbfec8bcbdf097527335dbf8f450ed04a650 100644
--- a/test/test_helper.rb
+++ b/test/test_helper.rb
@@ -272,3 +272,4 @@ class Test::Unit::TestCase
     all_lookups - [:freegeoip]
   end
 end
+