diff --git a/site_map.admin.inc b/site_map.admin.inc
index 40af07c..eeaebbe 100644
--- a/site_map.admin.inc
+++ b/site_map.admin.inc
@@ -38,31 +38,33 @@ function site_map_admin_settings_form() {
     '#default_value' => variable_get('site_map_show_front', 1),
     '#description' => t('When enabled, this option will include the front page in the site map.'),
   );
-  $form['site_map_content']['site_map_show_blogs'] = array(
-    '#type' => 'checkbox',
-    '#title' => t('Show active blog authors'),
-    '#default_value' => variable_get('site_map_show_blogs', 1),
-    '#description' => t('When enabled, this option will show the 10 most active blog authors.'),
-  );
-  $book_options = array();
+  if (module_exists('blog')) {
+    $form['site_map_content']['site_map_show_blogs'] = array(
+      '#type' => 'checkbox',
+      '#title' => t('Show active blog authors'),
+      '#default_value' => variable_get('site_map_show_blogs', 1),
+      '#description' => t('When enabled, this option will show the 10 most active blog authors.'),
+    );
+  }
   if (module_exists('book')) {
+    $book_options = array();
     foreach (book_get_books() as $book) {
-      $book_options[$book['nid']] = $book['title'];
+      $book_options[$book['mlid']] = $book['title'];
     }
+    $form['site_map_content']['site_map_show_books'] = array(
+      '#type' => 'checkboxes',
+      '#title' => t('Books to include in the site map'),
+      '#default_value' => variable_get('site_map_show_books', array()),
+      '#options' => $book_options,
+      '#multiple' => TRUE,
+    );
+    $form['site_map_content']['site_map_books_expanded'] = array(
+      '#type' => 'checkbox',
+      '#title' => t('Show books expanded'),
+      '#default_value' => variable_get('site_map_books_expanded', 1),
+      '#description' => t('When enabled, this option will show all children pages for each book.'),
+    );
   }
-  $form['site_map_content']['site_map_show_books'] = array(
-    '#type' => 'checkboxes',
-    '#title' => t('Books to include in the site map'),
-    '#default_value' => variable_get('site_map_show_books', array()),
-    '#options' => $book_options,
-    '#multiple' => TRUE,
-  );
-//   $form['site_map_content']['site_map_books_expanded'] = array(
-//     '#type' => 'checkbox',
-//     '#title' => t('Show books expanded'),
-//     '#default_value' => variable_get('site_map_books_expanded', 1),
-//     '#description' => t('When enabled, this option will show all children pages for each book.'),
-//   );
 
   $menu_options = array();
   $menu_options = menu_get_menus();
@@ -74,12 +76,14 @@ function site_map_admin_settings_form() {
     '#options' => $menu_options,
     '#multiple' => TRUE,
   );
-  $form['site_map_content']['site_map_show_faq'] = array(
-    '#type' => 'checkbox',
-    '#title' => t('Show FAQ content'),
-    '#default_value' => variable_get('site_map_show_faq', 0),
-    '#description' => t('When enabled, this option will include the content from the FAQ module in the site map.'),
-  );
+  if (module_exists('faq')) {
+    $form['site_map_content']['site_map_show_faq'] = array(
+      '#type' => 'checkbox',
+      '#title' => t('Show FAQ content'),
+      '#default_value' => variable_get('site_map_show_faq', 0),
+      '#description' => t('When enabled, this option will include the content from the FAQ module in the site map.'),
+    );
+  }
   $vocab_options = array();
   if (module_exists('taxonomy')) {
     foreach (taxonomy_get_vocabularies() as $vocabulary) {
diff --git a/site_map.info b/site_map.info
index 6bd2fcd..4e1bf90 100644
--- a/site_map.info
+++ b/site_map.info
@@ -2,8 +2,3 @@ name = Site map
 description = Display a site map.
 core = 7.x
 configure = admin/config/search/sitemap
-
-files[] = site_map.admin.inc
-files[] = site_map.install
-files[] = site_map.module
-files[] = site_map.theme.inc
diff --git a/site_map.module b/site_map.module
index a37a622..4177b2e 100644
--- a/site_map.module
+++ b/site_map.module
@@ -298,19 +298,33 @@ function _site_map_video() {
  */
 function _site_map_books() {
   $output = '';
-  $nids = array_filter(variable_get('site_map_show_books', array()));
+  $book_titles = array();
+  $mlid = array_filter(variable_get('site_map_show_books', array()));
 
-  if (module_exists('book') && !empty($nids)) {
+  if (module_exists('book') && !empty($mlid)) {
+    $books_expanded = variable_get('site_map_books_expanded', 1);
     $title = t('Books');
     $description = '<div class="description">' . t('Books at %sn.', array('%sn' => variable_get('site_name', 'Drupal'))) . '</div>';
 
-    $book_menus = array();
-    foreach ($nids as $nid) {
-      $node = node_load($nid);
-      $tree = menu_tree_all_data($node->book['menu_name']);
-      $data = array_shift($tree);
-      $output .= theme('book_title_link', array('link' => $data['link']));
-      $output .= ($data['below']) ? _site_map_menu_tree_output($data['below']) : '';
+    foreach (book_get_books() as $book_id => $book) {
+      if (in_array($book['mlid'], $mlid)) {
+        // Use menu_tree_all_data to retrieve the expanded tree.
+        $tree = menu_tree_all_data($book['menu_name']);
+        if (module_exists('i18n_menu')) {
+          $tree = i18n_menu_localize_tree($tree, $GLOBALS['language']->language);
+        }
+        if ($books_expanded) {
+          $output .= drupal_render(_site_map_menu_tree_output($tree));
+        }
+        else {
+          $data = array_shift($tree);
+          $book_titles[] = theme('book_title_link', array('link' => $data['link']));
+        }
+      }
+    }
+
+    if (!$books_expanded && !empty($book_titles)) {
+      $output .= theme('item_list', array('items' => $book_titles));
     }
 
     if (!empty($output)) {
@@ -527,10 +541,16 @@ function site_map_taxonomy_term_count_nodes($tid) {
  *
  * Returns a rendered menu tree.
  *
+ * The menu item's LI element is given one of the following classes:
+ * - expanded: The menu item is showing its submenu.
+ * - collapsed: The menu item has a submenu which is not shown.
+ * - leaf: The menu item has no submenu.
+ *
  * @param $tree
  *   A data structure representing the tree as returned from menu_tree_data.
+ *
  * @return
- *   The rendered HTML of that data structure.
+ *   A structured array to be rendered by drupal_render().
  */
 function _site_map_menu_tree_output($tree) {
   $build = array();
@@ -539,11 +559,12 @@ function _site_map_menu_tree_output($tree) {
   // Pull out just the menu links we are going to render so that we
   // get an accurate count for the first/last classes.
   foreach ($tree as $data) {
-    if (!$data['link']['hidden']) {
+    if ($data['link']['access'] && !$data['link']['hidden']) {
       $items[] = $data;
     }
   }
 
+  $router_item = menu_get_item();
   $num_items = count($items);
   foreach ($items as $i => $data) {
     $class = array();
@@ -553,8 +574,10 @@ function _site_map_menu_tree_output($tree) {
     if ($i == $num_items - 1) {
       $class[] = 'last';
     }
-    // Set a class if the link has children.
-    if ($data['below']) {
+    // Set a class for the <li>-tag. Since $data['below'] may contain local
+    // tasks, only set 'expanded' class if the link also has children within
+    // the current menu.
+    if ($data['link']['has_children'] && $data['below']) {
       $class[] = 'expanded';
     }
     elseif ($data['link']['has_children']) {
@@ -566,11 +589,18 @@ function _site_map_menu_tree_output($tree) {
     // Set a class if the link is in the active trail.
     if ($data['link']['in_active_trail']) {
       $class[] = 'active-trail';
-      $data['localized_options']['attributes']['class'][] = 'active-trail';
+      $data['link']['localized_options']['attributes']['class'][] = 'active-trail';
+    }
+    // Normally, l() compares the href of every link with $_GET['q'] and sets
+    // the active class accordingly. But local tasks do not appear in menu
+    // trees, so if the current path is a local task, and this link is its
+    // tab root, then we have to set the class manually.
+    if ($data['link']['href'] == $router_item['tab_root_href'] && $data['link']['href'] != $_GET['q']) {
+      $data['link']['localized_options']['attributes']['class'][] = 'active';
     }
 
     // Allow menu-specific theme overrides.
-    $element['#theme'] = 'site_map_menu_link__' . $data['link']['menu_name'];
+    $element['#theme'] = 'site_map_menu_link__' . strtr($data['link']['menu_name'], '-', '_');
     $element['#attributes']['class'] = $class;
     $element['#title'] = $data['link']['title'];
     $element['#href'] = $data['link']['href'];
@@ -585,7 +615,7 @@ function _site_map_menu_tree_output($tree) {
     $build['#sorted'] = TRUE;
     // Add the theme wrapper for outer markup.
     // Allow menu-specific theme overrides.
-    $build['#theme_wrappers'][] = 'site_map_menu_tree__' . $data['link']['menu_name'];
+    $build['#theme_wrappers'][] = 'site_map_menu_tree__' . strtr($data['link']['menu_name'], '-', '_');
   }
 
   return $build;
diff --git a/site_map.theme.css b/site_map.theme.css
index a71cc45..399cd0d 100644
--- a/site_map.theme.css
+++ b/site_map.theme.css
@@ -11,6 +11,10 @@
   padding-left: 1.5em;
 }
 
+#site-map .site-map-box ul ul {
+  margin: 0;
+}
+
 /* Styles when RSS icons are displayed on the left. */
 #site-map .site-map-rss-left ul {
   padding-left: 0;
