diff --git a/includes/menu.inc b/includes/menu.inc
index 2be0903..1d9dbed 100644
--- a/includes/menu.inc
+++ b/includes/menu.inc
@@ -391,14 +391,24 @@ function menu_get_ancestors($parts) {
  *   A path argument array, used to replace integer values in $data; an integer
  *   value N in $data will be replaced by value $map[N]. Typically, the $map
  *   array is generated from a call to the arg() function.
+ * @param $item
+ *   A menu router or menu link item.
+ *   Contains all data to dynamically load a corresponding object (entity).
+ *   $item['access'] may be set to FALSE, when the object cannot be loaded.
  *
  * @return
  *   The unserialized $data array, with path arguments replaced.
  */
-function menu_unserialize($data, $map) {
+function menu_unserialize($data, $map, &$item) {
   if ($data = unserialize($data)) {
     foreach ($data as $k => $v) {
       if (is_int($v)) {
+        // Load the object for the given id.
+        if (!empty($item['load_functions']) && !_menu_load_objects($item, $map)) {
+          // An error occurred loading an object.
+          $item['access'] = FALSE;
+          // return FALSE;
+        }
         $data[$k] = isset($map[$v]) ? $map[$v] : '';
       }
     }
@@ -470,15 +480,14 @@ function menu_get_item($path = NULL, $router_item = NULL) {
       drupal_alter('menu_get_item', $router_item, $path, $original_map);
 
       $map = _menu_translate($router_item, $original_map);
-      $router_item['original_map'] = $original_map;
       if ($map === FALSE) {
         $router_items[$path] = FALSE;
         return FALSE;
       }
       if ($router_item['access']) {
         $router_item['map'] = $map;
-        $router_item['page_arguments'] = array_merge(menu_unserialize($router_item['page_arguments'], $map), array_slice($map, $router_item['number_parts']));
-        $router_item['theme_arguments'] = array_merge(menu_unserialize($router_item['theme_arguments'], $map), array_slice($map, $router_item['number_parts']));
+        $router_item['page_arguments'] = array_merge(menu_unserialize($router_item['page_arguments'], $map, $router_item), array_slice($map, $router_item['number_parts']));
+        $router_item['theme_arguments'] = array_merge(menu_unserialize($router_item['theme_arguments'], $map, $router_item), array_slice($map, $router_item['number_parts']));
       }
     }
     $router_items[$path] = $router_item;
@@ -557,6 +566,12 @@ function _menu_load_objects(&$item, &$map) {
     if (!is_array($load_functions)) {
       $load_functions = unserialize($load_functions);
     }
+    // If the object is loaded before, don't load it again.
+    if (isset($item['_object_map'])) {
+      $map = $item['_object_map'];
+      return TRUE;
+    }
+
     $path_map = $map;
     foreach ($load_functions as $index => $function) {
       if ($function) {
@@ -603,6 +618,8 @@ function _menu_load_objects(&$item, &$map) {
     }
     $item['load_functions'] = $load_functions;
   }
+
+  $item['_object_map'] = $map;
   return TRUE;
 }
 
@@ -618,6 +635,11 @@ function _menu_load_objects(&$item, &$map) {
  *   $item['access'] becomes TRUE if the item is accessible, FALSE otherwise.
  */
 function _menu_check_access(&$item, $map) {
+  // menu_tree_check_access() may set this ahead of time for links to nodes.
+  if (isset($item['access'])) {
+    return;
+  }
+
   $item['access'] = FALSE;
   // Determine access callback, which will decide whether or not the current
   // user has access to this path.
@@ -627,7 +649,7 @@ function _menu_check_access(&$item, $map) {
     $item['access'] = (bool) $callback;
   }
   else {
-    $arguments = menu_unserialize($item['access_arguments'], $map);
+    $arguments = menu_unserialize($item['access_arguments'], $map, $item);
     // As call_user_func_array is quite slow and user_access is a very common
     // callback, it is worth making a special case for it.
     if ($callback == 'user_access') {
@@ -690,15 +712,30 @@ function _menu_item_localize(&$item, $map, $link_translate = FALSE) {
         $item['title'] = t($item['title']);
       }
       else {
-        $item['title'] = t($item['title'], menu_unserialize($item['title_arguments'], $map));
+        $item['title'] = t($item['title'], menu_unserialize($item['title_arguments'], $map, $item));
       }
     }
     elseif ($callback && function_exists($callback)) {
       if (empty($item['title_arguments'])) {
         $item['title'] = $callback($item['title']);
       }
+      elseif (0 == count(unserialize($item['title_arguments']))) {
+        $item['title'] = $callback($item['title']);
+      }
       else {
-        $item['title'] = call_user_func_array($callback, menu_unserialize($item['title_arguments'], $map));
+        // @TODO: this needs still some tweaking: 
+        //        - field_ui_menu_title() hase 3 cases. 1 still generates errors (after cache flush);
+        //        - node_type_page_title() is working;
+        //        - taxonomy_term_is_page() is working;
+        // Check analog functionality for 'page_arguments' and 'access_arguments'
+        $arguments = menu_unserialize($item['title_arguments'], $map, $item);
+//        $item['title'] = (count($arguments) == 1) ? $callback($arguments[0]) : call_user_func_array($callback, $arguments);
+        if ((count($arguments) == 1) && !empty($arguments[0])) {
+    	      $item['title'] = $callback($arguments[0]);
+        }
+        else {
+          $item['title'] = call_user_func_array($callback, $arguments);
+        }
       }
       // Avoid calling check_plain again on l() function.
       if ($callback == 'check_plain') {
@@ -736,7 +773,8 @@ function _menu_item_localize(&$item, $map, $link_translate = FALSE) {
  * to the language required to generate the current page.
  *
  * @param $router_item
- *   A menu router item
+ *   A menu router item.
+ *   The 'original_map' is attached to this item.
  * @param $map
  *   An array of path arguments (ex: array('node', '5'))
  * @param $to_arg
@@ -751,6 +789,9 @@ function _menu_item_localize(&$item, $map, $link_translate = FALSE) {
  *   a non-existent node) then this function returns FALSE.
  */
 function _menu_translate(&$router_item, $map, $to_arg = FALSE) {
+  // items can be generated from several sources. Save the path in this common function.
+  $router_item['original_map'] = $map;
+
   if ($to_arg && !empty($router_item['to_arg_functions'])) {
     // Fill in missing path elements, such as the current uid.
     _menu_link_map_translate($map, $router_item['to_arg_functions']);
@@ -758,11 +799,6 @@ function _menu_translate(&$router_item, $map, $to_arg = FALSE) {
   // The $path_map saves the pieces of the path as strings, while elements in
   // $map may be replaced with loaded objects.
   $path_map = $map;
-  if (!empty($router_item['load_functions']) && !_menu_load_objects($router_item, $map)) {
-    // An error occurred loading an object.
-    $router_item['access'] = FALSE;
-    return FALSE;
-  }
 
   // Generate the link path for the page request or local tasks.
   $link_map = explode('/', $router_item['path']);
@@ -917,15 +953,9 @@ function _menu_link_translate(&$item, $translate = FALSE) {
       $item['access'] = FALSE;
       return FALSE;
     }
-    // menu_tree_check_access() may set this ahead of time for links to nodes.
-    if (!isset($item['access'])) {
-      if (!empty($item['load_functions']) && !_menu_load_objects($item, $map)) {
-        // An error occurred loading an object.
-        $item['access'] = FALSE;
-        return FALSE;
-      }
-      _menu_check_access($item, $map);
-    }
+    $item['original_map'] = $map;
+    _menu_check_access($item, $map);
+
     // For performance, don't localize a link the user can't access.
     if ($item['access']) {
       _menu_item_localize($item, $map, TRUE);
@@ -971,7 +1001,10 @@ function _menu_link_translate(&$item, $translate = FALSE) {
 function menu_get_object($type = 'node', $position = 1, $path = NULL) {
   $router_item = menu_get_item($path);
   if (isset($router_item['load_functions'][$position]) && !empty($router_item['map'][$position]) && $router_item['load_functions'][$position] == $type . '_load') {
-    return $router_item['map'][$position];
+    $map = $router_item['map'];
+    if (_menu_load_objects($router_item, $map)) {
+      return $map[$position];
+    }
   }
 }
 
