diff --git a/lib/geocoder/results/base.rb b/lib/geocoder/results/base.rb
index 10844002e62615ac8f4aec56db4dd0b1908d137c..645e3c2a29e1400f4e25b567aaafed4eba3040de 100644
--- a/lib/geocoder/results/base.rb
+++ b/lib/geocoder/results/base.rb
@@ -32,6 +32,22 @@ module Geocoder
         coordinates[1]
       end
 
+      def state
+        fail
+      end
+
+      def province
+        state
+      end
+
+      def state_code
+        fail
+      end
+
+      def province_code
+        state_code
+      end
+
       def country
         fail
       end
diff --git a/lib/geocoder/results/freegeoip.rb b/lib/geocoder/results/freegeoip.rb
index bb8f1cd2d490259342e25719fcdc6212fee8be46..e2d437e255499b63fc69624b6a5c632c0f4ecf89 100644
--- a/lib/geocoder/results/freegeoip.rb
+++ b/lib/geocoder/results/freegeoip.rb
@@ -4,13 +4,21 @@ module Geocoder::Result
   class Freegeoip < Base
 
     def address(format = :full)
-      "#{city}#{', ' + region_code unless region_code == ''} #{postal_code}, #{country}"
+      "#{city}#{', ' + state_code unless state_code == ''} #{postal_code}, #{country}"
     end
 
     def city
       @data['city']
     end
 
+    def state
+      @data['region_name']
+    end
+
+    def state_code
+      @data['region_code']
+    end
+
     def country
       @data['country_name']
     end
@@ -24,7 +32,7 @@ module Geocoder::Result
     end
 
     def self.response_attributes
-      %w[region_code region_name metrocode zipcode country_name ip]
+      %w[metrocode ip]
     end
 
     response_attributes.each do |a|
diff --git a/lib/geocoder/results/geocoder_ca.rb b/lib/geocoder/results/geocoder_ca.rb
index db52765ede98a6ebbfd2a80686b2c58d803e9524..37d1c09a82c8e92f3602503aa71cb48787098074 100644
--- a/lib/geocoder/results/geocoder_ca.rb
+++ b/lib/geocoder/results/geocoder_ca.rb
@@ -23,7 +23,7 @@ module Geocoder::Result
       @data['prov']
     end
 
-    alias_method :province, :state
+    alias_method :state_code, :state
 
     def postal_code
       @data['postal']
diff --git a/lib/geocoder/results/google.rb b/lib/geocoder/results/google.rb
index 5455004d195e635454934c3cdb311a3849c04254..de99a002ab1ee6d07d15e24910d89f37731ee0f8 100644
--- a/lib/geocoder/results/google.rb
+++ b/lib/geocoder/results/google.rb
@@ -12,8 +12,9 @@ module Geocoder::Result
     end
 
     def city
-      fields = [:locality, :sublocality, :administrative_area_level_3,
-        :administrative_area_level_2, :administrative_area_level_1]
+      fields = [:locality, :sublocality,
+        :administrative_area_level_3,
+        :administrative_area_level_2]
       fields.each do |f|
         if entity = address_components_of_type(f).first
           return entity['long_name']
@@ -21,6 +22,18 @@ module Geocoder::Result
       end
     end
 
+    def state
+      if state = address_components_of_type(:administrative_area_level_1).first
+        state['long_name']
+      end
+    end
+
+    def state_code
+      if state = address_components_of_type(:administrative_area_level_1).first
+        state['short_name']
+      end
+    end
+
     def country
       if country = address_components_of_type(:country).first
         country['long_name']
diff --git a/lib/geocoder/results/yahoo.rb b/lib/geocoder/results/yahoo.rb
index d8e3e0d753900c05c9b1ff5b6611ee5083276729..fab775c545deb39f0826d1223d45d5310802ccef 100644
--- a/lib/geocoder/results/yahoo.rb
+++ b/lib/geocoder/results/yahoo.rb
@@ -11,6 +11,14 @@ module Geocoder::Result
       @data['city']
     end
 
+    def state
+      @data['state']
+    end
+
+    def state_code
+      @data['statecode']
+    end
+
     def country
       @data['country']
     end
@@ -25,8 +33,8 @@ module Geocoder::Result
 
     def self.response_attributes
       %w[quality offsetlat offsetlon radius boundingbox name
-        line1 line2 line3 line4 cross house street xstreet unittype unit postal
-        neighborhood county state countrycode statecode countycode
+        line1 line2 line3 line4 cross house street xstreet unittype unit
+        neighborhood county countycode
         level0 level1 level2 level3 level4 level0code level1code level2code
         timezone areacode uzip hash woeid woetype]
     end
diff --git a/lib/geocoder/results/yandex.rb b/lib/geocoder/results/yandex.rb
index 2227a521a9d88d6263a4561e40dee7b2d152aa24..ca2b3f20abf900d6e4607102fe5dbc4c6342f0b2 100644
--- a/lib/geocoder/results/yandex.rb
+++ b/lib/geocoder/results/yandex.rb
@@ -23,6 +23,14 @@ module Geocoder::Result
       address_details['CountryNameCode']
     end
 
+    def state
+      ""
+    end
+
+    def state_code
+      ""
+    end
+
     def postal_code
       ""
     end
diff --git a/test/geocoder_test.rb b/test/geocoder_test.rb
index 1d18853eb95c29d420d14b4cbe7f2b6eaf31fef2..752a4ec9d05b45c12df3cfaac06cbf244f5b73aa 100644
--- a/test/geocoder_test.rb
+++ b/test/geocoder_test.rb
@@ -427,13 +427,17 @@ class GeocoderTest < Test::Unit::TestCase
 
   def assert_result_has_required_attributes(result)
     m = "Lookup #{Geocoder::Configuration.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"
-    assert result.city.is_a?(String),         m % "city"
-    assert result.postal_code.is_a?(String),  m % "postal_code"
-    assert result.country.is_a?(String),      m % "country"
-    assert result.country_code.is_a?(String), m % "country_code"
-    assert_not_nil result.address,            m % "address"
+    assert result.coordinates.is_a?(Array),    m % "coordinates"
+    assert result.latitude.is_a?(Float),       m % "latitude"
+    assert result.longitude.is_a?(Float),      m % "longitude"
+    assert result.city.is_a?(String),          m % "city"
+    assert result.state.is_a?(String),         m % "state"
+    assert result.state_code.is_a?(String),    m % "state_code"
+    assert result.province.is_a?(String),      m % "province"
+    assert result.province_code.is_a?(String), m % "province_code"
+    assert result.postal_code.is_a?(String),   m % "postal_code"
+    assert result.country.is_a?(String),       m % "country"
+    assert result.country_code.is_a?(String),  m % "country_code"
+    assert_not_nil result.address,             m % "address"
   end
 end