Index: includes/menu.inc
===================================================================
RCS file: /cvs/drupal/drupal/includes/menu.inc,v
retrieving revision 1.325
diff -u -p -r1.325 menu.inc
--- includes/menu.inc	24 May 2009 17:39:30 -0000	1.325
+++ includes/menu.inc	26 May 2009 11:38:24 -0000
@@ -2243,6 +2243,38 @@ function menu_link_save(&$item) {
 }
 
 /**
+ * Save a custom menu.
+ *
+ * @param $menu
+ *   An array representing a custom menu item.
+ *   - menu_name      The machine readable name.
+ *   - title          The human readable name
+ *   - description    Optioanl; The custom menu description.
+ */
+function menu_custom_save($menu = array()) {
+  $menu += array('description' => '');
+  $menus = menu_get_menus();
+  if (empty($menus[$menu['menu_name']])) {
+    db_insert('menu_custom')
+      ->fields(array(
+        'menu_name' => $menu['menu_name'],
+        'title' => $menu['title'],
+        'description' => $menu['description'],
+      ))
+      ->execute();
+  }
+  else {
+    db_update('menu_custom')
+      ->fields(array(
+        'title' => $menu['title'],
+        'description' => $menu['description'],
+      ))
+      ->condition('menu_name', $menu['menu_name'])
+      ->execute();    
+  }
+}
+
+/**
  * Helper function to clear the page and block caches at most twice per page load.
  */
 function _menu_clear_page_cache() {
Index: modules/menu/menu.admin.inc
===================================================================
RCS file: /cvs/drupal/drupal/modules/menu/menu.admin.inc,v
retrieving revision 1.48
diff -u -p -r1.48 menu.admin.inc
--- modules/menu/menu.admin.inc	24 May 2009 17:39:32 -0000	1.48
+++ modules/menu/menu.admin.inc	26 May 2009 11:38:25 -0000
@@ -574,22 +574,10 @@ function menu_edit_menu_submit($form, &$
     ->fetchField();
 
     menu_link_save($link);
-    db_insert('menu_custom')
-      ->fields(array(
-        'menu_name' => $menu['menu_name'],
-        'title' => $menu['title'],
-        'description' => $menu['description'],
-      ))
-      ->execute();
+    menu_custom_save(array('menu_name' => $menu['menu_name'], 'title' => $menu['title'], 'description' => $menu['description']));
   }
   else {
-    db_update('menu_custom')
-      ->fields(array(
-        'title' => $menu['title'],
-        'description' => $menu['description'],
-      ))
-      ->condition('menu_name', $menu['menu_name'])
-      ->execute();
+    menu_custom_save(array('menu_name' => $menu['menu_name'], 'title' => $menu['title'], 'description' => $menu['description']));
     $result = db_query("SELECT mlid FROM {menu_links} WHERE link_path = :path", array(':path' => $path . $menu['menu_name']), array('fetch' => PDO::FETCH_ASSOC));
     foreach ($result as $m) {
       $link = menu_link_load($m['mlid']);
Index: modules/menu/menu.test
===================================================================
RCS file: /cvs/drupal/drupal/modules/menu/menu.test,v
retrieving revision 1.15
diff -u -p -r1.15 menu.test
--- modules/menu/menu.test	24 May 2009 17:39:32 -0000	1.15
+++ modules/menu/menu.test	26 May 2009 11:38:26 -0000
@@ -87,6 +87,31 @@ class MenuTestCase extends DrupalWebTest
     $this->menu = $this->addCustomMenu();
     $this->doMenuTests($this->menu['menu_name']);
     $this->addInvalidMenuLink($this->menu['menu_name']);
+    $this->addCustomMenuApi();
+  }
+  
+   /**
+   * Add custom menu using API.
+   *
+   */
+  function addCustomMenuApi() {
+    // Add a new custom menu.
+    $menu = array(
+      'menu_name' => 'menu-api-test',
+      'title' => 'Menu API title',
+      'description' => 'Description text',
+    );
+    menu_custom_save($menu);
+    
+    // Assert the menu.
+    $this->drupalGet('admin/build/menu-customize/menu-api-test/edit');
+    $this->assertText('Menu API title', t('Custom menu was added.'));
+    
+    // Edit the menu.
+    $menu['title'] = 'Changed title';
+    menu_custom_save($menu);
+    $this->drupalGet('admin/build/menu-customize/menu-api-test/edit');
+    $this->assertText('Changed title', t('Custom menu was edited.'));    
   }
 
   /**
