diff --git sites/all/modules/xmlsitemap/xmlsitemap.module sites/all/modules/xmlsitemap/xmlsitemap.module
index a015eea..4dc882b 100644
--- sites/all/modules/xmlsitemap/xmlsitemap.module
+++ sites/all/modules/xmlsitemap/xmlsitemap.module
@@ -6,6 +6,7 @@
  * Creates a site map compatible with the sitemaps.org schema.
  */
 
+define('SITEMAPS_DIR', 'sitemaps');
 /**
  * @addtogroup xmlsitemap
  * @{
@@ -19,6 +20,14 @@
  * Implementation of hook_cron().
  */
 function xmlsitemap_cron() {
+  if (variable_get('xmlsitemap_update', FALSE)) {
+    _xmlsitemap_update();
+  }
+  
+  if (variable_get('xmlsitemap_rebuild', FALSE) || 
+       (time() - variable_get('xmlsitemap_last_successfully_rebuild', 0) > variable_get('xmlsitemap_rebuild_interval', 86400))) {
+    _xmlsitemap_rebuild();
+  }
   if (variable_get('xmlsitemap_cron_submit', FALSE) && variable_get('xmlsitemap_changed', FALSE)) {
     _xmlsitemap_ping();
   }
@@ -165,8 +174,13 @@ function xmlsitemap_menu() {
     'access arguments' => $access_content,
     'type' => MENU_CALLBACK,
   );
-  $chunk_size = variable_get('xmlsitemap_chunk_size', 50000);
-  $link_count = _xmlsitemap_link_count();
+
+  // we get the chunk_size and link_count fron db
+  // they are stored/updated on every _xmlsitemap_rebuild
+  // so when user adds/deletes content or modifies the xmlsitemap settings
+  // the number of sitemaps served won't be affected on a menu_rebuild
+  $chunk_size = variable_get('xmlsitemap_current_chunk_size', variable_get('xmlsitemap_chunk_size', 50000));
+  $link_count = variable_get('xmlsitemap_current_link_count', _xmlsitemap_link_count());
   if ($link_count / $chunk_size > 1) {
     for ($chunk = 0; $chunk < $link_count / $chunk_size; ++$chunk) {
       $items["sitemap$chunk.xml"] = array(
@@ -193,15 +207,14 @@ function xmlsitemap_menu() {
  *  If not set and there is more than one chunk, display the site map index.
  */
 function xmlsitemap_output($chunk = NULL) {
-  if (variable_get('xmlsitemap_update', FALSE)) {
-    _xmlsitemap_update();
-  }
-  drupal_set_header('Content-type: text/xml; charset=utf-8');
-  $chunk_size = variable_get('xmlsitemap_chunk_size', 50000);
+  $headers = array('Content-type: text/xml; charset=utf-8');
+
+  $chunk_size = variable_get('xmlsitemap_current_chunk_size', 50000);
   if (isset($chunk)) {
-    $link_count = _xmlsitemap_link_count();
+    $link_count = variable_get('xmlsitemap_current_link_count', 0);
     if ($chunk < $link_count / $chunk_size) {
-      _xmlsitemap_output_chunk($chunk);
+      // if file cannot be read file_transfer "outputs" drupal_not_found
+      file_transfer(_xmlsitemap_file_get_path($chunk), $headers);
     }
     else {
       drupal_not_found();
@@ -209,13 +222,17 @@ function xmlsitemap_output($chunk = NULL) {
   }
   else {
     if ($link_count > $chunk_size) {
-      _xmlsitemap_output_index();
+      file_transfer(_xmlsitemap_file_get_path(), $headers);
     }
     else {
-      _xmlsitemap_output_chunk();
+      file_transfer(_xmlsitemap_file_get_path($chunk), $headers);
     }
   }
-  drupal_page_footer();
+  //if we write out to a file we don't need this anymore
+  //drupal_page_footer();
+  
+  //but we need this, right ?
+  module_invoke_all('exit');
   exit;
 }
 
@@ -263,6 +280,28 @@ function xmlsitemap_settings_engines_submit($form, &$form_state) {
  * Menu callback; return the site map settings form.
  */
 function xmlsitemap_settings_sitemap() {
+  $form['xmlsitemap_dir_path'] = array(
+    '#type' => 'textfield',
+    '#title' => t('Where to cache the sitemaps'),
+    '#default_value' => variable_get('xmlsitemap_dir_path', file_directory_path() . '/' . SITEMAPS_DIR),
+    '#size' => 60,
+    '#maxlength' => 150,
+    '#description' => t('This is the directory where the sitemaps will be cached. When, for example, one accesses http://yoursite.com/sitemap.xml then drupal will serve the file from within this directory.'),
+    '#weight' => -2,
+  );
+
+  foreach (array(1800, 3600, 7200, 10800, 21600, 43200, 86400, 172800, 259200, 604800) as $interval) {
+    $options[$interval] = t('Every') . ' ' . format_interval($interval, 1);
+  }
+  $form['xmlsitemap_rebuild_interval'] = array(
+    '#type' => 'select',
+    '#title' => t('How often should the sitemap be regenerated'),
+    '#description' => t('You have to run cron at least as often as this setting here.'),
+    '#options' => $options,
+    '#default_value' => variable_get('xmlsitemap_rebuild_interval', 86400),
+    '#weight' => -2,
+  );
+  
   $form['xmlsitemap_chunk_size'] = array(
     '#type' => 'textfield',
     '#title' => t('Chunk size'),
@@ -272,6 +311,15 @@ function xmlsitemap_settings_sitemap() {
     '#description' => t('This is the number of links to include in one site map. Values can range between 1 and 50,000. If the total number of links exceeds the chunk size, multiple site maps will be generated.'),
     '#weight' => -1,
   );
+  $form['xmlsitemap_rebuild_chunks_per_cron'] = array(
+    '#type' => 'textfield',
+    '#title' => t('How many chunks to rebuild per cron run (Not implemented)'),
+    '#default_value' => variable_get('xmlsitemap_rebuild_chunks_per_cron', 0),
+    '#size' => 60,
+    '#maxlength' => 150,
+    '#description' => t('If your site has a lot of links then you should limit the number of sitemap chunks that are rebuilt on cron run. The default value 0 means rebuild all on every cron.'),
+    '#weight' => -1,
+  );
   $form['xmlsitemap_front_page_priority'] = array(
     '#type' => 'select',
     '#title' => t('Front page priority'),
@@ -290,6 +338,9 @@ function xmlsitemap_settings_sitemap() {
  * Validate the site map settings form.
  */
 function xmlsitemap_settings_sitemap_validate($form, &$form_state) {
+  if(!file_check_directory($form_state['values']['xmlsitemap_dir_path'], FILE_CREATE_DIRECTORY)) {
+    form_set_error('xmlsitemap_dir_path', t('Cannot create this directory'));    
+  }
   if ($form_state['values']['xmlsitemap_chunk_size'] > 50000) {
     form_set_error('xmlsitemap_chunk_size', t('The number of links in a site map cannot be higher than 50,000.'));
   }
@@ -343,7 +394,7 @@ function xmlsitemap_tools_update_database_submit($form, &$form_state) {
     }
     $batch['finished'] = $final_callback;
     batch_set($batch);
-
+    
   }
 }
 
@@ -556,21 +607,165 @@ function _xmlsitemap_link_count() {
   return $link_count;
 }
 
+
+function _xmlsitemap_dir_path() {
+  static $dir_path;
+  if(!isset($dir_path)) {
+    $dir_path = variable_get('xmlsitemap_dir_path', file_directory_path() . '/' . SITEMAPS_DIR);
+    if(!file_check_directory($dir_path, FILE_CREATE_DIRECTORY)) {
+      watchdog('xmlsitemap', 'Could not create xmlsitemap directory @dir', array('@dir' => $dir_path), WATCHDOG_ERROR);
+    }
+  }
+  return $dir_path;
+}
+
+function _xmlsitemap_set_rebuild_dir($dir = NULL) {
+  static $xmlsitemap_temp_dir;
+  if(!is_null($dir)) {
+    $xmlsitemap_temp_dir = $dir;
+    // Is FILE_CREATE_DIRECTORY correct here ????
+    if(!file_check_directory($xmlsitemap_temp_dir, FILE_CREATE_DIRECTORY)) {
+      return FALSE;
+    }
+  }
+  return $xmlsitemap_temp_dir;
+}
+
+/**
+ * Get the path to a sitemap chunk
+ * @param $str [optional]
+ *  An integer or string 
+ *  Integer specifies which chunk index of the sitemap to fetch.
+ *  If string is passed then it fetches the sitemap specified by $str
+ */
+function _xmlsitemap_file_get_path($str = NULL) {
+  $sitempaps_dir_path = _xmlsitemap_dir_path();
+  if(!is_null($str)) {
+    if(is_numeric($str)) {
+      return $sitempaps_dir_path . '/sitemap' . $str . '.xml';
+    }
+    else {
+      //$str is the basename of the file
+      return $sitempaps_dir_path . '/' . $str;
+    }
+  }
+  return $sitempaps_dir_path . '/sitemap.xml';
+}
+
 /**
- * Display a chunk of the site map.
+ * Start a rebuild session of the sitemap(s)
+ * This function saves all the sitemap(s) into a temporary directory 
+ * under the sitemaps main directory (eg. sites/default/files/sitemaps/rebuild_TIMESTAMP)
+ * If everything goes as planned it generated the sitemaps and then overwrites the main sitemaps
+ * @return TRUE on success or FALSE on failure
+ */
+function _xmlsitemap_rebuild() {
+  //TODO: take in consideration the values of 
+  // variable_get('xmlsitemap_rebuild_chunks_per_cron', 0)
+  // variable_get('xmlsitemap_rebuild_running', FALSE)
+  if(variable_get('xmlsitemap_rebuild_running', FALSE)) {
+    //watchdog it ?
+  }
+  $error = FALSE;
+  $chunk_size = variable_get('xmlsitemap_chunk_size', 50000);
+  $link_count = _xmlsitemap_link_count();
+  if($link_count) {
+    $rebuild_time = time();
+    
+    // TODO
+    // we can compare the (actual time - this value) with php's maximum execution time so we can see if a 
+    //_xmlsitemap_rebuild call finished unsuccessfully and the flag xmlsitemap_rebuild_running was left TRUE
+    variable_set('xmlsitemap_last_start_rebuild_time', $rebuild_time);
+    variable_set('xmlsitemap_rebuild_running', TRUE);
+    
+    
+    $sitemaps_temp_dir_path = _xmlsitemap_dir_path() . '/rebuild_' . $rebuild_time;  
+    // try to create the temporary directory where the sitemaps will be stored
+    if(!_xmlsitemap_set_rebuild_dir($sitemaps_temp_dir_path)) {
+      watchdog('xmlsitemap', 'Could not create xmlsitemap temporary directory @dir', array('@dir' => $sitemaps_temp_dir_path), WATCHDOG_ERROR);
+      return FALSE;
+    }
+
+    $chunks = $link_count / $chunk_size;
+    if($chunks > 1) {
+      if(!_xmlsitemap_output_index()) {
+        $error = TRUE;
+      }
+      for($i = 0; $i < $chunks; $i++) {
+        if(!_xmlsitemap_output_chunk($i)) {
+          $error = TRUE;
+          break;
+        }
+      }
+    }
+    else {
+      if(!_xmlsitemap_output_chunk($i)) {
+        $error = TRUE;
+      }
+    }
+    
+    if($error) {
+      return !$error;
+    }
+    
+    //TODO: after moving: if there are more sitemaps 
+    //than currently generated in this session then
+    //delete the ones that are in aditional
+  
+    //move the files from the temp directory to the main sitemaps direcotry
+    $xml_files = file_scan_directory($sitemaps_temp_dir_path, "^sitemap[0-9]*\.xml$");
+    foreach($xml_files as $sitemap_file) {
+      if(!file_move($sitemap_file->filename, _xmlsitemap_file_get_path($sitemap_file->basename), FILE_EXISTS_REPLACE)) {
+        $error = TRUE;
+        break;
+      }
+    }
+  
+    _xmlsitemap_recursive_delete($sitemaps_temp_dir_path);
+  
+    variable_set('xmlsitemap_rebuild_running', FALSE);
+    //everything went oki => delete this value
+    variable_del('xmlsitemap_last_start_rebuild_time');
+  }
+  variable_set('xmlsitemap_current_chunk_size', $chunk_size);
+  variable_set('xmlsitemap_current_link_count', $link_count);
+  variable_set('xmlsitemap_rebuild', FALSE);
+  variable_set('xmlsitemap_last_successfully_rebuild', time());
+  menu_rebuild();
+  return !$error;
+}
+
+/**
+ * Write a chunk of the site map.
  * @param $chunk
- *  An integer specifying which chunk of the site map to display.
+ *  An integer specifying which chunk of the site map to write.
  */
 function _xmlsitemap_output_chunk($chunk = 0) {
-  print '<?xml version="1.0" encoding="UTF-8"?>'."\n";
-  print '<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"'."\n";
-  print '  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"'."\n";
-  print '  xsi:schemaLocation="http://www.sitemaps.org/schemas/sitemap/0.9'."\n";
-  print '  http://www.sitemaps.org/schemas/sitemap/0.9/sitemap.xsd">'."\n";
+  $sitempaps_dir_path = _xmlsitemap_set_rebuild_dir();
+  //if chunk is 0 then we output for sitemap.xml
+  $basename = 'sitemap' . $chunk . '.xml';
+  $sitemap_path = $sitempaps_dir_path . '/' . $basename;
+  
+  // from file_save_data
+  $temp = file_directory_temp();
+  // On Windows, tempnam() requires an absolute path, so we use realpath().
+  $file = tempnam(realpath($temp), 'file');
+  if (!$fp = fopen($file, 'wb')) {
+    watchdog('xmlsitemap', 'Could not create @file', array('@file' => $file), WATCHDOG_ERROR);
+    return FALSE;
+  }
+  fwrite($fp,   
+    '<?xml version="1.0" encoding="UTF-8"?>'."\n" .
+    '<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"'."\n" .
+    '  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"'."\n" .
+    '  xsi:schemaLocation="http://www.sitemaps.org/schemas/sitemap/0.9'."\n" .
+    '  http://www.sitemaps.org/schemas/sitemap/0.9/sitemap.xsd">'."\n"
+  );
   $chunk_size = variable_get('xmlsitemap_chunk_size', 50000);
   $start = $chunk * $chunk_size;
   $links = db_query_range("SELECT * FROM {xmlsitemap} ORDER BY lastmod DESC, changefreq, priority DESC, loc", $start , $chunk_size);
   while ($link = db_fetch_object($links)) {
+    $output = "";
     if ($link->module && function_exists($link->module .'_url')) {
       $function = $link->module .'_url';
       $url = $function($link->loc, $link->type);
@@ -578,36 +773,62 @@ function _xmlsitemap_output_chunk($chunk = 0) {
     else {
       $url = url($link->loc, array('absolute' => TRUE));
     }
-    print '  <url>'."\n";
-    print '    <loc>'. check_url($url) .'</loc>'."\n";
+    
+    $output .= '  <url>'."\n";
+    $output .= '    <loc>'. check_url($url) .'</loc>'."\n";
     if ($link->lastmod != 0) {
-      print '    <lastmod>'. gmdate('Y-m-d\TH:i:s+00:00', $link->lastmod) .'</lastmod>'."\n";
+      $output .= '    <lastmod>'. gmdate('Y-m-d\TH:i:s+00:00', $link->lastmod) .'</lastmod>'."\n";
     }
     if ($link->changefreq != 0) {
-      print '    <changefreq>'. xmlsitemap_frequency($link->changefreq) .'</changefreq>'."\n";
+      $output .= '    <changefreq>'. xmlsitemap_frequency($link->changefreq) .'</changefreq>'."\n";
     }
     if ($link->priority >= 0 && $link->priority <= 1) {
-      print '    <priority>'. number_format($link->priority, 1) .'</priority>'."\n";
+      $output .= '    <priority>'. number_format($link->priority, 1) .'</priority>'."\n";
     }
-    print '  </url>'."\n";
+    $output .= '  </url>'."\n";
+    
+    fwrite($fp, $output);
   }
-  print '</urlset>';
+  fwrite($fp, '</urlset>');
+  fclose($fp);
+
+  if (!file_move($file, $sitemap_path, FILE_EXISTS_REPLACE)) {
+    watchdog('xmlsitemap', 'Could not move @file to @newfile', array('@file' => $file, '@newfile' => $sitemap_path), WATCHDOG_ERROR);
+    return FALSE;
+  }
+  
+  return TRUE;
 }
 
 /**
  * Generate the site map index.
  */
 function _xmlsitemap_output_index() {
-  print '<?xml version="1.0" encoding="UTF-8"?>'."\n";
-  print '<sitemapindex xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"'."\n";
-  print '  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"'."\n";
-  print '  xsi:schemaLocation="http://www.sitemaps.org/schemas/sitemap/0.9'."\n";
-  print '  http://www.sitemaps.org/schemas/sitemap/0.9/siteindex.xsd">'."\n";
+  $sitempaps_dir_path = _xmlsitemap_set_rebuild_dir();
+  $sitemap_path = $sitempaps_dir_path . '/sitemap.xml';
+  
+  //taken from file_save_data
+  $temp = file_directory_temp();
+  // On Windows, tempnam() requires an absolute path, so we use realpath().
+  $file = tempnam(realpath($temp), 'file');
+  if (!$fp = fopen($file, 'wb')) {
+    watchdog('xmlsitemap', 'Could not create @file', array('@file' => $file), WATCHDOG_ERROR);
+    return 0;
+  }
+  fwrite($fp,   
+    '<?xml version="1.0" encoding="UTF-8"?>'."\n" .
+    '<sitemapindex xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"'."\n" .
+    '  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"'."\n" .
+    '  xsi:schemaLocation="http://www.sitemaps.org/schemas/sitemap/0.9'."\n" .
+    '  http://www.sitemaps.org/schemas/sitemap/0.9/siteindex.xsd">'."\n"
+  );
+  
   $chunk_size = variable_get('xmlsitemap_chunk_size', 50000);
   $link_count = _xmlsitemap_link_count();
   for ($chunk = 0; $chunk < $link_count / $chunk_size; ++$chunk) {
-    print '  <sitemap>'."\n";
-    print '    <loc>'. xmlsitemap_url("sitemap$chunk.xml", NULL, NULL, NULL, TRUE) .'</loc>'."\n";
+    $output = "";
+    $output .= '  <sitemap>'."\n";
+    $output .= '    <loc>'. xmlsitemap_url("sitemap$chunk.xml", NULL, NULL, NULL, TRUE) .'</loc>'."\n";
     if ($chunk < $link_count / $chunk_size) {
       $from = $chunk * $chunk_size;
       if (!empty($chunk_size)) {
@@ -615,13 +836,21 @@ function _xmlsitemap_output_index() {
           ORDER BY lastmod DESC, loc",$from, $chunk_size)
         );
         if ($lastmod !== FALSE) {
-          print '    <lastmod>'. gmdate('Y-m-d\TH:i:s+00:00', $lastmod) .'</lastmod>'."\n";
+          $output .= '    <lastmod>'. gmdate('Y-m-d\TH:i:s+00:00', $lastmod) .'</lastmod>'."\n";
         }
       }
     }
-    print '  </sitemap>'."\n";
+    $output .= '  </sitemap>'."\n";
+    
+    fwrite($fp, $output);
+  }
+  fwrite($fp, '</sitemapindex>');
+
+  if (!file_move($file, $sitemap_path, FILE_EXISTS_REPLACE)) {
+    watchdog('xmlsitemap', 'Could not move @file to @newfile', array('@file' => $file, '@newfile' => $sitemap_path), WATCHDOG_ERROR);
+    return FALSE;
   }
-  print '</sitemapindex>';
+  return TRUE;
 }
 
 /**
@@ -651,11 +880,45 @@ function _xmlsitemap_update() {
   db_query("DELETE FROM {xmlsitemap}");
   db_query("INSERT INTO {xmlsitemap} (loc, lastmod, changefreq, priority) VALUES ('%s', %d, %d, %f)", xmlsitemap_url(NULL, NULL, NULL, NULL, TRUE),time() - 1, 1, variable_get('xmlsitemap_front_page_priority', 1));
   module_invoke_all('xmlsitemap_links');
-  menu_rebuild();
-  db_query("DELETE FROM {cache_page} WHERE cid LIKE '%%sitemap%%.xml'");
+  //menu rebuild is called from _xmlsitemap_rebuild now
+  //menu_rebuild();
+  //i think we don't need this statement anymore
+  //db_query("DELETE FROM {cache_page} WHERE cid LIKE '%%sitemap%%.xml'");
   variable_set('xmlsitemap_update', FALSE);
 }
 
 /**
+ * Taken from imagecache module
+ * Recursively delete all files and folders in the specified filepath, then
+ * delete the containing folder.
+ *
+ * Note that this only deletes visible files with write permission.
+ *
+ * @param string $path
+ *   A filepath relative to file_directory_path.
+ */
+function _xmlsitemap_recursive_delete($path) {
+  if (is_file($path) || is_link($path)) {
+    unlink($path);
+  }
+  elseif (is_dir($path)) {
+    $d = dir($path);
+    while (($entry = $d->read()) !== false) {
+      if ($entry == '.' || $entry == '..') continue;
+      $entry_path = $path .'/'. $entry;
+      _imagecache_recursive_delete($entry_path);
+    }
+    $d->close();
+    rmdir($path);
+  }
+  else {
+    watchdog('xmlsitemap', 'Unknown file type(%path) stat: %stat ',
+              array('%path' => $path,  '%stat' => print_r(stat($path),1)), WATCHDOG_ERROR);
+  }
+
+}
+
+
+/**
  * @} End of "addtogroup xmlsitemap".
  */
