diff --git a/languageinterface.module b/languageinterface.module
index fe42afb..43d8351 100644
--- a/languageinterface.module
+++ b/languageinterface.module
@@ -162,8 +162,14 @@ function get_enabled_languages() {
   return $languages;
 }
 
+/*
+ * Return themed html of the language switching links.
+ */
 function language_link_creation() {
-
+  $path = drupal_is_front_page() ? '<front>' : $_GET['q'];
+  $link_object = language_negotiation_get_switch_links('language', $path);
+  $links = $link_object->links;
+  $current_path = drupal_get_path_alias();
   $customdimensions = variable_get('custom_flag_dimensions', '16x12');
   $customdimensions = explode('x', $customdimensions);
   $flagwidth        = $customdimensions[0];
@@ -174,62 +180,64 @@ function language_link_creation() {
     $flagpath = $defaultflagpath;
   }
   $textoptions      = variable_get('languageinterface_text', 'post');
-  $languages = get_enabled_languages();
   $languagetext = variable_get('tl', '');
-
+  //$languagetext = Array of custom language names from config form
   $tbl = variable_get('tbl', '');
   $tal = variable_get('tal', '');
-  //$tbl = Text before language icon
-  //$tal = Text after language icon
+  //$tbl = Array of text to display before language name, keyed by language
+  //$tal = Array of text to display after language language name, keyed by language
   global $base_url;
-  foreach ($languages as $lang) {
-    $path_array = languagepath($lang);
-    if ($lang == currentlanguage()) {
-      $activeclass = TRUE;
+  foreach ($links as $language_code => $link_array) {
+    /* the locale functions return 'locale-untranslated' if there is no translation for the
+     * current content item.  In that case we want to link back to the current page, but with the
+     * proper language link info set.
+     */
+    if (!is_array($links[$language_code]['attributes']['class']) && 
+        $links[$language_code]['attributes']['class'] == 'locale-untranslated') {
+      $links[$language_code]['href'] = $current_path;
+      $links[$language_code]['attributes']['class'] = array('language-link');
     }
-    else {
-      $activeclass = FALSE;
-    }
-
-    $src = $base_url . '/' . str_replace('*', $lang, $flagpath);
+    /* Get the url of the flag for this language set */
+    $image_src = $base_url . '/' . str_replace('*', $language_code, $flagpath);
+    /* Build the display text for the language from the options chosen on the config page. */
     $text = '';
-
-    $defaulttext = db_query("SELECT native FROM {languages} WHERE language = :lang", array(':lang' => $lang))->fetchField();
-
-    if (!empty($languagetext[$lang])) {
-      $ltext = $languagetext[$lang];
+    if (!empty($languagetext[$language_code])) {
+      $ltext = $languagetext[$language_code];
     }
     else {
-      $ltext = $defaulttext;
+      $ltext = $links[$language_code]['title'];
     }
-
-    if (!empty($tbl[$lang]) && empty($tal[$lang])) {
-      $text = $tbl[$lang] . ' ' . $ltext;
+    if (!empty($tbl[$language_code]) && empty($tal[$language_code])) {
+      $text = $tbl[$language_code] . ' ' . $ltext;
     }
-    if (!empty($tal[$lang]) && empty($tbl[$lang])) {
+    if (!empty($tal[$language_code]) && empty($tbl[$language_code])) {
       $text = $ltext . ' ' . $tal[$lang];
     }
-    if (!empty($tal[$lang]) && !empty($tbl[$lang])) {
-      $text = $tbl[$lang] . ' ' . $ltext . ' ' . $tal[$lang];
+    if (!empty($tal[$language_code]) && !empty($tbl[$language_code])) {
+      $text = $tbl[$language_code] . ' ' . $ltext . ' ' . $tal[$language_code];
     }
-    if (empty($tal[$lang]) && empty($tbl[$lang])) {
+    if (empty($tal[$language_code]) && empty($tbl[$language_code])) {
       $text = $ltext;
     }
-
-    $links[$lang] = $path_array;
-    $links[$lang]['text']       = $text;
-    $links[$lang]['src']        = $src;
-    $links[$lang]['flagheight'] = $flagheight;
-    $links[$lang]['flagwidth']  = $flagwidth;
-    $links[$lang]['position']   = $textoptions;
-    //$links[$lang]['path']       = $path_array['path'];
-    //$links[$lang]['absolute']   = (empty($path_array['absolute']) ? FALSE : $path_array['absolute']);
-    //$links[$lang]['query']      = $path_array['query'];
-    $links[$lang]['active']     = $activeclass;
-    //$links[$lang]['language']   = $lang;
+    /* Replace the title with the customized display text and then add our custom parameters
+     * to the output pulled from language_negotiation_get_switch_links() Since we are going to
+     * pass the title text in HTML to l() it won't be run through checkplain() so we need to 
+     * do that to the user supplied text.
+     */
+    $links[$language_code]['title'] = check_plain($text);
+    $links[$language_code]['image_src']  = $image_src;
+    $links[$language_code]['flagheight'] = $flagheight;
+    $links[$language_code]['flagwidth']  = $flagwidth;
+    $links[$language_code]['position']   = $textoptions;
   }
-  //End foreach.
-  return theme('languageswitcher', $links);
+  /* Prep for theming */
+  $class = "language-interface-{$link_object->provider}";
+      $variables = array(
+        'links' => $links,
+        'attributes' => array('class' => array($class)),
+      );
+/*   drupal_debug($links,"Modified links array" ); */
+  return theme('languageswitcher', $variables);
 }
 
 /**
@@ -243,58 +251,87 @@ function languageinterface_theme() {
   );
 }
 /**
- * Create a themable language switcher
+ * Adaptation of core theme_links()
  */
-function theme_languageswitcher($links) {
-  /*
-   Here we are manually creating a unordered list due to the fact that
-   theme('item_list') does not assign language specific active classes correctly.
-   The $classes variable is also directly fed to the l() function for the same reason.
-   */
-  $output = '<ul id="language-interface">';
-  foreach ($links as $link) {
-    $classes = array();
-    if ($link['active'] == TRUE) {
-      $classes[] = 'active';
-      $classes[] = $link['language']->language;
-    }
-    else {
-      $classes[] = $link['language']->language;
-    }
-    if ($link['position'] != 'no_image') {
-      $flag = '<img src="' . $link['src'] . '" width = "' . $link['flagwidth'] . '" height = "' . $link['flagheight'] . '" class="' . $classes . '" alt="' . $link['text'] . '" title="' . $link['text'] . '"/>';
-    }
-    if ($link['position'] != 'no_text') {
-      $text = $link['text'];
-    }
-    switch ($link['position']) {
-      case 'pre':
-        $display = $text . ' ' . $flag;
-        break;
+function theme_languageswitcher($variables) {
+  $links = $variables['links'];
+  $attributes = $variables['attributes'];
+  global $language_url;
+  $output = '';
 
-      case 'post';
-      $display = $flag . ' ' . $text;
-      break;
+  if (count($links) > 0) {
+    $output = '';
 
-      case 'no_text';
-      $display = $flag;
-      break;
+    $output .= '<ul' . drupal_attributes($attributes) . '>';
 
-      case 'no_image';
-      $display = $text;
-      break;
-    }
+    $num_links = count($links);
+    $i = 1;
+
+    foreach ($links as $key => $link) {
+      $class = array($key);
+
+      // Add first, last and active classes to the list of links to help out themers.
+      if ($i == 1) {
+        $class[] = 'first';
+      }
+      if ($i == $num_links) {
+        $class[] = 'last';
+      }
+      if (isset($link['href']) && ($link['href'] == $_GET['q'] || ($link['href'] == '<front>' && drupal_is_front_page()))
+           && (empty($link['language']) || $link['language']->language == $language_url->language)) {
+        $class[] = 'active';
+      }
+      $output .= '<li' . drupal_attributes(array('class' => $class)) . '>';
+      /*
+       * Build the link display with or without image as indicated by config value link['position']
+       */
+      if ($link['position'] != 'no_image') {
+        $flag = '<img src="'. $link['image_src'] .'" width = "'. $link['flagwidth'] .'" height = "'. $link['flagheight'] . drupal_attributes(array('class' => $class)) .' alt="'. $link['title'] .'"/>';
+      }
+      if ($link['position'] != 'no_text') {
+        $text = $link['title'];
+      }
+      switch ($link['position']) {
+        case 'pre':
+        $link['title'] = $text.' '.$flag;
+        break;
+          
+        case 'post';
+        $link['title'] = $flag.' '.$text;
+        break;  
+        
+        case 'no_text';
+        $link['title'] = $flag;
+        break;    
+        
+        case 'no_image';
+        $link['title'] = $text;
+        break;    
+      }
+      $link['html'] = TRUE;
+      // end switch
+      if (isset($link['href'])) {
+        // Pass in $link as $options, they share the same keys.
+        $output .= l($link['title'], $link['href'], $link);
+      }
+      elseif (!empty($link['title'])) {
+        // Some links are actually not links, but we wrap these in <span> for adding title and class attributes.
+        if (empty($link['html'])) {
+          $link['title'] = check_plain($link['title']);
+        }
+        $span_attributes = '';
+        if (isset($link['attributes'])) {
+          $span_attributes = drupal_attributes($link['attributes']);
+        }
+        $output .= '<span' . $span_attributes . '>' . $link['title'] . '</span>';
+      }
 
-    // end switch
-    $languages = language_list();
-    $options = $link;
-    //$options ['language'] = $languages[$link['language']];
-    $options['html']                = TRUE;
-    $options['attributes']['class'] = $classes;
+      $i++;
+      $output .= "</li>\n";
+    }
 
-    $output .= '<li class="' . implode(" ", $classes) . '">' . l($display, $link['path'], $options) . '</li>';
+    $output .= '</ul>';
   }
-  $output .= '</ul>';
   return $output;
 }
 
@@ -304,11 +341,10 @@ function languageinterface_options() {
   $flagwidth = $customdimensions[0];
   $flagheight = $customdimensions[1];
 
-  // @todo we don't take into account weights.
-  $langsettings = language_negotiation_get_any(LOCALE_LANGUAGE_NEGOTIATION_URL);
+  $langsettings = language_negotiation_get_any(LOCALE_LANGUAGE_NEGOTIATION_URL) || language_negotiation_get_any(LOCALE_LANGUAGE_NEGOTIATION_SESSION);
   //drupal_set_message(print_r($langsettings,true));
   if ($langsettings != TRUE) {
-    drupal_set_message(t('Language Negotiation URL method must  be enabled and set up for the language switcher to work. <br /> To change this setting please go to:') . ' ' . l('admin/config/regional/language/configure', 'admin/config/regional/language/configure'), $type = 'error', $repeat = FALSE);
+    drupal_set_message(t('Language Negotiation method must be enabled and set to either URL or Session for the language switcher to work. <br /> To change this setting please go to:') . ' ' . l('admin/config/regional/language/configure', 'admin/config/regional/language/configure'), $type = 'error', $repeat = FALSE);
   }
   $form['flag_text_config'] = array(
     '#type' => 'radios',
@@ -488,7 +524,9 @@ function languageinterface_options_submit($form, &$form_state) {
   drupal_set_message(t('Your configuration settings have been saved'), $type = 'status', $repeat = FALSE);
 }
 
-function currentlanguage() {
+/*
+function currentlanguage() {  
   global $language;
   return $language->language;
-}
\ No newline at end of file
+}
+*/
\ No newline at end of file
