diff --git a/geoip.module b/geoip.module
index 01790f3..2620f02 100644
--- a/geoip.module
+++ b/geoip.module
@@ -11,7 +11,7 @@
  * @return array
  */
 function geoip_menu() {
-  $items['admin/settings/geoip'] = array(
+  $items['admin/config/system/geoip'] = array(
     'title' => 'GeoIP',
     'description' => 'Configure the path to the GeoIP database.',
     'page callback' => 'drupal_get_form',
diff --git a/geoip.values.inc b/geoip.values.inc
index 3540d04..9df0c20 100644
--- a/geoip.values.inc
+++ b/geoip.values.inc
@@ -14,254 +14,16 @@
  * @return array
  */
 function _geoip_country_values() {
-  return array(
-    'A1' => "Anonymous Proxy",
-    'A2' => "Satellite Provider",
-    'AD' => "Andorra",
-    'AE' => "United Arab Emirates",
-    'AF' => "Afghanistan",
-    'AG' => "Antigua and Barbuda",
-    'AI' => "Anguilla",
-    'AL' => "Albania",
-    'AM' => "Armenia",
-    'AN' => "Netherlands Antilles",
-    'AO' => "Angola",
-    'AP' => "Asia/Pacific Region",
-    'AQ' => "Antarctica",
-    'AR' => "Argentina",
-    'AS' => "American Samoa",
-    'AT' => "Austria",
-    'AU' => "Australia",
-    'AW' => "Aruba",
-    'AX' => "Aland Islands",
-    'AZ' => "Azerbaijan",
-    'BA' => "Bosnia and Herzegovina",
-    'BB' => "Barbados",
-    'BD' => "Bangladesh",
-    'BE' => "Belgium",
-    'BF' => "Burkina Faso",
-    'BG' => "Bulgaria",
-    'BH' => "Bahrain",
-    'BI' => "Burundi",
-    'BJ' => "Benin",
-    'BM' => "Bermuda",
-    'BN' => "Brunei Darussalam",
-    'BO' => "Bolivia",
-    'BR' => "Brazil",
-    'BS' => "Bahamas",
-    'BT' => "Bhutan",
-    'BV' => "Bouvet Island",
-    'BW' => "Botswana",
-    'BY' => "Belarus",
-    'BZ' => "Belize",
-    'CA' => "Canada",
-    'CC' => "Cocos (Keeling) Islands",
-    'CD' => "Congo, The Democratic Republic of the",
-    'CF' => "Central African Republic",
-    'CG' => "Congo",
-    'CH' => "Switzerland",
-    'CI' => "Cote d'Ivoire",
-    'CK' => "Cook Islands",
-    'CL' => "Chile",
-    'CM' => "Cameroon",
-    'CN' => "China",
-    'CO' => "Colombia",
-    'CR' => "Costa Rica",
-    'CU' => "Cuba",
-    'CV' => "Cape Verde",
-    'CX' => "Christmas Island",
-    'CY' => "Cyprus",
-    'CZ' => "Czech Republic",
-    'DE' => "Germany",
-    'DJ' => "Djibouti",
-    'DK' => "Denmark",
-    'DM' => "Dominica",
-    'DO' => "Dominican Republic",
-    'DZ' => "Algeria",
-    'EC' => "Ecuador",
-    'EE' => "Estonia",
-    'EG' => "Egypt",
-    'EH' => "Western Sahara",
-    'ER' => "Eritrea",
-    'ES' => "Spain",
-    'ET' => "Ethiopia",
-    'EU' => "Europe",
-    'FI' => "Finland",
-    'FJ' => "Fiji",
-    'FK' => "Falkland Islands (Malvinas)",
-    'FM' => "Micronesia, Federated States of",
-    'FO' => "Faroe Islands",
-    'FR' => "France",
-    'GA' => "Gabon",
-    'GB' => "United Kingdom",
-    'GD' => "Grenada",
-    'GE' => "Georgia",
-    'GF' => "French Guiana",
-    'GG' => "Guernsey",
-    'GH' => "Ghana",
-    'GI' => "Gibraltar",
-    'GL' => "Greenland",
-    'GM' => "Gambia",
-    'GN' => "Guinea",
-    'GP' => "Guadeloupe",
-    'GQ' => "Equatorial Guinea",
-    'GR' => "Greece",
-    'GS' => "South Georgia and the South Sandwich Islands",
-    'GT' => "Guatemala",
-    'GU' => "Guam",
-    'GW' => "Guinea-Bissau",
-    'GY' => "Guyana",
-    'HK' => "Hong Kong",
-    'HM' => "Heard Island and McDonald Islands",
-    'HN' => "Honduras",
-    'HR' => "Croatia",
-    'HT' => "Haiti",
-    'HU' => "Hungary",
-    'ID' => "Indonesia",
-    'IE' => "Ireland",
-    'IL' => "Israel",
-    'IM' => "Isle of Man",
-    'IN' => "India",
-    'IO' => "British Indian Ocean Territory",
-    'IQ' => "Iraq",
-    'IR' => "Iran, Islamic Republic of",
-    'IS' => "Iceland",
-    'IT' => "Italy",
-    'JE' => "Jersey",
-    'JM' => "Jamaica",
-    'JO' => "Jordan",
-    'JP' => "Japan",
-    'KE' => "Kenya",
-    'KG' => "Kyrgyzstan",
-    'KH' => "Cambodia",
-    'KI' => "Kiribati",
-    'KM' => "Comoros",
-    'KN' => "Saint Kitts and Nevis",
-    'KP' => "Korea, Democratic People's Republic of",
-    'KR' => "Korea, Republic of",
-    'KW' => "Kuwait",
-    'KY' => "Cayman Islands",
-    'KZ' => "Kazakhstan",
-    'LA' => "Lao People's Democratic Republic",
-    'LB' => "Lebanon",
-    'LC' => "Saint Lucia",
-    'LI' => "Liechtenstein",
-    'LK' => "Sri Lanka",
-    'LR' => "Liberia",
-    'LS' => "Lesotho",
-    'LT' => "Lithuania",
-    'LU' => "Luxembourg",
-    'LV' => "Latvia",
-    'LY' => "Libyan Arab Jamahiriya",
-    'MA' => "Morocco",
-    'MC' => "Monaco",
-    'MD' => "Moldova, Republic of",
-    'ME' => "Montenegro",
-    'MG' => "Madagascar",
-    'MH' => "Marshall Islands",
-    'MK' => "Macedonia",
-    'ML' => "Mali",
-    'MM' => "Myanmar",
-    'MN' => "Mongolia",
-    'MO' => "Macao",
-    'MP' => "Northern Mariana Islands",
-    'MQ' => "Martinique",
-    'MR' => "Mauritania",
-    'MS' => "Montserrat",
-    'MT' => "Malta",
-    'MU' => "Mauritius",
-    'MV' => "Maldives",
-    'MW' => "Malawi",
-    'MX' => "Mexico",
-    'MY' => "Malaysia",
-    'MZ' => "Mozambique",
-    'NA' => "Namibia",
-    'NC' => "New Caledonia",
-    'NE' => "Niger",
-    'NF' => "Norfolk Island",
-    'NG' => "Nigeria",
-    'NI' => "Nicaragua",
-    'NL' => "Netherlands",
-    'NO' => "Norway",
-    'NP' => "Nepal",
-    'NR' => "Nauru",
-    'NU' => "Niue",
-    'NZ' => "New Zealand",
-    'OM' => "Oman",
-    'PA' => "Panama",
-    'PE' => "Peru",
-    'PF' => "French Polynesia",
-    'PG' => "Papua New Guinea",
-    'PH' => "Philippines",
-    'PK' => "Pakistan",
-    'PL' => "Poland",
-    'PM' => "Saint Pierre and Miquelon",
-    'PN' => "Pitcairn",
-    'PR' => "Puerto Rico",
-    'PS' => "Palestinian Territory",
-    'PT' => "Portugal",
-    'PW' => "Palau",
-    'PY' => "Paraguay",
-    'QA' => "Qatar",
-    'RE' => "Reunion",
-    'RO' => "Romania",
-    'RS' => "Serbia",
-    'RU' => "Russian Federation",
-    'RW' => "Rwanda",
-    'SA' => "Saudi Arabia",
-    'SB' => "Solomon Islands",
-    'SC' => "Seychelles",
-    'SD' => "Sudan",
-    'SE' => "Sweden",
-    'SG' => "Singapore",
-    'SH' => "Saint Helena",
-    'SI' => "Slovenia",
-    'SJ' => "Svalbard and Jan Mayen",
-    'SK' => "Slovakia",
-    'SL' => "Sierra Leone",
-    'SM' => "San Marino",
-    'SN' => "Senegal",
-    'SO' => "Somalia",
-    'SR' => "Suriname",
-    'ST' => "Sao Tome and Principe",
-    'SV' => "El Salvador",
-    'SY' => "Syrian Arab Republic",
-    'SZ' => "Swaziland",
-    'TC' => "Turks and Caicos Islands",
-    'TD' => "Chad",
-    'TF' => "French Southern Territories",
-    'TG' => "Togo",
-    'TH' => "Thailand",
-    'TJ' => "Tajikistan",
-    'TK' => "Tokelau",
-    'TL' => "Timor-Leste",
-    'TM' => "Turkmenistan",
-    'TN' => "Tunisia",
-    'TO' => "Tonga",
-    'TR' => "Turkey",
-    'TT' => "Trinidad and Tobago",
-    'TV' => "Tuvalu",
-    'TW' => "Taiwan",
-    'TZ' => "Tanzania, United Republic of",
-    'UA' => "Ukraine",
-    'UG' => "Uganda",
-    'UM' => "United States Minor Outlying Islands",
-    'US' => "United States",
-    'UY' => "Uruguay",
-    'UZ' => "Uzbekistan",
-    'VA' => "Holy See (Vatican City State)",
-    'VC' => "Saint Vincent and the Grenadines",
-    'VE' => "Venezuela",
-    'VG' => "Virgin Islands, British",
-    'VI' => "Virgin Islands, U.S.",
-    'VN' => "Vietnam",
-    'VU' => "Vanuatu",
-    'WF' => "Wallis and Futuna",
-    'WS' => "Samoa",
-    'YE' => "Yemen",
-    'YT' => "Mayotte",
-    'ZA' => "South Africa",
-    'ZM' => "Zambia",
-    'ZW' => "Zimbabwe",
+  include_once DRUPAL_ROOT . '/includes/locale.inc';
+  $countries = country_get_list();
+
+  // MaxMind specific shortcuts
+  $countries += array(
+    'A1' => t('Anonymous Proxy'),
+    'A2' => t('Satellite Provider'),
+    'AP' => t('Asia/Pacific Region'),
+    'EU' => t('Europe'),
+    'O1' => t('Other Country'),
   );
+  return $countries;
 }
diff --git a/geoip_language/geoip_language.admin.inc b/geoip_language/geoip_language.admin.inc
index 62052b9..58c2a49 100644
--- a/geoip_language/geoip_language.admin.inc
+++ b/geoip_language/geoip_language.admin.inc
@@ -12,23 +12,25 @@
  * @return string
  *  HTML Table
  */
-function geoip_language_settings_overview() {
-  if (variable_get('language_negotiation', LANGUAGE_NEGOTIATION_NONE) != GEOIP_LANGUAGE_NEGOTIATION_PATH) {
-    drupal_set_message(t('The GeoIP settings will have no effect until <em>Language Negotiation</em> is set to <em>Path prefix with GeoIP detection fallback</em> on the <a href="@language-configure">Language configuration page</a>.', array('@language-configure' => url('admin/settings/language/configure'))), 'warning');
-  }
+function theme_geoip_language_mapping_overview($languages) {
 
   $countries = geoip_country_values();
-  $languages = locale_language_list('name', TRUE);
-  $mapping = geoip_language_mappings();
+  $mapping = geoip_language_mappings(TRUE);
+
+  $output = NULL;
 
   $rows = array();
-  foreach ($mapping as $country => $info) {
+  foreach ($mapping as $country => $language) {
     $rows[] = array(
       $country,
       $countries[$country],
-      $info->language,
-      $languages[$info->language],
-      l(t('Delete'), 'admin/settings/language/geoip/delete/'. $country, array('query' => drupal_get_destination())),
+      $language,
+      $languages[$language],
+      l(
+        t('Delete'),
+        'admin/config/regional/language/configure/geoip/delete/' . $country,
+        array('query' => drupal_get_destination())
+      ),
     );
   }
   if (count($rows)) {
@@ -37,13 +39,21 @@ function geoip_language_settings_overview() {
       array('data' => t('Language'), 'colspan' => 2),
       t('Operations'),
     );
-    $output .= theme('table', $header, $rows);
+    $output .= theme_table(
+      array(
+        'header' => $header,
+        'rows' => $rows,
+        'attributes' => array(),
+        'caption' => NULL,
+        'colgroups' => NULL,
+        'sticky' => TRUE,
+        'empty' => t('No GeoIP language mappings defined.'),
+      )
+    );
   }
   else {
     drupal_set_message(t('No GeoIP language mappings defined.'));
   }
-
-  $output .= drupal_get_form('geoip_language_settings_form');
   return $output;
 }
 
@@ -52,9 +62,10 @@ function geoip_language_settings_overview() {
  *
  * @return array
  */
-function geoip_language_settings_form() {
+function geoip_language_form($form, &$form_state) {
   $countries = geoip_country_values();
-  $mapping = geoip_language_mappings();
+  $mapping = geoip_language_mappings(TRUE);
+  $languages = locale_language_list('name', TRUE);
   $options = array();
   foreach ($countries as $key => $value) {
     if (!$mapping[$key]) {
@@ -75,7 +86,7 @@ function geoip_language_settings_form() {
   $form['new']['language'] = array(
     '#type' => 'select',
     '#title' => t('Language'),
-    '#options' => locale_language_list('name', TRUE),
+    '#options' => $languages,
   );
 
   $form['new']['buttons'] = array();
@@ -84,23 +95,31 @@ function geoip_language_settings_form() {
     '#value' => t('Add mapping'),
   );
 
+  $form['set3']['textfiles'] = array(
+    '#type' => 'item',
+    '#markup' => theme('geoip_language_mapping_overview', $languages),
+  );
+
   return $form;
 }
 
 /**
  * FAPI submit handler.
  */
-function geoip_language_settings_form_submit($form, &$form_state) {
-  geoip_language_mapping_create($form_state['values']['country'], $form_state['values']['language']);
+function geoip_language_form_submit($form, &$form_state) {
+  geoip_language_mapping_create(
+    $form_state['values']['country'],
+    $form_state['values']['language']
+  );
 
   $countries = geoip_country_values();
   drupal_set_message(t('GeoIP mapping created for %country.', array('%country' => $countries[$form_state['values']['country']])));
 
-  $form_state['redirect'] = 'admin/settings/language/geoip';
+  $form_state['redirect'] = 'admin/config/regional/language/configure/geoip';
 }
 
 /**
- * Create the confirmmation form for deleting a mapping item.
+ * Create the confirmation form for deleting a mapping item.
  */
 function geoip_admin_delete_mapping(&$form_state, $country) {
   $form['country'] = array(
@@ -108,9 +127,10 @@ function geoip_admin_delete_mapping(&$form_state, $country) {
     '#value' => $country,
   );
 
-  return confirm_form($form,
+  return confirm_form(
+    $form,
     t('Are you sure you want to delete this mapping?'),
-    isset($_GET['destination']) ? $_GET['destination'] : 'admin/settings/language/geoip',
+    isset($_GET['destination']) ? $_GET['destination'] : 'admin/config/regional/language/configure/geoip',
     t('This action cannot be undone.'),
     t('Delete'),
     t('Cancel')
@@ -121,10 +141,11 @@ function geoip_admin_delete_mapping(&$form_state, $country) {
  * Process a confirmed delete request of a mapping item.
  */
 function geoip_admin_delete_mapping_submit($form, &$form_state) {
-  geoip_language_mapping_delete($form_state['values']['country']);
+  $coutry_code = $form_state['values']['country']['build_info']['args'][0];
+  geoip_language_mapping_delete($coutry_code);
 
   $countries = geoip_country_values();
-  drupal_set_message(t('GeoIP mapping deleted for %country.', array('%country' => $countries[$form_state['values']['country']])));
+  drupal_set_message(t('GeoIP mapping deleted for %country.', array('%country' => $countries[$coutry_code])));
 
-  $form_state['redirect'] = 'admin/settings/language/geoip';
-}
\ No newline at end of file
+  $form_state['redirect'] = 'admin/config/regional/language/configure/geoip';
+}
diff --git a/geoip_language/geoip_language.install b/geoip_language/geoip_language.install
index 4dd1814..ddfb7cd 100644
--- a/geoip_language/geoip_language.install
+++ b/geoip_language/geoip_language.install
@@ -36,16 +36,16 @@ function geoip_language_schema() {
 /**
  * Implements hook_disable().
  */
-function geoip_language_install() {
-  drupal_install_schema('geoip_language');
-  // Make sure this module loads before most "normal" modules.  This allows the
-  // language negotiation to happen in hook_init() rather than hook_boot().
-  db_query("UPDATE {system} SET weight = -1 WHERE name = 'geoip_language'");
-}
-
-/**
- * Implementation of hook_uninstall().
- */
-function geoip_language_uninstall() {
-  drupal_uninstall_schema('geoip_language');
+function geoip_language_disable() {
+  $language_negotiation = variable_get('language_negotiation_language', array());
+  if (isset($language_negotiation[GEOIP_LANGUAGE_NEGOTIATION])) {
+    unset($language_negotiation[GEOIP_LANGUAGE_NEGOTIATION]);
+    variable_set('language_negotiation_language', $language_negotiation);
+  }
+  $providers_weight_language = variable_get('locale_language_providers_weight_language', array());
+  if (isset($providers_weight_language[GEOIP_LANGUAGE_NEGOTIATION])) {
+    unset($providers_weight_language[GEOIP_LANGUAGE_NEGOTIATION]);
+    variable_set('locale_language_providers_weight_language', $providers_weight_language);
+  }
+  cache_clear_all('geoip_language_mappings', 'cache');
 }
diff --git a/geoip_language/geoip_language.module b/geoip_language/geoip_language.module
index be07e74..6d109da 100644
--- a/geoip_language/geoip_language.module
+++ b/geoip_language/geoip_language.module
@@ -13,13 +13,20 @@
 define('GEOIP_LANGUAGE_NEGOTIATION_PATH', 8);
 
 /**
+ * Key to recognize this language provider.
+ *
+ * @var string
+ */
+define('GEOIP_LANGUAGE_NEGOTIATION', 'geoip-language-negotiation');
+
+/**
  * Implements hook_help().
  *
  * @return string
  */
 function geoip_language_help($path, $arg) {
   switch ($path) {
-    case 'admin/settings/language/geoip':
+    case 'admin/config/regional/language/configure/geoip':
       $help = t('<p>This page provides an overview of your site\'s IP detection and language negotiation settings. You may configure which language is chosen when each country is detected from the user\'s IP, using the form below. All detectable languages are listed in the <em>Detected country</em> drop-down list, and all installed languages are listed in t the <em>Language</em> drop-down list. If a country is detected but doesn\'t have an entry in this list, the default language will be used.</p>');
       return $help;
   }
@@ -33,18 +40,18 @@ function geoip_language_help($path, $arg) {
 function geoip_language_menu() {
   $items = array();
 
-  $items['admin/settings/language/geoip'] = array(
+  $items['admin/config/regional/language/configure/geoip'] = array(
     'title' => 'GeoIP',
-    'type' => MENU_LOCAL_TASK,
     'weight' => 5,
-    'page callback' => 'geoip_language_settings_overview',
+    'page callback' => 'drupal_get_form',
+    'page arguments' => array('geoip_language_form'),
     'access arguments' => array('administer languages'),
     'file' => 'geoip_language.admin.inc',
   );
-  $items['admin/settings/language/geoip/delete/%'] = array(
+  $items['admin/config/regional/language/configure/geoip/delete/%'] = array(
     'title' => 'Delete GeoIP mapping',
     'page callback' => 'drupal_get_form',
-    'page arguments' => array('geoip_admin_delete_mapping', 5),
+    'page arguments' => array('geoip_admin_delete_mapping', 7),
     'access arguments' => array('administer languages'),
     'type' => MENU_CALLBACK,
     'file' => 'geoip_language.admin.inc',
@@ -58,17 +65,21 @@ function geoip_language_menu() {
  *
  * @return array
  */
-function geoip_language_init() {
-  // Configured presentation language mode.
-  $mode = variable_get('language_negotiation', LANGUAGE_NEGOTIATION_NONE);
-
-  $drush = (function_exists('drush_verify_cli') && drush_verify_cli());
-
-  // Only take action if language negotiation is set to GeoIP and there is more
-  // than 1 enabled language.
-  if (!$drush && ($mode == GEOIP_LANGUAGE_NEGOTIATION_PATH) && ((int)variable_get('language_count', 1) > 1)) {
-    geoip_language_negotiation();
-  }
+function geoip_language_language_negotiation_info() {
+  return array(GEOIP_LANGUAGE_NEGOTIATION => array(
+      'callbacks' => array(
+        'language' => 'language_negotiation_from_geoip',
+        // 'switcher' => 'custom_language_switcher_callback',
+        // 'url_rewrite' => 'custom_language_url_rewrite_callback',
+      ),
+      'file' => drupal_get_path('module', 'geoip_language') . '/geoip_language.module',
+      'weight' => -4,
+      'name' => 'GeoIP',
+      'description' => t('Use the users IP to determine the language'),
+      'config' => 'admin/config/regional/language/configure/geoip',
+      // 'cache' => 0,
+  ),
+  );
 }
 
 /**
@@ -78,76 +89,14 @@ function geoip_language_init() {
  * @return string
  *   Language as ISO 639-1 Code
  */
-function geoip_language_negotiation() {
-  // Get a list of enabled languages.
-  $languages = language_list('enabled');
-  $languages = $languages[1];
-
-  // Get the original q, as it is before path un-aliasing.  This is important
-  // because a path alias which is the same as a language prefix will have been
-  // improperly un-aliased and the language prefix will be lost.
-  $query = array();
-  parse_str($_SERVER['QUERY_STRING'], $query);
-  $q = $query['q'];
-
-  // Mostly copied from language_initialize(). Do a basic path prefix lookup to
-  // determine the language.
-  $args = explode('/', $q);
-  $prefix = array_shift($args);
-  // Search prefix within enabled languages.
-  foreach ($languages as $language) {
-    if (!empty($language->prefix) && $language->prefix == $prefix) {
-      // Set the global language object.
-      $GLOBALS['language'] = $language;
-      // Rebuild $_GET['q'] with the language removed.
-      $_GET['q'] = implode('/', $args);
-      // Re-initialize the path.
-      drupal_init_path();
-      // Make PressFlow happy by only storing the language code if there's an
-      // existing session.
-      if (count($_SESSION)) {
-        $_SESSION['geoip_language'] = $language->language;
-      }
-      return;
-    }
-  }
-
-  // Begin fallbacks. At this point, we know that there is not a valid path
-  // prefix, so we must first determine a language, and then do a redirect to
-  // the current path, in that language.
-
-  global $user;
-  // First check to see if a language was previously determined.
-  if (isset($_SESSION['geoip_language']) && isset($languages[$_SESSION['geoip_language']])) {
-    $language = $languages[$_SESSION['geoip_language']];
-  }
-  // Fallback for user-preferred language.
-  elseif ($user->uid && isset($languages[$user->language])) {
-    $language = $languages[$user->language];
-  }
-  // If all else fails, do a GeoIP lookup and redirect.
-  else {
-    $language = geoip_language_detect_language();
-  }
-
-
-  // Set the global language object.
-  $GLOBALS['language'] = $language;
-
-  global $base_path;
-  // Abort the redirect if bootstrap happened outside of index.php or if the
-  // requested path is inside the files directory
-  if (($_SERVER['SCRIPT_NAME'] != $base_path .'index.php')
-    || (strpos($_GET['q'], file_directory_path()) === 0)
-    || ($_SERVER['REQUEST_METHOD'] == 'POST')) {
-    return;
-  }
-
-  // Now that the language is detected, do an absolute redirect to avoid page
-  // caching in the wrong language.
-  $url = url($_GET['q'], array('language' => $language, 'absolute' => TRUE, 'query' => drupal_query_string_encode($_GET, array('q'))));
-  drupal_goto($url, NULL, NULL, 301);
-  exit();
+function language_negotiation_from_geoip($languages) {
+  // Use the core URL language provider to get a valid language code.
+  include_once DRUPAL_ROOT . '/includes/locale.inc';
+  include_once DRUPAL_ROOT . '/modules/locale/locale.module';
+  include_once dirname(__FILE__) . '/../geoip.module';
+  $langcode = geoip_language_detect_language();
+
+  return $langcode;
 }
 
 /**
@@ -155,33 +104,33 @@ function geoip_language_negotiation() {
  * language_url_rewrite() doesn't add the path prefix for the default language,
  * so we are doing it here.  This lessens the amount of redirection that
  * would occur because of a missing path prefix.
+ *
+ * @TODO Function disabled - looks like this is not necessary anymore in D7
  */
-if (!function_exists('custom_url_rewrite_outbound')) {
-  function custom_url_rewrite_outbound(&$path, &$options, $original_path) {
-    global $language;
-
-    if (variable_get('language_negotiation', LANGUAGE_NEGOTIATION_NONE) == GEOIP_LANGUAGE_NEGOTIATION_PATH
-      && ((int)variable_get('language_count', 1) > 1)) {
-      // Only modify relative (insite) URLs.
-      if (!$options['external']) {
-
-        // Allow links to bypass the language prefixing.  Helpful for simpletest.
-        // Breaking forms as of 2009-06-22
-//        if (isset($options['geoip_language_no_prefix']) && ($options['geoip_language_no_prefix'] === TRUE)) {
-//          return;
+function _geoip_language_url_outbound_alter(&$path, &$options, $original_path) {
+//    global $language;
+//
+//    if (variable_get('language_negotiation', LANGUAGE_NEGOTIATION_NONE) == GEOIP_LANGUAGE_NEGOTIATION_PATH
+//      && ((int) variable_get('language_count', 1) > 1)) {
+//      // Only modify relative (insite) URLs.
+//      if (!$options['external']) {
+//
+//        // Allow links to bypass the language prefixing.  Helpful for simpletest.
+//        // Breaking forms as of 2009-06-22
+////        if (isset($options['geoip_language_no_prefix']) && ($options['geoip_language_no_prefix'] === TRUE)) {
+////          return;
+////        }
+//
+//        // Language can be passed as an option, or we go for current language.
+//        if (!isset($options['language'])) {
+//          $options['language'] = $language;
 //        }
-
-        // Language can be passed as an option, or we go for current language.
-        if (!isset($options['language'])) {
-          $options['language'] = $language;
-        }
-
-        if (!empty($options['language']->prefix)) {
-          $options['prefix'] = $options['language']->prefix .'/';
-        }
-      }
-    }
-  }
+//
+//        if (!empty($options['language']->prefix)) {
+//          $options['prefix'] = $options['language']->prefix . '/';
+//        }
+//      }
+//    }
 }
 
 /**
@@ -202,10 +151,15 @@ function geoip_language_mapping_create($country, $language) {
     'language' => $language,
   );
   drupal_write_record('geoip_language', $data);
-  geoip_language_mappings(TRUE);
 
   $countries = geoip_country_values();
-  watchdog('geoip_language', 'GeoIP mapping created for %country', array('%country' => $countries[$country]));
+  watchdog(
+    'geoip_language',
+    'GeoIP mapping created for %country',
+    array('%country' => $countries[$country])
+  );
+
+  geoip_language_mappings(TRUE);
 
   return $data;
 }
@@ -216,11 +170,21 @@ function geoip_language_mapping_create($country, $language) {
  * @return boolean
  */
 function geoip_language_mapping_delete($country) {
-  db_query('DELETE FROM {geoip_language} WHERE country="%s"', $country);
-  geoip_language_mappings(TRUE);
+  // On error an Exception is thrown
+  db_delete('geoip_language')
+            ->condition('country', $country)
+            ->execute();
 
   $countries = geoip_country_values();
-  watchdog('geoip_language', 'GeoIP mapping deleted for %country', array('%country' => $countries[$country]));
+  watchdog(
+    'geoip_language',
+    'GeoIP mapping deleted for %country',
+    array('%country' => $countries[$country])
+  );
+
+  geoip_language_mappings(TRUE);
+
+  return TRUE;
 }
 
 /**
@@ -233,13 +197,12 @@ function geoip_language_mapping_delete($country) {
  *  Associative array key=countrycode, value= Language as ISO 639-1 Code
  */
 function geoip_language_mappings($reset = FALSE) {
-  static $mapping = NULL;
+  $mapping = drupal_static(__FUNCTION__, NULL);
 
   if ($reset || !isset($mapping)) {
-    $file = file_directory_path() .'/geoip_language.txt';
-    if (file_exists($file)) {
-      $data = unserialize(file_get_contents($file));
-      $mapping = isset($data['geoip']) ? $data['geoip'] : NULL;
+    $data = cache_get(__METHOD__);
+    if ($data != FALSE) {
+      $mapping = isset($data->data['geoip']) ? $data->data['geoip'] : NULL;
     }
 
     // Build the mapping array and cache it to the filesystem.
@@ -249,14 +212,17 @@ function geoip_language_mappings($reset = FALSE) {
         'geoip' => array(),
         'default' => language_default('prefix'),
       );
-      $result = db_query('SELECT g.*, l.prefix FROM {geoip_language} g INNER JOIN {languages} l on g.language = l.language ORDER BY g.country ASC');
-      while ($row = db_fetch_object($result)) {
+      $result = db_query(
+        'SELECT g.*, l.prefix ' .
+        'FROM {geoip_language} g ' .
+        'INNER JOIN {languages} l on g.language = l.language ' .
+        'ORDER BY g.country ASC'
+      );
+      foreach ($result as $row) {
         $mapping[$row->country] = $row->language;
         $data['geoip'][$row->country] = $row;
       }
-
-      // Add default
-      $file = file_save_data(serialize($data), 'geoip_language.txt', FILE_EXISTS_REPLACE);
+      $data = cache_set(__METHOD__, $data);
     }
   }
 
@@ -274,24 +240,17 @@ function geoip_language_detect_language($reset = FALSE) {
   static $geoip_language = NULL;
 
   if ($reset || !isset($geoip_language)) {
-    // Get a list of enabled languages.
-    $languages = language_list('enabled');
-    $languages = $languages[1];
     // Get a list of country->language mappings.
     $mappings = geoip_language_mappings();
     // GeoIP detect the current country.
     $country_code = geoip_country_code();
 
-    // Make sure country_code, the mapping for that country_code, and the enabled
-    // language for that mapping, all exist.
-    if ($country_code && $mappings[$country_code] && $languages[$mappings[$country_code]->language]) {
-      $geoip_language = $languages[$mappings[$country_code]->language];
-    }
-    else {
-      $geoip_language = language_default();
+    // Make sure country_code, the mapping for that country_code, and the
+    // enabled language for that mapping, all exist.
+    if ($country_code && isset($mappings[$country_code])) {
+      $geoip_language = $mappings[$country_code]->language;
     }
   }
-
   return $geoip_language;
 }
 
@@ -304,6 +263,18 @@ function geoip_language_detect_language($reset = FALSE) {
 function geoip_language_flush_caches() {
   // Reload the geoip cache file.
   geoip_language_mappings(TRUE);
-
   return array();
 }
+
+/**
+ * Implements hook_theme().
+ *
+ * @return array()
+ */
+function geoip_language_theme() {
+  return array(
+    'geoip_language_mapping_overview' => array(
+      'arguments' => array('form' => NULL),
+    ),
+  );
+}
diff --git a/geoip_language/geoip_language.test b/geoip_language/geoip_language.test
index 1ce47a4..33d1fc7 100644
--- a/geoip_language/geoip_language.test
+++ b/geoip_language/geoip_language.test
@@ -28,7 +28,7 @@ class geoipLanguageTestCase extends DrupalWebTestCase {
     $this->drupalLogin($this->admin_user);
 
     // Make sure default language has a prefix.
-    $this->drupalPost('admin/settings/language/edit/en', array('prefix' => 'global'), t('Save language'));
+    $this->drupalPost('admin/config/regional/edit/en', array('prefix' => 'global'), t('Save language'));
     // Add and map french/france
     $this->addLanguage('fr');
     geoip_language_mapping_create('FR', 'fr');
@@ -51,13 +51,13 @@ class geoipLanguageTestCase extends DrupalWebTestCase {
    */
   function addLanguage($language_code) {
     // Check to make sure that language has not already been installed.
-    $this->drupalGet('admin/settings/language');
+    $this->drupalGet('admin/config/language');
 
     if (strpos($this->drupalGetContent(), 'enabled[' . $language_code . ']') === FALSE) {
       // Doesn't have language installed so add it.
       $edit = array();
       $edit['langcode'] = $language_code;
-      $this->drupalPost('admin/settings/language/add', $edit, t('Add language'));
+      $this->drupalPost('admin/config/regional/add', $edit, t('Add language'));
 
       $languages = language_list('language', TRUE); // Make sure not using cached version.
       $this->assertTrue(array_key_exists($language_code, $languages), t('%language language was installed successfully.', array('%language' => $languages[$language_code]->name)));
@@ -81,12 +81,12 @@ class geoipLanguageTestCase extends DrupalWebTestCase {
   function testMappingCrud() {
     $mappings = geoip_language_mappings(TRUE);
     $this->assertFalse(array_key_exists('US', $mappings), t('No mapping for US'));
-    $this->drupalPost('admin/settings/language/geoip', array('country' => 'US', 'language' => 'en'), t('Add mapping'), array('language' => $GLOBALS['language']));
+    $this->drupalPost('admin/config/regional/language/configure/geoip', array('country' => 'US', 'language' => 'en'), t('Add mapping'), array('language' => $GLOBALS['language']));
 
     $mappings = geoip_language_mappings(TRUE);
     $this->assertEqual($mappings['US'], 'en', t('Mapping created for US => en'));
 
-    $this->drupalPost('admin/settings/language/geoip/delete/US', array(), t('Delete'));
+    $this->drupalPost('admin/config/regional/language/configure/geoip/delete/US', array(), t('Delete'));
     $mappings = geoip_language_mappings(TRUE);
     $this->assertFalse(array_key_exists('US', $mappings), t('US mapping deleted.'));
   }
diff --git a/lib/geoipcity.inc b/lib/geoipcity.inc
index 08efe52..4e7b397 100644
--- a/lib/geoipcity.inc
+++ b/lib/geoipcity.inc
@@ -67,9 +67,9 @@ class geoipdnsrecord {
 
 function getrecordwithdnsservice($str){
   $record = new geoipdnsrecord;
-  $keyvalue = split(";",$str);
+  $keyvalue = explode(";",$str);
   foreach ($keyvalue as $keyvalue2){
-    list($key,$value) = split("=",$keyvalue2);
+    list($key,$value) = explode("=",$keyvalue2);
     if ($key == "co"){
       $record->country_code = $value;
     }
