 includes/menu.inc           |   20 ++++++++++++++++++++
 modules/menu/menu.admin.inc |   16 ++--------------
 modules/menu/menu.test      |   28 ++++++++++++++++++++++++++++
 3 files changed, 50 insertions(+), 14 deletions(-)


diff --git a/includes/menu.inc b/includes/menu.inc
index a9917dc..493bbb6 100644
--- a/includes/menu.inc
+++ b/includes/menu.inc
@@ -2261,6 +2261,26 @@ function menu_link_save(&$item) {
 }
 
 /**
+ * Save a custom menu.
+ *
+ * @param menu_name
+ *   The machine readable name.
+ * @param $title
+ *   The human readable name.
+ * @param description
+ *   Optional; The custom menu description.
+ */
+function menu_custom_save($menu_name, $title, $description = '') {
+  db_merge('menu_custom')
+    ->key(array('menu_name' => $menu_name))
+    ->fields(array(
+        'title' => $title,
+        'description' => $description,
+    ))
+    ->execute();  
+}
+
+/**
  * Helper function to clear the page and block caches at most twice per page load.
  */
 function _menu_clear_page_cache() {
diff --git a/modules/menu/menu.admin.inc b/modules/menu/menu.admin.inc
index 4640990..2ac5d62 100644
--- a/modules/menu/menu.admin.inc
+++ b/modules/menu/menu.admin.inc
@@ -575,22 +575,10 @@ function menu_edit_menu_submit($form, &$form_state) {
     ->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($menu['menu_name'], $menu['title'], $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($menu['menu_name'], $menu['title'], $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']);
diff --git a/modules/menu/menu.test b/modules/menu/menu.test
index 93639da..22510db 100644
--- a/modules/menu/menu.test
+++ b/modules/menu/menu.test
@@ -87,6 +87,34 @@ class MenuTestCase extends DrupalWebTestCase {
     $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_name = substr(md5($this->randomName(16)), 0, MENU_MAX_MENU_NAME_LENGTH_UI);
+    $title = $this->randomName(16);
+    
+    $menu = array(
+      'menu_name' => $menu_name,
+      'title' => $title,
+      'description' => 'Description text',
+    );
+    menu_custom_save($menu['menu_name'], $menu['title'], $menu['description']);
+    
+    // Assert the menu.
+    $this->drupalGet('admin/structure/menu-customize/' . $menu_name . '/edit');
+    $this->assertText($title, t('Custom menu was added.'));
+    
+    // Edit the menu.
+    $new_title = $this->randomName(16);
+    $menu['title'] = $new_title;
+    menu_custom_save($menu['menu_name'], $menu['title']);
+    $this->drupalGet('admin/structure/menu-customize/' . $menu_name . '/edit');
+    $this->assertText($new_title, t('Custom menu was edited.'));    
   }
 
   /**
