diff --git a/lib/geocoder/configuration.rb b/lib/geocoder/configuration.rb
index 4128a01ee57e786cb3792c0eaa771dd72fbce285..8a53e9817572d9f159368f5779b3d22d05c45baf 100644
--- a/lib/geocoder/configuration.rb
+++ b/lib/geocoder/configuration.rb
@@ -38,6 +38,14 @@ module Geocoder
     data
   end
 
+  ##
+  # Merge the given hash into a lookup's existing configuration.
+  #
+  def self.merge_into_lookup_config(lookup_name, options)
+    base = Geocoder.config[lookup_name]
+    Geocoder.configure(lookup_name => base.merge(options))
+  end
+
   class Configuration
     include Singleton
 
diff --git a/lib/geocoder/lookups/esri.rb b/lib/geocoder/lookups/esri.rb
index 2c599b05d42a1103b759888a38cdf17515cee846..a8afb0a210a862e78dba8e75cfa043b9de2a02f2 100644
--- a/lib/geocoder/lookups/esri.rb
+++ b/lib/geocoder/lookups/esri.rb
@@ -65,7 +65,7 @@ module Geocoder::Lookup
     end
 
     def save_token!(token_instance)
-      Geocoder.configure(:esri => Geocoder.config[:esri].merge({:token => token_instance}))
+      Geocoder.merge_into_lookup_config(:esri, token: token_instance)
     end
   end
 end
diff --git a/test/unit/configuration_test.rb b/test/unit/configuration_test.rb
index 527a57e7bf674f75c539c29bccb85c91caba8790..df8aed91cb54742366c5358178438ecd40b44686 100644
--- a/test/unit/configuration_test.rb
+++ b/test/unit/configuration_test.rb
@@ -51,4 +51,23 @@ class ConfigurationTest < GeocoderTestCase
     # method option > per-model configuration
     assert_equal 111, v.distance_to([0,1], :km).round
   end
+
+  def test_merge_into_lookup_config
+    base = {
+      timeout: 5,
+      api_key: "xxx"
+    }
+    new = {
+      timeout: 10,
+      units: :km,
+    }
+    merged = {
+      timeout: 10, # overwritten
+      units: :km, # added
+      api_key: "xxx" # preserved
+    }
+    Geocoder.configure(google: base)
+    Geocoder.merge_into_lookup_config(:google, new)
+    assert_equal merged, Geocoder.config[:google]
+  end
 end