Index: wp-includes/load.php
===================================================================
--- wp-includes/load.php	(revision 12749)
+++ wp-includes/load.php	(working copy)
@@ -383,6 +383,19 @@
 
 	// Load in support for template functions which the theme supports
 	require_if_theme_supports( 'post-thumbnails', ABSPATH . WPINC . '/post-thumbnail-template.php' );
+
+	// Menus init
+	if ( current_theme_supports( 'menus' ) ) {
+		if ( apply_filters('load_default_menu_items', true) )
+			require( ABSPATH . WPINC . '/default-menu-items.php' );
+
+		function _wp_add_menus_menu() {
+			global $submenu;
+			$submenu['themes.php'][8] = array( __( 'Menus' ), 'switch_themes', 'menus.php' );
+			ksort( $submenu['themes.php'], SORT_NUMERIC );
+		}
+		add_action( '_admin_menu', '_wp_add_menus_menu' );
+	}
 }
 
 /**
@@ -444,4 +457,4 @@
 	return false;
 }
 
-?>
\ No newline at end of file
+?>
Index: wp-includes/default-menu-items.php
===================================================================
--- wp-includes/default-menu-items.php	(revision 0)
+++ wp-includes/default-menu-items.php	(revision 0)
@@ -0,0 +1,192 @@
+<?php
+
+/**
+ * Page Menu Item class
+ *
+ * @since 3.0
+ */
+class WP_Menu_Item_Page extends WP_Menu_Item {
+
+	function WP_Menu_Item_Page() {
+		$menu_item_ops = array('classname' => 'menu_item_page', 'description' => __('A WordPress page') );
+		$this->WP_Menu_Item('page', __('Page'), $menu_item_ops);
+	}
+
+	function display( $args, $instance ) {
+		extract( $args );
+
+		$title = $this->get_title($instance);
+
+		// TODO
+	}
+
+	function get_title($instance) {
+		return empty( $instance['title'] ) ? get_the_title($instance['page_id']) : $instance['title'];
+	}
+
+	function update( $new_instance, $old_instance ) {
+		$instance = $old_instance;
+		$instance['title'] = strip_tags($new_instance['title']);
+
+		return $instance;
+	}
+
+	function form( $instance ) {
+		$instance = wp_parse_args( (array) $instance, array( 'page_id' => 0, 'title' => '') );
+
+		$page_id = absint( $instance['page_id'] );
+
+		$title = esc_attr($this->get_title($instance));
+	?>
+		<input id="<?php echo $this->get_field_id('page_id'); ?>" name="<?php echo $this->get_field_name('page_id'); ?>" type="hidden" value="<?php echo $page_id; ?>" />
+		<p><label for="<?php echo $this->get_field_id('title'); ?>"><?php _e('Title:'); ?></label> <input class="widefat" id="<?php echo $this->get_field_id('title'); ?>" name="<?php echo $this->get_field_name('title'); ?>" type="text" value="<?php echo $title; ?>" /></p>
+<?php
+	}
+}
+
+
+/**
+ * Category menu item class
+ *
+ * @since 3.0
+ */
+class WP_Menu_Item_Category extends WP_Menu_Item {
+
+	function WP_Menu_Item_Category() {
+		$menu_item_ops = array( 'classname' => 'menu_item_category', 'description' => __('A WordPress category') );
+		$this->WP_Menu_Item('category', __('Category'), $menu_item_ops);
+	}
+
+	function display( $args, $instance ) {
+		extract( $args );
+
+		$title = $this->get_title($instance);
+
+		// TODO
+	}
+
+	function get_title( $instance ) {
+		return empty( $instance['title'] ) ? get_term($category_id, 'category')->name : $instance['title'];
+	}
+
+	function update( $new_instance, $old_instance ) {
+		$instance = $old_instance;
+		$instance['title'] = strip_tags($new_instance['title']);
+
+		return $instance;
+	}
+
+	function form( $instance ) {
+		$instance = wp_parse_args( (array) $instance, array( 'category_id' => 0, 'title' => '') );
+
+		$category_id = absint( $instance['category_id'] );
+
+		$title = esc_attr($this->get_title($instance));
+	?>
+		<input id="<?php echo $this->get_field_id('category_id'); ?>" name="<?php echo $this->get_field_name('category_id'); ?>" type="hidden" value="<?php echo $category_id; ?>" />
+		<p><label for="<?php echo $this->get_field_id('title'); ?>"><?php _e('Title:'); ?></label> <input class="widefat" id="<?php echo $this->get_field_id('title'); ?>" name="<?php echo $this->get_field_name('title'); ?>" type="text" value="<?php echo $title; ?>" /></p>
+<?php
+	}
+}
+
+
+/**
+ * Home Menu Item class
+ *
+ * @since 3.0
+ */
+class WP_Menu_Item_Home extends WP_Menu_Item {
+
+	function WP_Menu_Item_Home() {
+		$menu_item_ops = array('classname' => 'menu_item_home', 'description' => __('The site homepage') );
+		$this->WP_Menu_Item('home', __('Home'), $menu_item_ops);
+	}
+
+	function display( $args, $instance ) {
+		extract($args);
+
+		$title = $this->get_title($instance);
+
+		echo '<a href="' . home_url() . '">' . $title . '</a>';
+	}
+
+	function get_title( $instance ) {
+		return empty( $instance['title'] ) ? __('Home') : $instance['title'];
+	}
+
+	function update( $new_instance, $old_instance ) {
+		$instance = $old_instance;
+		$instance['title'] = strip_tags($new_instance['title']);
+
+		return $instance;
+	}
+
+	function form( $instance ) {
+		//Defaults
+		$instance = wp_parse_args( (array) $instance, array( 'title' => '' ) );
+		$title = esc_attr($this->get_title($instance));
+	?>
+		<p><label for="<?php echo $this->get_field_id('title'); ?>"><?php _e('Title:'); ?></label> <input class="widefat" id="<?php echo $this->get_field_id('title'); ?>" name="<?php echo $this->get_field_name('title'); ?>" type="text" value="<?php echo $title; ?>" /></p>
+<?php
+	}
+}
+
+/**
+ * Link menu item class
+ *
+ * @since 3.0
+ */
+class WP_Menu_Item_Link extends WP_Menu_Item {
+
+	function WP_Menu_Item_Link() {
+		$menu_item_ops = array('description' => __('An external link') );
+		$this->WP_Menu_Item('link', __('Link'), $menu_item_ops);
+	}
+
+	function display( $args, $instance ) {
+		echo '<a href="' . esc_attr($instance['url']) . '">' . esc_html($instance['title']) . '</a>';
+	}
+
+	function update( $new_instance, $old_instance ) {
+		$instance = $old_instance;
+		$instance['url'] = trim($new_instance['url']);
+		$instance['title'] = strip_tags($new_instance['title']);
+
+		return $instance;
+	}
+
+	function form( $instance ) {
+		//Defaults
+		$instance = wp_parse_args( (array) $instance, array( 'url' => '', 'title' => '' ) );
+		$url = esc_attr( $instance['url'] );
+		$title = esc_attr( $instance['title'] );
+	?>
+		<p><label for="<?php echo $this->get_field_id('url'); ?>"><?php _e('URL:'); ?></label> <input class="widefat" id="<?php echo $this->get_field_id('url'); ?>" name="<?php echo $this->get_field_name('url'); ?>" type="text" value="<?php echo $url; ?>" /></p>
+		<p><label for="<?php echo $this->get_field_id('title'); ?>"><?php _e('Title:'); ?></label> <input class="widefat" id="<?php echo $this->get_field_id('title'); ?>" name="<?php echo $this->get_field_name('title'); ?>" type="text" value="<?php echo $title; ?>" /></p>
+<?php
+	}
+}
+
+
+/**
+ * Register all of the default WordPress menu items on startup.
+ *
+ * Calls 'menu_items_init' action after all of the WordPress menu items have been
+ * registered.
+ *
+ * @since 3.0
+ */
+function wp_menu_items_init() {
+	if ( !is_blog_installed() )
+		return;
+
+	register_menu_item('WP_Menu_Item_Page');
+	register_menu_item('WP_Menu_Item_Category');
+	register_menu_item('WP_Menu_Item_Home');
+	register_menu_item('WP_Menu_Item_Link');
+
+	do_action('menu_items_init');
+}
+
+add_action('init', 'wp_menu_items_init', 1);
+
Index: wp-includes/menus.php
===================================================================
--- wp-includes/menus.php	(revision 0)
+++ wp-includes/menus.php	(revision 0)
@@ -0,0 +1,1085 @@
+<?php
+/**
+ * API for creating dynamic menus without hardcoding functionality into
+ * themes. Includes both internal WordPress routines and theme use routines.
+ *
+ * @link http://codex.wordpress.org/Plugins/WordPress_Menu_Items WordPress Menu_Items
+ * @link http://codex.wordpress.org/Plugins/WordPress_Menu_Items_Api Menu_Items API
+ *
+ * @package WordPress
+ * @subpackage Menus
+ */
+
+/**
+ * This class must be extended for each menu item and WP_Menu_Item::menu_item(), WP_Menu_Item::update()
+ * and WP_Menu_Item::form() need to be over-ridden.
+ *
+ * @package WordPress
+ * @subpackage Menu_Items
+ * @since 3.0
+ */
+class WP_Menu_Item {
+
+	var $id_base;			// Root id for all menu_items of this type.
+	var $name;				// Name for this menu_item type.
+	var $menu_item_options;	// Option array passed to wp_register_menu_item()
+	var $control_options;	// Option array passed to wp_register_menu_item_control()
+
+	var $number = false;	// Unique ID number of the current instance.
+	var $id = false;		// Unique ID string of the current instance (id_base-number)
+	var $updated = false;	// Set true when we update the data after a POST submit - makes sure we don't do it twice.
+
+	// Member functions that you must over-ride.
+
+	/** Echo the menu_item content.
+	 *
+	 * Subclasses should over-ride this function to generate their menu_item code.
+	 *
+	 * @param array $args Display arguments including before_title, after_title, before_menu_item, and after_menu_item.
+	 * @param array $instance The settings for the particular instance of the menu_item
+	 */
+	function output($args, $instance) {
+		die('function WP_Menu_Item::menu_item() must be over-ridden in a sub-class.');
+	}
+
+	/** Update a particular instance.
+	 *
+	 * This function should check that $new_instance is set correctly.
+	 * The newly calculated value of $instance should be returned.
+	 * If "false" is returned, the instance won't be saved/updated.
+	 *
+	 * @param array $new_instance New settings for this instance as input by the user via form()
+	 * @param array $old_instance Old settings for this instance
+	 * @return array Settings to save or bool false to cancel saving
+	 */
+	function update($new_instance, $old_instance) {
+		return $new_instance;
+	}
+
+	/** Echo the settings update form
+	 *
+	 * @param array $instance Current settings
+	 */
+	function form($instance) {
+		echo '<p class="no-options-menu_item">' . __('There are no options for this menu item.') . '</p>';
+		return 'noform';
+	}
+
+	// Functions you'll need to call.
+
+	/**
+	 * PHP4 constructor
+	 */
+	function WP_Menu_Item( $id_base = false, $name, $menu_item_options = array(), $control_options = array() ) {
+		$this->__construct( $id_base, $name, $menu_item_options, $control_options );
+	}
+
+	/**
+	 * PHP5 constructor
+	 *
+	 * @param string $id_base Optional Base ID for the menu_item, lower case,
+	 * if left empty a portion of the menu_item's class name will be used. Has to be unique.
+	 * @param string $name Name for the menu_item displayed on the configuration page.
+	 * @param array $menu_item_options Optional Passed to wp_register_menu_item()
+	 *	 - description: shown on the configuration page
+	 *	 - classname
+	 * @param array $control_options Optional Passed to wp_register_menu_item_control()
+	 *	 - width: required if more than 250px
+	 *	 - height: currently not used but may be needed in the future
+	 */
+	function __construct( $id_base = false, $name, $menu_item_options = array(), $control_options = array() ) {
+		$this->id_base = empty($id_base) ? preg_replace( '/(wp_)?menu_item_/', '', strtolower(get_class($this)) ) : strtolower($id_base);
+		$this->name = $name;
+		$this->option_name = 'menu_item_' . $this->id_base;
+		$this->menu_item_options = wp_parse_args( $menu_item_options, array('classname' => $this->option_name) );
+		$this->control_options = wp_parse_args( $control_options, array('id_base' => $this->id_base) );
+	}
+
+	/**
+	 * Constructs name attributes for use in form() fields
+	 *
+	 * This function should be used in form() methods to create name attributes for fields to be saved by update()
+	 *
+	 * @param string $field_name Field name
+	 * @return string Name attribute for $field_name
+	 */
+	function get_field_name($field_name) {
+		return 'menu-item-' . $this->id_base . '[' . $this->number . '][' . $field_name . ']';
+	}
+
+	/**
+	 * Constructs id attributes for use in form() fields
+	 *
+	 * This function should be used in form() methods to create id attributes for fields to be saved by update()
+	 *
+	 * @param string $field_name Field name
+	 * @return string ID attribute for $field_name
+	 */
+	function get_field_id($field_name) {
+		return 'menu-item-' . $this->id_base . '-' . $this->number . '-' . $field_name;
+	}
+
+	// Private Functions. Don't worry about these.
+
+	function _register() {
+		$settings = $this->get_settings();
+		$empty = true;
+
+		if ( is_array($settings) ) {
+			foreach ( array_keys($settings) as $number ) {
+				if ( is_numeric($number) ) {
+					$this->_set($number);
+					$this->_register_one($number);
+					$empty = false;
+				}
+			}
+		}
+
+		if ( $empty ) {
+			// If there are none, we register the menu_item's existance with a
+			// generic template
+			$this->_set(1);
+			$this->_register_one();
+		}
+	}
+
+	function _set($number) {
+		$this->number = $number;
+		$this->id = $this->id_base . '-' . $number;
+	}
+
+	function _get_display_callback() {
+		return array(&$this, 'display_callback');
+	}
+
+	function _get_update_callback() {
+		return array(&$this, 'update_callback');
+	}
+
+	function _get_form_callback() {
+		return array(&$this, 'form_callback');
+	}
+
+	/** Generate the actual menu_item content.
+	 *	Just finds the instance and calls output().
+	 *	Do NOT over-ride this function. */
+	function display_callback( $args, $menu_item_args = 1 ) {
+		if ( is_numeric($menu_item_args) )
+			$menu_item_args = array( 'number' => $menu_item_args );
+
+		$menu_item_args = wp_parse_args( $menu_item_args, array( 'number' => -1 ) );
+		$this->_set( $menu_item_args['number'] );
+		$instance = $this->get_settings();
+
+		if ( array_key_exists( $this->number, $instance ) ) {
+			$instance = $instance[$this->number];
+			// filters the menu_item's settings, return false to stop displaying the menu_item
+			$instance = apply_filters('menu_item_display_callback', $instance, $this, $args);
+			if ( false !== $instance )
+				$this->output($args, $instance);
+		}
+	}
+
+	/** Deal with changed settings.
+	 *	Do NOT over-ride this function. */
+	function update_callback( $menu_item_args = 1 ) {
+		global $wp_registered_menu_items;
+
+		if ( is_numeric($menu_item_args) )
+			$menu_item_args = array( 'number' => $menu_item_args );
+
+		$menu_item_args = wp_parse_args( $menu_item_args, array( 'number' => -1 ) );
+		$all_instances = $this->get_settings();
+
+		// We need to update the data
+		if ( $this->updated )
+			return;
+
+		$wp_menu_items = wp_get_menu_items();
+
+		if ( isset($_POST['delete_menu_item']) && $_POST['delete_menu_item'] ) {
+			// Delete the settings for this instance of the menu_item
+			if ( isset($_POST['the-menu-item-id']) )
+				$del_id = $_POST['the-menu-item-id'];
+			else
+				return;
+
+			if ( isset($wp_registered_menu_items[$del_id]['params'][0]['number']) ) {
+				$number = $wp_registered_menu_items[$del_id]['params'][0]['number'];
+
+				if ( $this->id_base . '-' . $number == $del_id )
+					unset($all_instances[$number]);
+			}
+		} else {
+			if ( isset($_POST['menu-item-' . $this->id_base]) && is_array($_POST['menu-item-' . $this->id_base]) ) {
+				$settings = $_POST['menu-item-' . $this->id_base];
+			} elseif ( isset($_POST['id_base']) && $_POST['id_base'] == $this->id_base ) {
+				$num = $_POST['multi_number'] ? (int) $_POST['multi_number'] : (int) $_POST['menu_item_number'];
+				$settings = array( $num => array() );
+			} else {
+				return;
+			}
+
+			foreach ( $settings as $number => $new_instance ) {
+				$new_instance = stripslashes_deep($new_instance);
+				$this->_set($number);
+
+				$old_instance = isset($all_instances[$number]) ? $all_instances[$number] : array();
+
+				$instance = $this->update($new_instance, $old_instance);
+
+				// filters the menu_item's settings before saving, return false to cancel saving (keep the old settings if updating)
+				$instance = apply_filters('menu_item_update_callback', $instance, $new_instance, $old_instance, $this);
+				if ( false !== $instance )
+					$all_instances[$number] = $instance;
+
+				break; // run only once
+			}
+		}
+
+		$this->save_settings($all_instances);
+		$this->updated = true;
+	}
+
+	/** Generate the control form.
+	 *	Do NOT over-ride this function. */
+	function form_callback( $menu_item_args = 1 ) {
+		if ( is_numeric($menu_item_args) )
+			$menu_item_args = array( 'number' => $menu_item_args );
+
+		$menu_item_args = wp_parse_args( $menu_item_args, array( 'number' => -1 ) );
+		$all_instances = $this->get_settings();
+
+		if ( -1 == $menu_item_args['number'] ) {
+			// We echo out a form where 'number' can be set later
+			$this->_set('__i__');
+			$instance = array();
+		} else {
+			$this->_set($menu_item_args['number']);
+			$instance = $all_instances[ $menu_item_args['number'] ];
+		}
+
+		// filters the menu_item admin form before displaying, return false to stop displaying it
+		$instance = apply_filters('menu_item_form_callback', $instance, $this);
+
+		$return = null;
+		if ( false !== $instance ) {
+			$return = $this->form($instance);
+			// add extra fields in the menu_item form - be sure to set $return to null if you add any
+			// if the menu_item has no form the text echoed from the default form method can be hidden using css
+			do_action_ref_array( 'in_menu_item_form', array(&$this, &$return, $instance) );
+		}
+		return $return;
+	}
+
+	/** Helper function: Registers a single instance. */
+	function _register_one($number = -1) {
+		wp_register_menu_item(	$this->id, $this->name,	$this->_get_display_callback(), $this->menu_item_options, array( 'number' => $number ) );
+		_register_menu_item_update_callback( $this->id_base, $this->_get_update_callback(), $this->control_options, array( 'number' => -1 ) );
+		_register_menu_item_form_callback(	$this->id, $this->name,	$this->_get_form_callback(), $this->control_options, array( 'number' => $number ) );
+	}
+
+	function save_settings($settings) {
+		update_option( $this->option_name, $settings );
+	}
+
+	function get_settings() {
+		$settings = get_option($this->option_name);
+
+		if ( false === $settings && isset($this->alt_option_name) )
+			$settings = get_option($this->alt_option_name);
+
+		if ( !is_array($settings) )
+			$settings = array();
+
+		unset($settings['__i__']);
+		return $settings;
+	}
+}
+
+/**
+ * Singleton that registers and instantiates WP_Menu_Item classes.
+ *
+ * @package WordPress
+ * @subpackage Menu_Items
+ * @since 3.0
+ */
+class WP_Menu_Item_Factory {
+	var $menu_items = array();
+
+	function WP_Menu_Item_Factory() {
+		add_action( 'menu_items_init', array( &$this, '_register_menu_items' ), 100 );
+	}
+
+	function register($menu_item_class) {
+		$this->menu_items[$menu_item_class] = & new $menu_item_class();
+	}
+
+	function unregister($menu_item_class) {
+		if ( isset($this->menu_items[$menu_item_class]) )
+			unset($this->menu_items[$menu_item_class]);
+	}
+
+	function _register_menu_items() {
+		global $wp_registered_menu_items;
+		$keys = array_keys($this->menu_items);
+		$registered = array_keys($wp_registered_menu_items);
+		$registered = array_map('_get_menu_item_id_base', $registered);
+
+		foreach ( $keys as $key ) {
+			// don't register new menu_item if old menu_item with the same id is already registered
+			if ( in_array($this->menu_items[$key]->id_base, $registered, true) ) {
+				unset($this->menu_items[$key]);
+				continue;
+			}
+
+			$this->menu_items[$key]->_register();
+		}
+	}
+}
+
+/* Global Variables */
+
+/** @ignore */
+global $wp_registered_menus, $wp_registered_menu_items, $wp_registered_menu_item_controls, $wp_registered_menu_item_updates;
+
+/**
+ * Stores the menus, since many themes can have more than one.
+ *
+ * @global array $wp_registered_menus
+ * @since 3.0.0
+ */
+$wp_registered_menus = array();
+
+/**
+ * Stores the registered menu_items.
+ *
+ * @global array $wp_registered_menu_items
+ * @since 3.0.0
+ */
+$wp_registered_menu_items = array();
+
+/**
+ * Stores the registered menu_item control (options).
+ *
+ * @global array $wp_registered_menu_item_controls
+ * @since 3.0.0
+ */
+$wp_registered_menu_item_controls = array();
+$wp_registered_menu_item_updates = array();
+
+/**
+ * Private
+ */
+$_wp_menu_items = array();
+
+/* Template tags & API functions */
+
+/**
+ * Register a menu_item
+ *
+ * Registers a WP_Menu_Item menu_item
+ *
+ * @since 3.0.0
+ *
+ * @see WP_Menu_Item
+ * @see WP_Menu_Item_Factory
+ * @uses WP_Menu_Item_Factory
+ *
+ * @param string $menu_item_class The name of a class that extends WP_Menu_Item
+ */
+function register_menu_item($menu_item_class) {
+	global $wp_menu_item_factory;
+
+	$wp_menu_item_factory->register($menu_item_class);
+}
+
+/**
+ * Unregister a menu_item
+ *
+ * Unregisters a WP_Menu_Item menu_item. Useful for unregistering default menu_items.
+ * Run within a function hooked to the menu_items_init action.
+ *
+ * @since 3.0.0
+ *
+ * @see WP_Menu_Item
+ * @see WP_Menu_Item_Factory
+ * @uses WP_Menu_Item_Factory
+ *
+ * @param string $menu_item_class The name of a class that extends WP_Menu_Item
+ */
+function unregister_menu_item($menu_item_class) {
+	global $wp_menu_item_factory;
+
+	$wp_menu_item_factory->unregister($menu_item_class);
+}
+
+/**
+ * Creates multiple menus.
+ *
+ * If you wanted to quickly create multiple menus for a theme or internally.
+ * This function will allow you to do so. If you don't pass the 'name' and/or
+ * 'id' in $args, then they will be built for you.
+ *
+ * The default for the name is "Menu #", with '#' being replaced with the
+ * number the menu is currently when greater than one. If first menu, the
+ * name will be just "Menu". The default for id is "menu-" followed by the
+ * number the menu creation is currently at.
+ *
+ * @since 3.0.0
+ *
+ * @see register_menu() The second parameter is documented by register_menu() and is the same here.
+ * @uses parse_str() Converts a string to an array to be used in the rest of the function.
+ * @uses register_menu() Sends single menu information [name, id] to this
+ *	function to handle building the menu.
+ *
+ * @param int $number Number of menus to create.
+ * @param string|array $args Builds Menu based off of 'name' and 'id' values.
+ */
+function register_menus($number = 1, $args = array()) {
+	global $wp_registered_menus;
+	$number = (int) $number;
+
+	if ( is_string($args) )
+		parse_str($args, $args);
+
+	for ( $i=1; $i <= $number; $i++ ) {
+		$_args = $args;
+
+		if ( $number > 1 ) {
+			$_args['name'] = isset($args['name']) ? sprintf($args['name'], $i) : sprintf(__('Menu %d'), $i);
+		} else {
+			$_args['name'] = isset($args['name']) ? $args['name'] : __('Menu');
+		}
+
+		if ( !isset($args['id']) ) {
+			$n = count($wp_registered_menus);
+			do {
+				$n++;
+				$_args['id'] = "menu-$n";
+			} while (isset($wp_registered_menus[$_args['id']]));
+		}
+
+		register_menu($_args);
+	}
+}
+
+/**
+ * Builds the definition for a single menu and returns the ID.
+ *
+ * The $args parameter takes either a string or an array with 'name' and 'id'
+ * contained in either usage. It will be noted that the values will be applied
+ * to all menus, so if creating more than one, it will be advised to allow
+ * for WordPress to create the defaults for you.
+ *
+ * Example for string would be <code>'name=whatever;id=whatever1'</code> and for
+ * the array it would be <code>array(
+ *    'name' => 'whatever',
+ *    'id' => 'whatever1')</code>.
+ *
+ * name - The name of the menu, which presumably the title which will be
+ *     displayed.
+ * id - The unique identifier by which the menu will be called by.
+ * before_menu_item - The content that will prepended to the menu_items when they are
+ *     displayed.
+ * after_menu_item - The content that will be appended to the menu_items when they are
+ *     displayed.
+ * before_title - The content that will be prepended to the title when displayed.
+ * after_title - the content that will be appended to the title when displayed.
+ *
+ * <em>Content</em> is assumed to be HTML and should be formatted as such, but
+ * doesn't have to be.
+ *
+ * @since 3.0.0
+ * @uses $wp_registered_menus Stores the new menu in this array by menu ID.
+ * @uses parse_str() Converts a string to an array to be used in the rest of the function.
+ * @usedby register_menus()
+ *
+ * @param string|array $args Builds Menu based off of 'name' and 'id' values
+ * @return string The menu id that was added.
+ */
+function register_menu($args = array()) {
+	global $wp_registered_menus;
+
+	$i = count($wp_registered_menus) + 1;
+
+	$defaults = array(
+		'name' => sprintf(__('Menu %d'), $i ),
+		'id' => "menu-$i",
+		'description' => '',
+		'before_menu' => '<ul id="%1$s" class="menu %2$s">',
+		'after_menu' => "</ul>\n",
+	);
+
+	$menu = wp_parse_args($args, $defaults);
+
+	$wp_registered_menus[$menu['id']] = $menu;
+
+	return $menu['id'];
+}
+
+/**
+ * Removes a menu from the list.
+ *
+ * @since 3.0.0
+ *
+ * @uses $wp_registered_menus Stores the new menu in this array by menu ID.
+ *
+ * @param string $name The ID of the menu when it was added.
+ */
+function unregister_menu( $name ) {
+	global $wp_registered_menus;
+
+	if ( isset( $wp_registered_menus[$name] ) )
+		unset( $wp_registered_menus[$name] );
+}
+
+/**
+ * Register menu_item for use in menus.
+ *
+ * The default menu_item option is 'classname' that can be override.
+ *
+ * The function can also be used to unregister menu_items when $output_callback
+ * parameter is an empty string.
+ *
+ * @since 3.0.0
+ *
+ * @uses $wp_registered_menu_items Uses stored registered menu_items.
+ * @uses $wp_register_menu_item_defaults Retrieves menu_item defaults.
+ *
+ * @param int|string $id Menu_Item ID.
+ * @param string $name Menu_Item display title.
+ * @param callback $output_callback Run when menu_item is called.
+ * @param array|string Optional. $options Menu_Item Options.
+ * @param mixed $params,... Menu_Item parameters to add to menu_item.
+ * @return null Will return if $output_callback is empty after removing menu_item.
+ */
+function wp_register_menu_item($id, $name, $output_callback, $options = array()) {
+	global $wp_registered_menu_items, $wp_registered_menu_item_controls, $wp_registered_menu_item_updates;
+
+	$id = strtolower($id);
+
+	if ( empty($output_callback) ) {
+		unset($wp_registered_menu_items[$id]);
+		return;
+	}
+
+	$id_base = _get_menu_item_id_base($id);
+	if ( !is_callable($output_callback) ) {
+		if ( isset($wp_registered_menu_item_controls[$id]) )
+			unset($wp_registered_menu_item_controls[$id]);
+
+		if ( isset($wp_registered_menu_item_updates[$id_base]) )
+			unset($wp_registered_menu_item_updates[$id_base]);
+
+		return;
+	}
+
+	$defaults = array('classname' => $output_callback);
+	$options = wp_parse_args($options, $defaults);
+	$menu_item = array(
+		'name' => $name,
+		'id' => $id,
+		'callback' => $output_callback,
+		'params' => array_slice(func_get_args(), 4)
+	);
+	$menu_item = array_merge($menu_item, $options);
+
+	if ( is_callable($output_callback) && ( !isset($wp_registered_menu_items[$id]) || did_action( 'menu_items_init' ) ) )
+		$wp_registered_menu_items[$id] = $menu_item;
+}
+
+/**
+ * Retrieve description for menu_item.
+ *
+ * When registering menu_items, the options can also include 'description' that
+ * describes the menu_item for display on the menu_item administration panel or
+ * in the theme.
+ *
+ * @since 3.0.0
+ *
+ * @param int|string $id Menu_Item ID.
+ * @return string Menu_Item description, if available. Null on failure to retrieve description.
+ */
+function wp_menu_item_description( $id ) {
+	if ( !is_scalar($id) )
+		return;
+
+	global $wp_registered_menu_items;
+
+	if ( isset($wp_registered_menu_items[$id]['description']) )
+		return esc_html( $wp_registered_menu_items[$id]['description'] );
+}
+
+/**
+ * Retrieve description for a menu.
+ *
+ * When registering menus a 'description' parameter can be included that
+ * describes the menu for display on the menu_item administration panel.
+ *
+ * @since 3.0.0
+ *
+ * @param int|string $id menu ID.
+ * @return string Menu description, if available. Null on failure to retrieve description.
+ */
+function wp_menu_description( $id ) {
+	if ( !is_scalar($id) )
+		return;
+
+	global $wp_registered_menus;
+
+	if ( isset($wp_registered_menus[$id]['description']) )
+		return esc_html( $wp_registered_menus[$id]['description'] );
+}
+
+
+/**
+ * Remove menu_item from menu.
+ *
+ * @since 3.0.0
+ *
+ * @param int|string $id Menu_Item ID.
+ */
+function wp_unregister_menu_item($id) {
+	wp_register_menu_item($id, '', '');
+	wp_unregister_menu_item_control($id);
+}
+
+/**
+ * Registers menu_item control callback for customizing options.
+ *
+ * The options contains the 'height', 'width', and 'id_base' keys. The 'height'
+ * option is never used. The 'width' option is the width of the fully expanded
+ * control form, but try hard to use the default width. The 'id_base' is for
+ * multi-menu_items (menu_items which allow multiple instances such as the text
+ * menu_item), an id_base must be provided. The menu_item id will end up looking like
+ * {$id_base}-{$unique_number}.
+ *
+ * @since 3.0.0
+ *
+ * @param int|string $id Menu ID.
+ * @param string $name Menu display name.
+ * @param callback $control_callback Run when menu is displayed.
+ * @param array|string $options Optional. Menu_Item options. See above long description.
+ * @param mixed $params,... Optional. Additional parameters to add to menu_item.
+ */
+function wp_register_menu_item_control($id, $name, $control_callback, $options = array()) {
+	global $wp_registered_menu_item_controls, $wp_registered_menu_item_updates, $wp_registered_menu_items;
+
+	$id = strtolower($id);
+	$id_base = _get_menu_item_id_base($id);
+
+	if ( empty($control_callback) ) {
+		unset($wp_registered_menu_item_controls[$id]);
+		unset($wp_registered_menu_item_updates[$id_base]);
+		return;
+	}
+
+	if ( !is_callable($control_callback) ) {
+		if ( isset($wp_registered_menu_items[$id]) )
+			unset($wp_registered_menu_items[$id]);
+
+		return;
+	}
+
+	if ( isset($wp_registered_menu_item_controls[$id]) && !did_action( 'menu_items_init' ) )
+		return;
+
+	$defaults = array('width' => 250, 'height' => 200 ); // height is never used
+	$options = wp_parse_args($options, $defaults);
+	$options['width'] = (int) $options['width'];
+	$options['height'] = (int) $options['height'];
+
+	$menu_item = array(
+		'name' => $name,
+		'id' => $id,
+		'callback' => $control_callback,
+		'params' => array_slice(func_get_args(), 4)
+	);
+	$menu_item = array_merge($menu_item, $options);
+
+	$wp_registered_menu_item_controls[$id] = $menu_item;
+
+	if ( isset($wp_registered_menu_item_updates[$id_base]) )
+		return;
+
+	if ( isset($menu_item['params'][0]['number']) )
+		$menu_item['params'][0]['number'] = -1;
+
+	unset($menu_item['width'], $menu_item['height'], $menu_item['name'], $menu_item['id']);
+	$wp_registered_menu_item_updates[$id_base] = $menu_item;
+}
+
+function _register_menu_item_update_callback($id_base, $update_callback, $options = array()) {
+	global $wp_registered_menu_item_updates;
+
+	if ( isset($wp_registered_menu_item_updates[$id_base]) ) {
+		if ( empty($update_callback) )
+			unset($wp_registered_menu_item_updates[$id_base]);
+		return;
+	}
+
+	$menu_item = array(
+		'callback' => $update_callback,
+		'params' => array_slice(func_get_args(), 3)
+	);
+
+	$menu_item = array_merge($menu_item, $options);
+	$wp_registered_menu_item_updates[$id_base] = $menu_item;
+}
+
+function _register_menu_item_form_callback($id, $name, $form_callback, $options = array()) {
+	global $wp_registered_menu_item_controls;
+
+	$id = strtolower($id);
+
+	if ( empty($form_callback) ) {
+		unset($wp_registered_menu_item_controls[$id]);
+		return;
+	}
+
+	if ( isset($wp_registered_menu_item_controls[$id]) && !did_action( 'menu_items_init' ) )
+		return;
+
+	$defaults = array('width' => 250, 'height' => 200 );
+	$options = wp_parse_args($options, $defaults);
+	$options['width'] = (int) $options['width'];
+	$options['height'] = (int) $options['height'];
+
+	$menu_item = array(
+		'name' => $name,
+		'id' => $id,
+		'callback' => $form_callback,
+		'params' => array_slice(func_get_args(), 4)
+	);
+	$menu_item = array_merge($menu_item, $options);
+
+	$wp_registered_menu_item_controls[$id] = $menu_item;
+}
+
+/**
+ * Remove control callback for menu_item.
+ *
+ * @since 3.0.0
+ * @uses wp_register_menu_item_control() Unregisters by using empty callback.
+ *
+ * @param int|string $id Menu_Item ID.
+ */
+function wp_unregister_menu_item_control($id) {
+	return wp_register_menu_item_control($id, '', '');
+}
+
+/**
+ * Display dynamic menu.
+ *
+ * By default it displays the default menu or 'menu-1'. The 'menu-1' is
+ * not named by the theme, the actual name is '1', but 'menu-' is added to
+ * the registered menus for the name. If you named your menu 'after-post',
+ * then the parameter $index will still be 'after-post', but the lookup will be
+ * for 'menu-after-post'.
+ *
+ * It is confusing for the $index parameter, but just know that it should just
+ * work. When you register the menu in the theme, you will use the same name
+ * for this function or "Pay no heed to the man behind the curtain." Just accept
+ * it as an oddity of WordPress menu register and display.
+ *
+ * @since 3.0.0
+ *
+ * @param int|string $index Optional, default is 1. Name or ID of dynamic menu.
+ * @return bool True, if menu_item menu was found and called. False if not found or not called.
+ */
+function dynamic_menu($index = 1) {
+	global $wp_registered_menus, $wp_registered_menu_items;
+
+	if ( is_int($index) ) {
+		$index = "menu-$index";
+	} else {
+		$index = sanitize_title($index);
+		foreach ( (array) $wp_registered_menus as $key => $value ) {
+			if ( sanitize_title($value['name']) == $index ) {
+				$index = $key;
+				break;
+			}
+		}
+	}
+
+	$wp_menu_items = wp_get_menu_items();
+
+	if ( empty($wp_registered_menus[$index]) || !array_key_exists($index, $wp_menu_items) || !is_array($wp_menu_items[$index]) || empty($wp_menu_items[$index]) )
+		return false;
+
+	$menu = $wp_registered_menus[$index];
+
+	$did_one = false;
+	foreach ( (array) $wp_menu_items[$index] as $id ) {
+
+		if ( !isset($wp_registered_menu_items[$id]) ) continue;
+
+		$params = array_merge(
+			array( array_merge( $menu, array('menu_item_id' => $id, 'menu_item_name' => $wp_registered_menu_items[$id]['name']) ) ),
+			(array) $wp_registered_menu_items[$id]['params']
+		);
+
+		// Substitute HTML id and class attributes into before_menu_item
+		$classname_ = '';
+		foreach ( (array) $wp_registered_menu_items[$id]['classname'] as $cn ) {
+			if ( is_string($cn) )
+				$classname_ .= '_' . $cn;
+			elseif ( is_object($cn) )
+				$classname_ .= '_' . get_class($cn);
+		}
+		$classname_ = ltrim($classname_, '_');
+		$params[0]['before_menu_item'] = sprintf($params[0]['before_menu'], $id, $classname_);
+
+		$params = apply_filters( 'dynamic_menu_params', $params );
+
+		$callback = $wp_registered_menu_items[$id]['callback'];
+
+		if ( is_callable($callback) ) {
+			call_user_func_array($callback, $params);
+			$did_one = true;
+		}
+	}
+
+	return $did_one;
+}
+
+/**
+ * Whether menu_item is displayied on the front-end.
+ *
+ * Either $callback or $id_base can be used
+ * $id_base is the first argument when extending WP_Menu_Item class
+ * Without the optional $menu_item_id parameter, returns the ID of the first menu
+ * in which the first instance of the menu_item with the given callback or $id_base is found.
+ * With the $menu_item_id parameter, returns the ID of the menu where
+ * the menu_item with that callback/$id_base AND that ID is found.
+ *
+ * NOTE: $menu_item_id and $id_base are the same for single menu_items. To be effective
+ * this function has to run after menu_items have initialized, at action 'init' or later.
+ *
+ * @since 3.0.0
+ *
+ * @param callback Optional, Menu_Item callback to check.
+ * @param int $menu_item_id Optional, but needed for checking. Menu_Item ID.
+ * @param string $id_base Optional, the base ID of a menu_item created by extending WP_Menu_Item.
+ * @param bool $skip_inactive Optional, whether to check in 'wp_inactive_menu_items'.
+ * @return mixed false if menu_item is not active or id of menu in which the menu_item is active.
+ */
+function is_active_menu_item($callback = false, $menu_item_id = false, $id_base = false, $skip_inactive = true) {
+	global $wp_registered_menu_items;
+
+	$wp_menu_items = wp_get_menu_items();
+
+	if ( is_array($wp_menu_items) ) {
+		foreach ( $wp_menu_items as $menu => $menu_items ) {
+			if ( $skip_inactive && 'wp_inactive_menu_items' == $menu )
+				continue;
+
+			if ( is_array($menu_items) ) {
+				foreach ( $menu_items as $menu_item ) {
+					if ( ( $callback && isset($wp_registered_menu_items[$menu_item]['callback']) && $wp_registered_menu_items[$menu_item]['callback'] == $callback ) || ( $id_base && _get_menu_item_id_base($menu_item) == $id_base ) ) {
+						if ( !$menu_item_id || $menu_item_id == $wp_registered_menu_items[$menu_item]['id'] )
+							return $menu;
+					}
+				}
+			}
+		}
+	}
+	return false;
+}
+
+/**
+ * Whether the dynamic menu is enabled and used by theme.
+ *
+ * @since 3.0.0
+ *
+ * @return bool True, if using menu_items. False, if not using menu_items.
+ */
+function is_dynamic_menu() {
+	global $wp_registered_menu_items, $wp_registered_menus;
+	$wp_menu_items = get_option('wp_menu_items');
+	foreach ( (array) $wp_registered_menus as $index => $menu ) {
+		if ( count($wp_menu_items[$index]) ) {
+			foreach ( (array) $wp_menu_items[$index] as $menu_item )
+				if ( array_key_exists($menu_item, $wp_registered_menu_items) )
+					return true;
+		}
+	}
+	return false;
+}
+
+/**
+ * Whether a menu is in use.
+ *
+ * @since 3.0
+ *
+ * @param mixed $index, menu name, id or number to check.
+ * @return bool true if the menu is in use, false otherwise.
+ */
+function is_active_menu( $index ) {
+	$index = ( is_int($index) ) ? "menu-$index" : sanitize_title($index);
+	$wp_menu_items = wp_get_menu_items();
+	if ( isset($wp_menu_items[$index]) && !empty($wp_menu_items[$index]) )
+		return true;
+
+	return false;
+}
+
+/* Internal Functions */
+
+/**
+ * Retrieve full list of menus and their menu_items.
+ *
+ * Will upgrade menu menu_item list, if needed. Will also save updated list, if
+ * needed.
+ *
+ * @since 3.0.0
+ * @access private
+ *
+ * @return array Upgraded list of menu_items to version 3 array format when called from the admin.
+ */
+function wp_get_menu_items() {
+	global $wp_registered_menu_items, $wp_registered_menus, $_wp_menu_items;
+
+	// If loading from front page, consult $_wp_menu_items rather than options
+	// to see if wp_convert_menu_item_settings() has made manipulations in memory.
+	if ( !is_admin() ) {
+		if ( empty($_wp_menu_items) )
+			$_wp_menu_items = get_option('wp_menu_items', array());
+
+		$wp_menu_items = $_wp_menu_items;
+	} else {
+		$wp_menu_items = get_option('wp_menu_items', array());
+		$_wp_menu_items = array();
+
+		if ( isset($wp_menu_items['wp_inactive_menu_items']) || empty($wp_menu_items) )
+			$wp_menu_items['array_version'] = 3;
+		elseif ( !isset($wp_menu_items['array_version']) )
+			$wp_menu_items['array_version'] = 1;
+
+		switch ( $wp_menu_items['array_version'] ) {
+			case 1 :
+				foreach ( (array) $wp_menu_items as $index => $menu )
+				if ( is_array($menu) )
+				foreach ( (array) $menu as $i => $name ) {
+					$id = strtolower($name);
+					if ( isset($wp_registered_menu_items[$id]) ) {
+						$_wp_menu_items[$index][$i] = $id;
+						continue;
+					}
+					$id = sanitize_title($name);
+					if ( isset($wp_registered_menu_items[$id]) ) {
+						$_wp_menu_items[$index][$i] = $id;
+						continue;
+					}
+
+					$found = false;
+
+					foreach ( $wp_registered_menu_items as $menu_item_id => $menu_item ) {
+						if ( strtolower($menu_item['name']) == strtolower($name) ) {
+							$_wp_menu_items[$index][$i] = $menu_item['id'];
+							$found = true;
+							break;
+						} elseif ( sanitize_title($menu_item['name']) == sanitize_title($name) ) {
+							$_wp_menu_items[$index][$i] = $menu_item['id'];
+							$found = true;
+							break;
+						}
+					}
+
+					if ( $found )
+						continue;
+
+					unset($_wp_menu_items[$index][$i]);
+				}
+				$_wp_menu_items['array_version'] = 2;
+				$wp_menu_items = $_wp_menu_items;
+				unset($_wp_menu_items);
+
+			case 2 :
+				$menus = array_keys( $wp_registered_menus );
+				if ( !empty( $menus ) ) {
+					// Move the known-good ones first
+					foreach ( (array) $menus as $id ) {
+						if ( array_key_exists( $id, $wp_menu_items ) ) {
+							$_wp_menu_items[$id] = $wp_menu_items[$id];
+							unset($wp_menu_items[$id], $menus[$id]);
+						}
+					}
+
+					// move the rest to wp_inactive_menu_items
+					if ( !isset($_wp_menu_items['wp_inactive_menu_items']) )
+						$_wp_menu_items['wp_inactive_menu_items'] = array();
+
+					if ( !empty($wp_menu_items) ) {
+						foreach ( $wp_menu_items as $lost => $val ) {
+							if ( is_array($val) )
+								$_wp_menu_items['wp_inactive_menu_items'] = array_merge( (array) $_wp_menu_items['wp_inactive_menu_items'], $val );
+						}
+					}
+
+					$wp_menu_items = $_wp_menu_items;
+					unset($_wp_menu_items);
+				}
+		}
+	}
+
+	if ( isset($wp_menu_items['array_version']) )
+		unset($wp_menu_items['array_version']);
+
+	$wp_menu_items = apply_filters('wp_menu_items', $wp_menu_items);
+	return $wp_menu_items;
+}
+
+/**
+ * Set the menu menu_item option to update menus.
+ *
+ * @since 3.0.0
+ * @access private
+ *
+ * @param array $wp_menu_items Menu menu_items and their settings.
+ */
+function wp_set_menu_items( $wp_menu_items ) {
+	if ( !isset( $wp_menu_items['array_version'] ) )
+		$wp_menu_items['array_version'] = 3;
+	update_option( 'wp_menu_items', $wp_menu_items );
+}
+
+/**
+ * Retrieve default registered menus list.
+ *
+ * @since 3.0.0
+ * @access private
+ *
+ * @return array
+ */
+function wp_get_menu_item_defaults() {
+	global $wp_registered_menus;
+
+	$defaults = array();
+
+	foreach ( (array) $wp_registered_menus as $index => $menu )
+		$defaults[$index] = array();
+
+	return $defaults;
+}
+
+/**
+ * Private
+ */
+function _get_menu_item_id_base($id) {
+	return preg_replace( '/-[0-9]+$/', '', $id );
+}
+
+// Initialization code
+
+/*ignore*/
+global $wp_menu_item_factory;
+
+/**
+ * WordPress Menu Item Factory Object
+ * @global object $wp_menu_item_factory
+ * @since 3.0
+ */
+$wp_menu_item_factory =& new WP_Menu_Item_Factory();
+
Index: wp-includes/script-loader.php
===================================================================
--- wp-includes/script-loader.php	(revision 12749)
+++ wp-includes/script-loader.php	(working copy)
@@ -326,6 +326,9 @@
 		$scripts->add( 'admin-widgets', "/wp-admin/js/widgets$suffix.js", array( 'jquery-ui-sortable', 'jquery-ui-draggable', 'jquery-ui-droppable' ), '20090824' );
 		$scripts->add_data( 'admin-widgets', 'group', 1 );
 
+		$scripts->add( 'admin-menus', "/wp-admin/js/menus$suffix.js", array( 'jquery-ui-sortable', 'jquery-ui-draggable', 'jquery-ui-droppable' ), '20090824' );
+		$scripts->add_data( 'admin-menus', 'group', 1 );
+
 		$scripts->add( 'word-count', "/wp-admin/js/word-count$suffix.js", array( 'jquery' ), '20090422' );
 		$scripts->add_data( 'word-count', 'group', 1 );
 		$scripts->localize( 'word-count', 'wordCountL10n', array(
@@ -426,7 +429,7 @@
 
 	$suffix = defined('STYLE_DEBUG') && STYLE_DEBUG ? '.dev' : '';
 
-	$rtl_styles = array( 'wp-admin', 'global', 'colors', 'dashboard', 'ie', 'install', 'login', 'media', 'theme-editor', 'upload', 'widgets', 'press-this', 'plugin-install', 'farbtastic' );
+	$rtl_styles = array( 'wp-admin', 'global', 'colors', 'dashboard', 'ie', 'install', 'login', 'media', 'theme-editor', 'upload', 'widgets', 'menus', 'press-this', 'plugin-install', 'farbtastic' );
 
 	// all colors stylesheets need to have the same query strings (cache manifest compat)
 	$colors_version = '20091227';
@@ -448,6 +451,7 @@
 	$styles->add( 'global', "/wp-admin/css/global$suffix.css", array(), '20100108' );
 	$styles->add( 'media', "/wp-admin/css/media$suffix.css", array(), '20091029' );
 	$styles->add( 'widgets', "/wp-admin/css/widgets$suffix.css", array(), '20091118' );
+	$styles->add( 'menus', "/wp-admin/css/menus$suffix.css", array(), '20100109' );
 	$styles->add( 'dashboard', "/wp-admin/css/dashboard$suffix.css", array(), '20091211' );
 	$styles->add( 'install', "/wp-admin/css/install$suffix.css", array(), '20090514' );
 	$styles->add( 'theme-editor', "/wp-admin/css/theme-editor$suffix.css", array(), '20090625' );
Index: wp-content/themes/default/functions.php
===================================================================
--- wp-content/themes/default/functions.php	(revision 12749)
+++ wp-content/themes/default/functions.php	(working copy)
@@ -17,6 +17,10 @@
 	));
 }
 
+// Dynamic menu support
+add_theme_support('menus');
+register_menus(2);
+
 /** @ignore */
 function kubrick_head() {
 	$head = "<style type='text/css'>\n<!--";
Index: wp-settings.php
===================================================================
--- wp-settings.php	(revision 12749)
+++ wp-settings.php	(working copy)
@@ -101,6 +101,7 @@
 require (ABSPATH . WPINC . '/media.php');
 require (ABSPATH . WPINC . '/http.php');
 require (ABSPATH . WPINC . '/widgets.php');
+require (ABSPATH . WPINC . '/menus.php');
 
 if ( is_multisite() ) {
 	require_once( ABSPATH . WPINC . '/ms-functions.php' );
@@ -221,4 +222,4 @@
 // Everything is loaded and initialized.
 do_action('init');
 
-?>
\ No newline at end of file
+?>
Index: wp-admin/admin-ajax.php
===================================================================
--- wp-admin/admin-ajax.php	(revision 12749)
+++ wp-admin/admin-ajax.php	(working copy)
@@ -1382,6 +1382,105 @@
 
 	die();
 	break;
+case 'menu-items-order' :
+	check_ajax_referer( 'save-menu-items', 'savemenu_items' );
+
+	if ( !current_user_can('switch_themes') )
+		die('-1');
+
+	unset( $_POST['savemenu_items'], $_POST['action'] );
+
+	// save menu_items order for all menus
+	if ( is_array($_POST['menus']) ) {
+		$menus = array();
+		foreach ( $_POST['menus'] as $key => $val ) {
+			$sb = array();
+			if ( !empty($val) ) {
+				$val = explode(',', $val);
+				foreach ( $val as $k => $v ) {
+					if ( strpos($v, 'menu-item-') === false )
+						continue;
+
+					$tmp = explode('_', $v, 2);
+					$sb[$k] = $tmp[1];
+				}
+			}
+			$menus[$key] = $sb;
+		}
+		wp_set_menu_items($menus);
+		die('1');
+	}
+
+	die('-1');
+	break;
+case 'save-menu-item' :
+	check_ajax_referer( 'save-menu-items', 'savemenu_items' );
+
+	if ( !current_user_can('switch_themes') || !isset($_POST['id_base']) )
+		die('-1');
+
+	unset( $_POST['savemenu_items'], $_POST['action'] );
+
+	do_action('load-menus.php');
+	do_action('menus.php');
+	do_action('menu_admin_setup');
+
+	$id_base = $_POST['id_base'];
+	$menu_item_id = $_POST['menu-item-id'];
+	$menu_id = $_POST['menu'];
+	$multi_number = !empty($_POST['multi_number']) ? (int) $_POST['multi_number'] : 0;
+	$settings = isset($_POST['menu-item-' . $id_base]) && is_array($_POST['menu-item-' . $id_base]) ? $_POST['menu-item-' . $id_base] : false;
+	$error = '<p>' . __('An error has occured. Please reload the page and try again.') . '</p>';
+
+	$menus = wp_get_menu_items();
+	$menu = isset($menus[$menu_id]) ? $menus[$menu_id] : array();
+
+	// delete
+	if ( isset($_POST['delete_menu_item']) && $_POST['delete_menu_item'] ) {
+
+		if ( !isset($wp_registered_menu_items[$menu_item_id]) )
+			die($error);
+
+		$menu = array_diff( $menu, array($menu_item_id) );
+		$_POST = array('menu' => $menu_id, 'menu-item-' . $id_base => array(), 'the-menu-item-id' => $menu_item_id, 'delete_menu_item' => '1');
+	} elseif ( $settings && preg_match( '/__i__|%i%/', key($settings) ) ) {
+		if ( !$multi_number )
+			die($error);
+
+		$_POST['menu-item-' . $id_base] = array( $multi_number => array_shift($settings) );
+		$menu_item_id = $id_base . '-' . $multi_number;
+		$menu[] = $menu_item_id;
+	}
+	$_POST['menu-item-id'] = $menu;
+
+	foreach ( (array) $wp_registered_menu_item_updates as $name => $control ) {
+
+		if ( $name == $id_base ) {
+			if ( !is_callable( $control['callback'] ) )
+				continue;
+
+			ob_start();
+				call_user_func_array( $control['callback'], $control['params'] );
+			ob_end_clean();
+			break;
+		}
+	}
+
+	if ( isset($_POST['delete_menu_item']) && $_POST['delete_menu_item'] ) {
+		$menus[$menu_id] = $menu;
+		wp_set_menu_items($menus);
+		echo "deleted:$menu_item_id";
+		die();
+	}
+
+	if ( !empty($_POST['add_new']) )
+		die();
+
+	if ( $form = $wp_registered_menu_item_controls[$menu_item_id] )
+		call_user_func_array( $form['callback'], $form['params'] );
+
+	die();
+	break;
 case 'image-editor':
 	$attachment_id = intval($_POST['postid']);
 	if ( empty($attachment_id) || !current_user_can('edit_post', $attachment_id) )
Index: wp-admin/includes/menus.php
===================================================================
--- wp-admin/includes/menus.php	(revision 0)
+++ wp-admin/includes/menus.php	(revision 0)
@@ -0,0 +1,223 @@
+<?php
+/**
+ * WordPress Menus Administration API
+ *
+ * @package WordPress
+ * @subpackage Administration
+ */
+
+/**
+ * Display list of the available menu items, either all or matching search.
+ *
+ * The search parameter are search terms separated by spaces.
+ *
+ * @since 3.0
+ *
+ * @param string $show Optional, default is all. What to display, can be 'all', 'unused', or 'used'.
+ * @param string $_search Optional. Search for menu_items. Should be unsanitized.
+ */
+function wp_list_menu_items() {
+	global $wp_registered_menu_items, $menu_items_map, $wp_registered_menu_item_controls;
+
+	$sort = $wp_registered_menu_items;
+
+	usort( $sort, create_function( '$a, $b', 'return strnatcasecmp( $a["name"], $b["name"] );' ) );
+	$done = array();
+	$special_items = array(__('Page'), __('Category'));
+
+	foreach ( $sort as $menu_item ) {
+		if ( in_array( $menu_item['callback'], $done, true ) ) // We already showed this multi-menu_item
+			continue;
+
+		$menu = is_active_menu_item( $menu_item['callback'], $menu_item['id'], false, false );
+		$done[] = $menu_item['callback'];
+
+		if ( ! isset( $menu_item['params'][0] ) )
+			$menu_item['params'][0] = array();
+
+		$args = array( 'menu_item_id' => $menu_item['id'], 'menu_item_name' => $menu_item['name'], '_display' => 'template' );
+
+		if ( isset($wp_registered_menu_item_controls[$menu_item['id']]['id_base']) && isset($menu_item['params'][0]['number']) ) {
+			$id_base = $wp_registered_menu_item_controls[$menu_item['id']]['id_base'];
+			$args['_temp_id'] = "$id_base-__i__";
+			$args['_multi_num'] = next_menu_item_id_number($id_base);
+			$args['_add'] = 'multi';
+		} else {
+			$args['_add'] = 'single';
+			if ( $menu )
+				$args['_hide'] = '1';
+		}
+
+		if ( in_array( $menu_item['name'], $special_items ) ) // Don't list special menu items here
+			$args['_hide'] = '1';
+
+		$args = wp_list_menu_item_controls_dynamic_menu( array( 0 => $args, 1 => $menu_item['params'][0] ) );
+		call_user_func_array( 'wp_menu_item_control', $args );
+	}
+}
+
+/**
+ * Show the menu_items and their settings for a menu.
+ * Used in the the admin menu_item config screen.
+ *
+ * @since 3.0
+ *
+ * @param string $menu id slug of the menu
+ */
+function wp_list_menu_item_controls( $menu ) {
+	add_filter( 'dynamic_menu_params', 'wp_list_menu_item_controls_dynamic_menu' );
+
+	echo "<div id='$menu' class='menu-items-sortables'>\n";
+
+	$description = wp_menu_description( $menu );
+
+	if ( !empty( $description ) ) {
+		echo "<div class='menu-description'>\n";
+		echo "\t<p class='description'>$description</p>"; 
+		echo "</div>\n";
+	}
+
+	dynamic_menu( $menu );
+	echo "</div>\n";
+}
+
+/**
+ * {@internal Missing Short Description}}
+ *
+ * @since 3.0
+ *
+ * @param array $params
+ * @return array
+ */
+function wp_list_menu_item_controls_dynamic_menu( $params ) {
+	global $wp_registered_menu_items;
+	static $i = 0;
+	$i++;
+
+	$menu_item_id = $params[0]['menu_item_id'];
+	$id = isset($params[0]['_temp_id']) ? $params[0]['_temp_id'] : $menu_item_id;
+	$hidden = isset($params[0]['_hide']) ? ' style="display:none;"' : '';
+
+	$params[0]['before_menu_item'] = "<div id='menu-item-${i}_$id' class='menu-item'$hidden>";
+	$params[0]['after_menu_item'] = "</div>";
+	if ( is_callable( $wp_registered_menu_items[$menu_item_id]['callback'] ) ) {
+		$wp_registered_menu_items[$menu_item_id]['_callback'] = $wp_registered_menu_items[$menu_item_id]['callback'];
+		$wp_registered_menu_items[$menu_item_id]['callback'] = 'wp_menu_item_control';
+	}
+
+	return $params;
+}
+
+function next_menu_item_id_number($id_base) {
+	global $wp_registered_menu_items;
+	$number = 1;
+
+	foreach ( $wp_registered_menu_items as $menu_item_id => $menu_item ) {
+		if ( preg_match( '/' . $id_base . '-([0-9]+)$/', $menu_item_id, $matches ) )
+			$number = max($number, $matches[1]);
+	}
+	$number++;
+
+	return $number;
+}
+
+/**
+ * Meta menu_item used to display the control form for a menu_item.
+ *
+ * Called from dynamic_menu().
+ *
+ * @since 3.0
+ *
+ * @param array $menu_args
+ * @return array
+ */
+function wp_menu_item_control( $menu_args ) {
+	global $wp_registered_menu_items, $wp_registered_menu_item_controls, $menu_items_map;
+
+	$menu_item_id = $menu_args['menu_item_id'];
+	$menu_id = isset($menu_args['id']) ? $menu_args['id'] : false;
+	$key = $menu_id ? array_search( $menu_item_id, $menu_items_map[$menu_id] ) : '-1'; // position of menu_item in menu
+	$control = isset($wp_registered_menu_item_controls[$menu_item_id]) ? $wp_registered_menu_item_controls[$menu_item_id] : array();
+	$menu_item = $wp_registered_menu_items[$menu_item_id];
+
+	$id_format = $menu_item['id'];
+	$menu_item_number = isset($control['params'][0]['number']) ? $control['params'][0]['number'] : '';
+	$id_base = isset($control['id_base']) ? $control['id_base'] : $menu_item_id;
+	$multi_number = isset($menu_args['_multi_num']) ? $menu_args['_multi_num'] : '';
+	$add_new = isset($menu_args['_add']) ? $menu_args['_add'] : '';
+
+	$query_arg = array( 'editmenu_item' => $menu_item['id'] );
+	if ( $add_new ) {
+		$query_arg['addnew'] = 1;
+		if ( $multi_number ) {
+			$query_arg['num'] = $multi_number;
+			$query_arg['base'] = $id_base;
+		}
+	} else {
+		$query_arg['menu'] = $menu_id;
+		$query_arg['key'] = $key;
+	}
+
+	// We aren't showing a menu_item control, we're outputing a template for a mult-menu_item control
+	if ( isset($menu_args['_display']) && 'template' == $menu_args['_display'] && $menu_item_number ) {
+		// number == -1 implies a template where id numbers are replaced by a generic '__i__'
+		$control['params'][0]['number'] = -1;
+		// with id_base menu_item id's are constructed like {$id_base}-{$id_number}
+		if ( isset($control['id_base']) )
+			$id_format = $control['id_base'] . '-__i__';
+	}
+
+	$wp_registered_menu_items[$menu_item_id]['callback'] = $wp_registered_menu_items[$menu_item_id]['_callback'];
+	unset($wp_registered_menu_items[$menu_item_id]['_callback']);
+
+	$menu_item_title = esc_html( strip_tags( $menu_args['menu_item_name'] ) );
+	$has_form = 'noform';
+
+	echo $menu_args['before_menu_item']; ?>
+	<div class="menu-item-top">
+	<div class="menu-item-title-action">
+		<a class="menu-item-action hide-if-no-js" href="#available-menu-items"></a>
+		<a class="menu-item-control-edit hide-if-js" href="<?php echo esc_url( add_query_arg( $query_arg ) ); ?>"><span class="edit"><?php _e('Edit'); ?></span><span class="add"><?php _e('Add'); ?></span></a>
+	</div>
+	<div class="menu-item-title"><h4><?php echo $menu_item_title ?><span class="in-menu-item-title"></span></h4></div>
+	</div>
+
+	<div class="menu-item-inside">
+	<form action="" method="post">
+	<div class="menu-item-content">
+<?php
+	if ( isset($control['callback']) )
+		$has_form = call_user_func_array( $control['callback'], $control['params'] );
+	else
+		echo "\t\t<p>" . __('There are no options for this menu item.') . "</p>\n"; ?>
+	</div>
+	<input type="hidden" name="menu-item-id" class="menu-item-id" value="<?php echo esc_attr($id_format); ?>" />
+	<input type="hidden" name="id_base" class="id_base" value="<?php echo esc_attr($id_base); ?>" />
+	<input type="hidden" name="menu-item-width" class="menu-item-width" value="<?php if (isset( $control['width'] )) echo esc_attr($control['width']); ?>" />
+	<input type="hidden" name="menu-item-height" class="menu-item-height" value="<?php if (isset( $control['height'] )) echo esc_attr($control['height']); ?>" />
+	<input type="hidden" name="menu_item_number" class="menu_item_number" value="<?php echo esc_attr($menu_item_number); ?>" />
+	<input type="hidden" name="multi_number" class="multi_number" value="<?php echo esc_attr($multi_number); ?>" />
+	<input type="hidden" name="add_new" class="add_new" value="<?php echo esc_attr($add_new); ?>" />
+
+	<div class="menu-item-control-actions">
+		<div class="alignleft">
+		<a class="menu-item-control-remove" href="#remove"><?php _e('Delete'); ?></a> |
+		<a class="menu-item-control-close" href="#close"><?php _e('Close'); ?></a>
+		</div>
+		<div class="alignright<?php if ( 'noform' === $has_form ) echo ' menu-item-control-noform'; ?>">
+		<img src="images/wpspin_light.gif" class="ajax-feedback " title="" alt="" />
+		<input type="submit" name="savemenu_item" class="button-primary menu-item-control-save" value="<?php esc_attr_e('Save'); ?>" />
+		</div>
+		<br class="clear" />
+	</div>
+	</form>
+	</div>
+
+	<div class="menu-item-description">
+<?php echo ( $menu_item_description = wp_menu_item_description($menu_item_id) ) ? "$menu_item_description\n" : "$menu_item_title\n"; ?>
+	</div>
+<?php
+	echo $menu_args['after_menu_item'];
+	return $menu_args;
+}
+
Index: wp-admin/js/menus.dev.js
===================================================================
--- wp-admin/js/menus.dev.js	(revision 0)
+++ wp-admin/js/menus.dev.js	(revision 0)
@@ -0,0 +1,319 @@
+(function($) {
+	window.wpMenus = {
+		
+	addItem : function(item) {
+		var add = item.find('input.add_new').val(),
+			n = item.find('input.multi_number').val(),
+			id = item.attr('id');
+
+		if ( ! add )
+			return false;
+
+		item.html( item.html().replace(/<[^<>]+>/g, function(m){ return m.replace(/__i__|%i%/g, n); }) );
+		item.attr( 'id', id.replace(/__i__|%i%/g, n) );
+		n++;
+		$('div#' + id).find('input.multi_number').val(n);
+
+		return true;
+	},
+
+	init : function() {
+		var rem, menus = $('div.menu-items-sortables');
+
+		$('#menu-item-dropdowns select').change(function(ev) {
+			var active_menu = $('.menu-item-liquid-right .menu-items-sortables').not('#wp_inactive_menu_items, .ui-sortable-disabled').eq(0);
+
+			if ( ! active_menu.length )
+				return;
+
+		  	var select = $(this),
+				selected = select.find('option:selected'),
+				item_type = select.parents('.menu-item-dropdown').attr('id').replace('-dropdown', '');
+				item_id = selected.val(),
+				item_title = $.trim(selected.text().replace('&nbsp;', ''));
+
+			if ( ! item_id )
+				return;
+
+			var menu_item = $('.menu-item[id*="' + item_type + '-__i__"]').clone(true).show();
+
+			active_menu.append(menu_item);
+
+			wpMenus.addItem(menu_item);
+
+			menu_item
+				.find('input[id*="-' + item_type + '_id"]')
+					.val(item_id)
+				.end()
+				.find('input[id*="-title"]')
+					.val(item_title)
+				.end();
+			wpMenus.appendTitle(menu_item.get());
+
+			wpMenus.save( menu_item, 0, 0, 1 );
+			menu_item.find('input.add_new').val('');
+		});
+
+		$('#menu-items-right').children('.menu-items-holder-wrap').children('.menu-name').click(function(){
+			var c = $(this).siblings('.menu-items-sortables'), p = $(this).parent();
+			if ( !p.hasClass('closed') ) {
+				c.sortable('disable');
+				p.addClass('closed');
+			} else {
+				p.removeClass('closed');
+				c.sortable('enable').sortable('refresh');
+			}
+		});
+
+		$('#menu-items-left').children('.menu-items-holder-wrap').children('.menu-name').click(function() {
+			$(this).siblings('.menu-item-holder').parent().toggleClass('closed');
+		});
+
+		menus.not('#wp_inactive_menu_items').each(function(){
+			var h = 50, H = $(this).children('.menu-item').length;
+			h = h + parseInt(H * 48, 10);
+			$(this).css( 'minHeight', h + 'px' );
+		});
+
+		$('a.menu-item-action').live('click', function(){
+			var css = {}, menu_item = $(this).closest('div.menu-item'), inside = menu_item.children('.menu-item-inside'), w = parseInt( menu_item.find('input.menu-item-width').val(), 10 );
+			
+			if ( inside.is(':hidden') ) {
+				if ( w > 250 && inside.closest('div.menu-items-sortables').length ) {
+					css['width'] = w + 30 + 'px';
+					if ( inside.closest('div.menu-item-liquid-right').length )
+						css['marginLeft'] = 235 - w + 'px';
+					menu_item.css(css);
+				}
+				wpMenus.fixLabels(menu_item);
+				inside.slideDown('fast');
+			} else {
+				inside.slideUp('fast', function() {
+					menu_item.css({'width':'','marginLeft':''});
+				});
+			}
+			return false;
+		});
+
+		$('input.menu-item-control-save').live('click', function(){
+			wpMenus.save( $(this).closest('div.menu-item'), 0, 1, 0 );
+			return false;
+		});
+
+		$('a.menu-item-control-remove').live('click', function(){
+			wpMenus.save( $(this).closest('div.menu-item'), 1, 1, 0 );
+			return false;
+		});
+
+		$('a.menu-item-control-close').live('click', function(){
+			wpMenus.close( $(this).closest('div.menu-item') );
+			return false;
+		});
+
+		menus.children('.menu-item').each(function() {
+			wpMenus.appendTitle(this);
+			if ( $('p.menu-item-error', this).length )
+				$('a.menu-item-action', this).click();
+		});
+
+		$('#menu-item-list').children('.menu-item').draggable({
+			connectToSortable: 'div.menu-items-sortables',
+			handle: '> .menu-item-top > .menu-item-title',
+			distance: 2,
+			helper: 'clone',
+			zIndex: 5,
+			containment: 'document',
+			start: function(e,ui) {
+				wpMenus.fixWebkit(1);
+				ui.helper.find('div.menu-item-description').hide();
+			},
+			stop: function(e,ui) {
+				if ( rem )
+					$(rem).hide();
+				rem = '';
+				wpMenus.fixWebkit();
+			}
+		});
+
+		menus.sortable({
+			placeholder: 'menu-item-placeholder',
+			items: '> .menu-item',
+			handle: '> .menu-item-top > .menu-item-title',
+			cursor: 'move',
+			distance: 2,
+			containment: 'document',
+			start: function(e,ui) {
+				wpMenus.fixWebkit(1);
+				ui.item.children('.menu-item-inside').hide();
+				ui.item.css({'marginLeft':'','width':''});
+			},
+			stop: function(e,ui) {
+				if ( ui.item.hasClass('ui-draggable') )
+					ui.item.draggable('destroy');
+
+				if ( ui.item.hasClass('deleting') ) {
+					wpMenus.save( ui.item, 1, 0, 1 ); // delete menu item
+					ui.item.remove();
+					return;
+				}
+
+				var sb = $(this).attr('id');
+				
+				ui.item.css({'marginLeft':'','width':''});
+				wpMenus.fixWebkit();
+
+				if ( wpMenus.addItem(ui.item) ) {
+					wpMenus.save( ui.item, 0, 0, 1 );
+					ui.item.find('input.add_new').val('');
+					ui.item.find('a.menu-item-action').click();
+					return;
+				}
+
+				wpMenus.saveOrder(sb);
+			},
+			receive: function(e,ui) {
+				if ( !$(this).is(':visible') )
+					$(this).sortable('cancel');
+			}
+		}).sortable('option', 'connectWith', 'div.menu-items-sortables').parent().filter('.closed').children('.menu-items-sortables').sortable('disable');
+
+		$('#available-menu-items').droppable({
+			tolerance: 'pointer',
+			accept: function(o){
+				return $(o).parent().attr('id') != 'menu-item-list';
+			},
+			drop: function(e,ui) {
+				ui.draggable.addClass('deleting');
+				$('#removing-menu-item').hide().children('span').html('');
+			},
+			over: function(e,ui) {
+				ui.draggable.addClass('deleting');
+				$('div.menu-item-placeholder').hide();
+
+				if ( ui.draggable.hasClass('ui-sortable-helper') )
+					$('#removing-menu-item').show().children('span')
+					.html( ui.draggable.find('div.menu-item-title').children('h4').html() );
+			},
+			out: function(e,ui) {
+				ui.draggable.removeClass('deleting');
+				$('div.menu-item-placeholder').show();
+				$('#removing-menu-item').hide().children('span').html('');
+			}
+		});
+	},
+
+	saveOrder : function(sb) {
+		if ( sb )
+			$('#' + sb).closest('div.menu-items-holder-wrap').find('img.ajax-feedback').css('visibility', 'visible');
+
+		var a = {
+			action: 'menu-items-order',
+			savemenu_items: $('#_wpnonce_menu_items').val(),
+			menus: []
+		};
+
+		$('div.menu-items-sortables').each( function() {
+			a['menus[' + $(this).attr('id') + ']'] = $(this).sortable('toArray').join(',');
+		});
+
+		$.post( ajaxurl, a, function() {
+			$('img.ajax-feedback').css('visibility', 'hidden');
+		});
+
+		this.resize();
+	},
+
+	save : function(menu_item, del, animate, order) {
+		var sb = menu_item.closest('div.menu-items-sortables').attr('id'), data = menu_item.find('form').serialize(), a;
+		menu_item = $(menu_item);
+		$('.ajax-feedback', menu_item).css('visibility', 'visible');
+
+		a = {
+			action: 'save-menu-item',
+			savemenu_items: $('#_wpnonce_menu_items').val(),
+			menu: sb
+		};
+
+		if ( del )
+			a['delete_menu_item'] = 1;
+
+		data += '&' + $.param(a);
+
+		$.post( ajaxurl, data, function(r){
+			var id;
+
+			if ( del ) {
+				if ( !$('input.menu_item_number', menu_item).val() ) {
+					id = $('input.menu-item-id', menu_item).val();
+					$('#available-menu-items').find('input.menu-item-id').each(function(){
+						if ( $(this).val() == id )
+							$(this).closest('div.menu-item').show();
+					});
+				}
+
+				if ( animate ) {
+					order = 0;
+					menu_item.slideUp('fast', function(){
+						$(this).remove();
+						wpMenus.saveOrder();
+					});
+				} else {
+					menu_item.remove();
+					wpMenus.resize();
+				}
+			} else {
+				$('.ajax-feedback').css('visibility', 'hidden');
+				if ( r && r.length > 2 ) {
+					$('div.menu-item-content', menu_item).html(r);
+					wpMenus.appendTitle(menu_item);
+					wpMenus.fixLabels(menu_item);
+				}
+			}
+			if ( order )
+				wpMenus.saveOrder();
+		});
+	},
+
+	appendTitle : function(menu_item) {
+		var title = $('input[id*="-title"]', menu_item);
+		if ( title = title.val() ) {
+			title = title.replace(/<[^<>]+>/g, '').replace(/</g, '&lt;').replace(/>/g, '&gt;');
+			$(menu_item).children('.menu-item-top').children('.menu-item-title').children()
+				.children('.in-menu-item-title').html(': ' + title);
+		}
+	},
+
+	resize : function() {
+		$('div.menu-items-sortables').not('#wp_inactive_menu_items').each(function(){
+			var h = 50, H = $(this).children('.menu-item').length;
+			h = h + parseInt(H * 48, 10);
+			$(this).css( 'minHeight', h + 'px' );
+		});
+	},
+
+    fixWebkit : function(n) {
+        n = n ? 'none' : '';
+        $('body').css({
+			WebkitUserSelect: n,
+			KhtmlUserSelect: n
+		});
+    },
+
+    fixLabels : function(menu_item) {
+		menu_item.children('.menu-item-inside').find('label').each(function(){
+			var f = $(this).attr('for');
+			if ( f && f == $('input', this).attr('id') )
+				$(this).removeAttr('for');
+		});
+	},
+
+    close : function(menu_item) {
+		menu_item.children('.menu-item-inside').slideUp('fast', function(){
+			menu_item.css({'width':'','marginLeft':''});
+		});
+	}
+};
+
+$(document).ready(function($){ wpMenus.init(); });
+
+})(jQuery);
Index: wp-admin/menus.php
===================================================================
--- wp-admin/menus.php	(revision 0)
+++ wp-admin/menus.php	(revision 0)
@@ -0,0 +1,416 @@
+<?php
+/**
+ * Menus administration panel.
+ *
+ * @package WordPress
+ * @subpackage Administration
+ */
+
+/** WordPress Administration Bootstrap */
+require_once( 'admin.php' );
+
+/** WordPress Administration Menus API */
+require_once(ABSPATH . 'wp-admin/includes/menus.php');
+
+if ( ! current_user_can('switch_themes') )
+	wp_die( __( 'Cheatin&#8217; uh?' ));
+
+wp_admin_css( 'menus' );
+
+$menus_access = get_user_setting( 'menus_access' );
+if ( isset($_GET['menus-access']) ) {
+	$menus_access = 'on' == $_GET['menus-access'] ? 'on' : 'off';
+	set_user_setting( 'menus_access', $menus_access );
+}
+
+if ( 'on' == $menus_access )
+	add_filter( 'admin_body_class', create_function('', '{return " menus_access ";}') );
+else
+	wp_enqueue_script('admin-menus');
+
+do_action( 'menu_admin_setup' );
+
+$title = __( 'Menus' );
+$parent_file = 'themes.php';
+
+// register the inactive_menu_items area as menu
+register_menu(array(
+	'name' => __('Inactive Menu Items'),
+	'id' => 'wp_inactive_menu_items',
+	'description' => '',
+	'before_menu' => '',
+	'after_menu' => '',
+));
+
+// These are the menu_items grouped by menu
+$menu_items_map = wp_get_menu_items();
+if ( empty( $menu_items_map ) )
+	$menu_items_map = wp_get_menu_item_defaults();
+
+// look for "lost" menu_items, this has to run at least on each theme change
+function retrieve_menu_items() {
+	global $wp_registered_menu_item_updates, $wp_registered_menus, $menu_items_map, $wp_registered_menu_items;
+
+	$_menus_menu_items = array();
+	$menus = array_keys($wp_registered_menus);
+
+	unset( $menu_items_map['array_version'] );
+
+	$old = array_keys($menu_items_map);
+	sort($old);
+	sort($menus);
+
+	if ( $old == $menus )
+		return;
+
+	// Move the known-good ones first
+	foreach ( $menus as $id ) {
+		if ( array_key_exists( $id, $menu_items_map ) ) {
+			$_menus_menu_items[$id] = $menu_items_map[$id];
+			unset($menu_items_map[$id], $menus[$id]);
+		}
+	}
+
+	// if new theme has less menus than the old theme
+	if ( !empty($menu_items_map) ) {
+		foreach ( $menu_items_map as $lost => $val ) {
+			if ( is_array($val) )
+				$_menus_menu_items['wp_inactive_menu_items'] = array_merge( (array) $_menus_menu_items['wp_inactive_menu_items'], $val );
+		}
+	}
+
+	// discard invalid, theme-specific menu_items from menus
+	$shown_menu_items = array();
+	foreach ( $_menus_menu_items as $menu => $menu_items ) {
+		if ( !is_array($menu_items) )
+			continue;
+
+		$_menu_items = array();
+		foreach ( $menu_items as $menu_item ) {
+			if ( isset($wp_registered_menu_items[$menu_item]) )
+				$_menu_items[] = $menu_item;
+		}
+		$_menus_menu_items[$menu] = $_menu_items;
+		$shown_menu_items = array_merge($shown_menu_items, $_menu_items);
+	}
+
+	$menu_items_map = $_menus_menu_items;
+	unset($_menus_menu_items, $_menu_items);
+
+	// find hidden/lost multi-menu_item instances
+	$lost_menu_items = array();
+	foreach ( $wp_registered_menu_items as $key => $val ) {
+		if ( in_array($key, $shown_menu_items, true) )
+			continue;
+
+		$number = preg_replace('/.+?-([0-9]+)$/', '$1', $key);
+
+		if ( 2 > (int) $number )
+			continue;
+
+		$lost_menu_items[] = $key;
+	}
+
+	$menu_items_map['wp_inactive_menu_items'] = array_merge($lost_menu_items, (array) $menu_items_map['wp_inactive_menu_items']);
+	wp_set_menu_items($menu_items_map);
+}
+retrieve_menu_items();
+
+if ( !count($wp_registered_menus) == 1 ) {
+	// If only "wp_inactive_menu_items" is defined the theme has no menus, die.
+	require_once( 'admin-header.php' );
+?>
+
+	<div class="wrap">
+	<?php screen_icon(); ?>
+	<h2><?php echo esc_html( $title ); ?></h2>
+		<div class="error">
+			<p><?php _e( 'No Menus Defined' ); ?></p>
+		</div>
+		<p><?php _e( 'The theme you are currently using isn&#8217;t menu-aware, meaning that it has no menus that you are able to change. For information on making your theme menu-aware, please <a href="http://codex.wordpress.org/Custom_Menus_In_Themes">follow these instructions</a>.' ); ?></p>
+	</div>
+
+<?php
+	require_once( 'admin-footer.php' );
+	exit;
+}
+
+// We're saving a menu_item without js
+if ( isset($_POST['savemenu_item']) || isset($_POST['removemenu_item']) ) {
+	$menu_item_id = $_POST['menu-item-id'];
+	check_admin_referer("save-delete-menu-item-$menu_item_id");
+
+	$number = isset($_POST['multi_number']) ? (int) $_POST['multi_number'] : '';
+	if ( $number ) {
+		foreach ( $_POST as $key => $val ) {
+			if ( is_array($val) && preg_match('/__i__|%i%/', key($val)) ) {
+				$_POST[$key] = array( $number => array_shift($val) );
+				break;
+			}
+		}
+	}
+
+	$menu_id = $_POST['menu'];
+	$position = isset($_POST[$menu_id . '_position']) ? (int) $_POST[$menu_id . '_position'] - 1 : 0;
+
+	$id_base = $_POST['id_base'];
+	$menu = isset($menu_items_map[$menu_id]) ? $menu_items_map[$menu_id] : array();
+
+	// delete
+	if ( isset($_POST['removemenu_item']) && $_POST['removemenu_item'] ) {
+
+		if ( !in_array($menu_item_id, $menu, true) ) {
+			wp_redirect('menu_items.php?error=0');
+			exit;
+		}
+
+		$menu = array_diff( $menu, array($menu_item_id) );
+		$_POST = array('menu' => $menu_id, 'menu-item-' . $id_base => array(), 'the-menu-item-id' => $menu_item_id, 'delete_menu_item' => '1');
+	}
+
+	$_POST['menu-item-id'] = $menu;
+
+	foreach ( (array) $wp_registered_menu_item_updates as $name => $control ) {
+		if ( $name != $id_base || !is_callable($control['callback']) )
+			continue;
+
+		ob_start();
+			call_user_func_array( $control['callback'], $control['params'] );
+		ob_end_clean();
+
+		break;
+	}
+
+	$menu_items_map[$menu_id] = $menu;
+
+	// remove old position
+	if ( !isset($_POST['delete_menu_item']) ) {
+		foreach ( $menu_items_map as $key => $sb ) {
+			if ( is_array($sb) )
+				$menu_items_map[$key] = array_diff( $sb, array($menu_item_id) );
+		}
+		array_splice( $menu_items_map[$menu_id], $position, 0, $menu_item_id );
+	}
+
+	wp_set_menu_items($menu_items_map);
+	wp_redirect('menu_items.php?message=0');
+	exit;
+}
+
+// Output the menu_item form without js
+if ( isset($_GET['editmenu_item']) && $_GET['editmenu_item'] ) {
+	$menu_item_id = $_GET['editmenu_item'];
+
+	if ( isset($_GET['addnew']) ) {
+		// Default to the first menu
+		$menu = array_shift( $keys = array_keys($wp_registered_menus) );
+
+		if ( isset($_GET['base']) && isset($_GET['num']) ) { // multi-menu_item
+			// Copy minimal info from an existing instance of this menu_item to a new instance
+			foreach ( $wp_registered_menu_item_controls as $control ) {
+				if ( $_GET['base'] === $control['id_base'] ) {
+					$control_callback = $control['callback'];
+					$multi_number = (int) $_GET['num'];
+					$control['params'][0]['number'] = -1;
+					$menu_item_id = $control['id'] = $control['id_base'] . '-' . $multi_number;
+					$wp_registered_menu_item_controls[$control['id']] = $control;
+					break;
+				}
+			}
+		}
+	}
+
+	if ( isset($wp_registered_menu_item_controls[$menu_item_id]) && !isset($control) ) {
+		$control = $wp_registered_menu_item_controls[$menu_item_id];
+		$control_callback = $control['callback'];
+	} elseif ( !isset($wp_registered_menu_item_controls[$menu_item_id]) && isset($wp_registered_menu_items[$menu_item_id]) ) {
+		$name = esc_html( strip_tags($wp_registered_menu_items[$menu_item_id]['name']) );
+	}
+
+	if ( !isset($name) )
+		$name = esc_html( strip_tags($control['name']) );
+
+	if ( !isset($menu) )
+		$menu = isset($_GET['menu']) ? $_GET['menu'] : 'wp_inactive_menu_items';
+
+	if ( !isset($multi_number) )
+		$multi_number = isset($control['params'][0]['number']) ? $control['params'][0]['number'] : '';
+
+	$id_base = isset($control['id_base']) ? $control['id_base'] : $control['id'];
+
+	// show the menu item form
+	$width = ' style="width:' . max($control['width'], 350) . 'px"';
+	$key = isset($_GET['key']) ? (int) $_GET['key'] : 0;
+
+	require_once( 'admin-header.php' ); ?>
+	<div class="wrap">
+	<?php screen_icon(); ?>
+	<h2><?php echo esc_html( $title ); ?></h2>
+	<div class="editmenu_item"<?php echo $width; ?>>
+	<h3><?php printf( __( 'Widget %s' ), $name ); ?></h3>
+
+	<form action="menus.php" method="post">
+	<div class="menu-item-inside">
+<?php
+	if ( is_callable( $control_callback ) )
+		call_user_func_array( $control_callback, $control['params'] );
+	else
+		echo '<p>' . __('There are no options for this menu item.') . "</p>\n"; ?>
+	</div>
+
+	<p class="describe"><?php _e('Select both the menu for this menu item and the position of the menu item in that menu.'); ?></p>
+	<div class="menu-item-position">
+	<table class="widefat"><thead><tr><th><?php _e('menu'); ?></th><th><?php _e('Position'); ?></th></tr></thead><tbody>
+<?php
+	foreach ( $wp_registered_menus as $sbname => $sbvalue ) {
+		echo "\t\t<tr><td><label><input type='radio' name='menu' value='" . esc_attr($sbname) . "'" . checked( $sbname, $menu, false ) . " /> $sbvalue[name]</label></td><td>";
+		if ( 'wp_inactive_menu_items' == $sbname ) {
+			echo '&nbsp;';
+		} else {
+			if ( !isset($menu_items_map[$sbname]) || !is_array($menu_items_map[$sbname]) ) {
+				$j = 1;
+				$menu_items_map[$sbname] = array();
+			} else {
+				$j = count($menu_items_map[$sbname]);
+				if ( isset($_GET['addnew']) || !in_array($menu_item_id, $menu_items_map[$sbname], true) )
+					$j++;
+			}
+			$selected = '';
+			echo "\t\t<select name='{$sbname}_position'>\n";
+			echo "\t\t<option value=''>" . __('-- select --') . "</option>\n";
+			for ( $i = 1; $i <= $j; $i++ ) {
+				if ( in_array($menu_item_id, $menu_items_map[$sbname], true) )
+					$selected = selected( $i, $key + 1, false );
+				echo "\t\t<option value='$i'$selected> $i </option>\n";
+			}
+			echo "\t\t</select>\n";
+		}
+		echo "</td></tr>\n";
+	} ?>
+	</tbody></table>
+	</div>
+
+	<div class="menu-item-control-actions">
+<?php	if ( isset($_GET['addnew']) ) { ?>
+	<a href="menus.php" class="button alignleft"><?php _e('Cancel'); ?></a>
+<?php	} else { ?>
+	<input type="submit" name="removemenu_item" class="button alignleft" value="<?php esc_attr_e('Delete'); ?>" />
+<?php	} ?>
+	<input type="submit" name="savemenu_item" class="button-primary alignright" value="<?php esc_attr_e('Save Widget'); ?>" />
+	<input type="hidden" name="menu-item-id" class="menu-item-id" value="<?php echo esc_attr($menu_item_id); ?>" />
+	<input type="hidden" name="id_base" class="id_base" value="<?php echo esc_attr($id_base); ?>" />
+	<input type="hidden" name="multi_number" class="multi_number" value="<?php echo esc_attr($multi_number); ?>" />
+<?php	wp_nonce_field("save-delete-menu-item-$menu_item_id"); ?>
+	<br class="clear" />
+	</div>
+	</form>
+	</div>
+	</div>
+<?php
+	require_once( 'admin-footer.php' );
+	exit;
+}
+
+$messages = array(
+	__('Changes saved.')
+);
+
+$errors = array(
+	__('Error while saving.'),
+	__('Error in displaying the menu item settings form.')
+);
+
+require_once( 'admin-header.php' ); ?>
+
+<div class="wrap">
+<?php screen_icon(); ?>
+<h2><?php echo esc_html( $title ); ?></h2>
+
+<?php if ( isset($_GET['message']) && isset($messages[$_GET['message']]) ) { ?>
+<div id="message" class="updated"><p><?php echo $messages[$_GET['message']]; ?></p></div>
+<?php } ?>
+<?php if ( isset($_GET['error']) && isset($errors[$_GET['error']]) ) { ?>
+<div id="message" class="error"><p><?php echo $errors[$_GET['error']]; ?></p></div>
+<?php } ?>
+
+<div class="menu-item-liquid-left">
+<div id="menu-items-left">
+	<div id="special-menu-items" class="menu-items-holder-wrap">
+		<div class="menu-name">
+		<div class="menu-name-arrow"><br /></div>
+		<h3><?php _e('Special Menu Items'); ?> <span id="removing-menu-item"><?php _e('Deactivate'); ?> <span></span></span></h3></div>
+		<div class="menu-item-holder">
+		<p class="description"><?php _e('Select menu items from here to add them to the currently open menu on the right.'); ?></p>
+		<div id="menu-item-dropdowns">
+			<div id="page-dropdown" class="menu-item-dropdown">
+				<p><?php _e('Add a page:'); ?></p>
+				<?php wp_dropdown_pages(array('name' => 'category-dropdown', 'hide_if_empty' => false, 'orderby' => 'name', 'hierarchical' => true, 'show_option_none' => ' ')); ?>
+			</div>
+			<div id="category-dropdown" class="menu-item-dropdown">
+				<p><?php _e('Add a category:'); ?></p>
+				<?php wp_dropdown_categories(array('name' => 'category-dropdown', 'hide_empty' => 0, 'hide_if_empty' => false, 'orderby' => 'name', 'hierarchical' => true, 'show_option_none' => ' ')); ?>
+			</div>
+		</div>
+
+		<br class='clear' />
+		</div>
+		<br class="clear" />
+	</div>
+
+	<div id="available-menu-items" class="menu-items-holder-wrap">
+		<div class="menu-name">
+		<div class="menu-name-arrow"><br /></div>
+		<h3><?php _e('Available Menu Items'); ?> <span id="removing-menu-item"><?php _e('Deactivate'); ?> <span></span></span></h3></div>
+		<div class="menu-item-holder">
+		<p class="description"><?php _e('Drag menu items from here to a menu on the right to activate them. Drag menu items back here to deactivate them and delete their settings.'); ?></p>
+		<div id="menu-item-list">
+		<?php wp_list_menu_items(); ?>
+		</div>
+		<br class='clear' />
+		</div>
+		<br class="clear" />
+	</div>
+
+	<div class="menu-items-holder-wrap">
+		<div class="menu-name">
+		<div class="menu-name-arrow"><br /></div>
+		<h3><?php _e('Inactive Menu Items'); ?>
+		<span><img src="images/wpspin_light.gif" class="ajax-feedback" title="" alt="" /></span></h3></div>
+		<div class="menu-item-holder inactive">
+		<p class="description"><?php _e('Drag menu items here to remove them from the menu but keep their settings.'); ?></p>
+		<?php wp_list_menu_item_controls('wp_inactive_menu_items'); ?>
+		<br class="clear" />
+		</div>
+	</div>
+</div>
+</div>
+
+<div class="menu-item-liquid-right">
+<div id="menu-items-right">
+<?php
+$i = 0;
+foreach ( $wp_registered_menus as $menu => $registered_menu ) {
+	if ( 'wp_inactive_menu_items' == $menu )
+		continue;
+	$closed = $i ? ' closed' : ''; ?>
+	<div class="menu-items-holder-wrap<?php echo $closed; ?>">
+	<div class="menu-name">
+	<div class="menu-name-arrow"><br /></div>
+	<h3><?php echo esc_html( $registered_menu['name'] ); ?>
+	<span><img src="images/wpspin_dark.gif" class="ajax-feedback" title="" alt="" /></span></h3></div>
+	<?php wp_list_menu_item_controls( $menu ); // Show the control forms for each of the menu_items in this menu ?>
+	</div>
+<?php
+	$i++;
+} ?>
+</div>
+</div>
+<form action="" method="post">
+<?php wp_nonce_field( 'save-menu-items', '_wpnonce_menu_items', false ); ?>
+</form>
+<br class="clear" />
+</div>
+
+<?php
+do_action( 'menu_admin_page' );
+require_once( 'admin-footer.php' );
Index: wp-admin/css/menus.dev.css
===================================================================
--- wp-admin/css/menus.dev.css	(revision 0)
+++ wp-admin/css/menus.dev.css	(revision 0)
@@ -0,0 +1,379 @@
+html,
+body {
+	min-width: 950px;
+}
+
+/* 2 column liquid layout */
+div.menu-item-liquid-left {
+	float: left;
+	clear: left;
+	width: 100%;
+	margin-right: -325px;
+}
+
+div#menu-items-left {
+	margin-left: 5px;
+	margin-right: 325px;
+}
+
+div#menu-items-right {
+	width: 285px;
+	margin: 0 auto;
+}
+
+div.menu-item-liquid-right {
+	float: right;
+	clear: right;
+	width: 300px;
+}
+
+.menu-item-liquid-right .menu-item,
+#wp_inactive_menu_items .menu-item,
+.menu-item-liquid-right .menu-description {
+	width: 250px;
+	margin: 0 auto 20px;
+	overflow: hidden;
+}
+
+.menu-item-liquid-right .menu-description {
+	margin-bottom: 10px;
+}
+
+#wp_inactive_menu_items .menu-item {
+	float: left;
+}
+
+div.menu-name h3 {
+	margin: 0;
+	padding: 5px 12px;
+	font-size: 13px;
+	height: 19px;
+	overflow: hidden;
+	white-space: nowrap;
+}
+
+div.menu-name {
+	background-repeat: repeat-x;
+	background-position: 0 0;
+	cursor: pointer;
+	font-size: 13px;
+	border-width: 1px;
+	border-style: solid;
+	-moz-border-radius-topleft: 8px;
+	-moz-border-radius-topright: 8px;
+	-webkit-border-top-right-radius: 8px;
+	-webkit-border-top-left-radius: 8px;
+	-khtml-border-top-right-radius: 8px;
+	-khtml-border-top-left-radius: 8px;
+	border-top-right-radius: 8px;
+	border-top-left-radius: 8px;
+}
+
+.js .closed .menu-name {
+	-moz-border-radius-bottomleft: 8px;
+	-moz-border-radius-bottomright: 8px;
+	-webkit-border-bottom-right-radius: 8px;
+	-webkit-border-bottom-left-radius: 8px;
+	-khtml-border-bottom-right-radius: 8px;
+	-khtml-border-bottom-left-radius: 8px;
+	border-bottom-right-radius: 8px;
+	border-bottom-left-radius: 8px;
+}
+
+.menu-item-liquid-right .menu-items-sortables,
+#menu-items-left .menu-item-holder {
+	border-width: 0 1px 1px;
+	border-style: none solid solid;
+    -moz-border-radius-bottomleft: 8px;
+	-moz-border-radius-bottomright: 8px;
+	-webkit-border-bottom-right-radius: 8px;
+	-webkit-border-bottom-left-radius: 8px;
+	-khtml-border-bottom-right-radius: 8px;
+	-khtml-border-bottom-left-radius: 8px;
+	border-bottom-right-radius: 8px;
+	border-bottom-left-radius: 8px;
+}
+
+.js .closed .menu-items-sortables,
+.js .closed .menu-item-holder {
+	display: none;
+}
+
+.menu-item-liquid-right .menu-items-sortables {
+	padding: 15px 0 0;
+}
+
+#menu-item-list,
+#wp_inactive_menu_items {
+	padding:0 5px;
+}
+
+#wp_inactive_menu_items .menu-item {
+	margin: 0 10px 15px;
+}
+
+#menu-item-list .menu-item {
+	width: 250px;
+	margin: 0 10px 15px;
+	border: 0 none;
+	float: left;
+}
+
+#menu-item-list .menu-item-description {
+	padding: 5px 8px;
+}
+
+#menu-item-list .menu-item-top {
+	border-width: 1px;
+	border-style: solid;
+	-moz-border-radius: 6px;
+	-khtml-border-radius: 6px;
+	-webkit-border-radius: 6px;
+	border-radius: 6px;
+}
+
+.menu-item-placeholder {
+	border-width: 1px;
+	border-style: dashed;
+	margin: 0 auto 20px;
+	height: 26px;
+	width: 250px;
+}
+
+#wp_inactive_menu_items .menu-item-placeholder {
+	margin: 0 10px 20px;
+	float: left;
+}
+
+div.menu-items-holder-wrap {
+	padding: 0;
+	margin: 10px 0 20px;
+}
+
+#menu-items-left #available-menu-items {
+	background-color: transparent;
+	border: 0 none;
+}
+
+ul#menu-item-list {
+	list-style: none;
+	margin: 0;
+	padding: 0;
+	min-height: 100px;
+}
+
+.menu-item .menu-item-top {
+	font-size: 12px;
+	font-weight: bold;
+	height: 26px;
+	overflow: hidden;
+}
+
+.menu-item-top .menu-item-title {
+	padding: 5px 9px;
+}
+
+.menu-item-top .menu-item-title-action {
+	float: right;
+}
+
+a.menu-item-action {
+	display: block;
+	width: 24px;
+	height: 26px;
+}
+
+#available-menu-items a.menu-item-action {
+	display: none;
+}
+
+.menu-item-top a.menu-item-action {
+	background: url("../images/menu-bits.gif") no-repeat scroll 0 -110px;
+}
+
+.menu-item .menu-item-inside,
+.menu-item .menu-item-description {
+	padding: 12px 12px 10px;
+	font-size: 11px;
+	line-height: 16px;
+}
+
+.menu-item-inside,
+.menu-item-description {
+	display: none;
+}
+
+#available-menu-items .menu-item-description {
+	display: block;
+}
+
+.menu-item .menu-item-inside p {
+	margin: 0 0 1em;
+	padding: 0;
+}
+
+.menu-item-title h4 {
+	margin: 0;
+	line-height: 1.3;
+	overflow: hidden;
+	white-space: nowrap;
+}
+
+.menu-items-sortables {
+	min-height: 90px;
+}
+
+.menu-item-control-actions {
+	margin-top: 8px;
+}
+
+.menu-item-control-actions a {
+	text-decoration: none;
+}
+
+.menu-item-control-actions a:hover {
+	text-decoration: underline;
+}
+
+.menu-item-control-actions .ajax-feedback {
+	padding-bottom: 3px;
+}
+
+.menu-item-control-actions div.alignleft {
+	margin-top: 6px;
+}
+
+div#menu-info {
+	padding: 0 1em;
+	margin-bottom: 1em;
+	font-size: 11px;
+}
+
+.menu-item-title a,
+.menu-item-title a:hover {
+	text-decoration: none;
+	border-bottom: none;
+}
+
+.menu-item-control-edit {
+	display: block;
+	font-size: 11px;
+	font-weight: normal;
+	line-height: 26px;
+	padding: 0 8px 0 0;
+}
+
+a.menu-item-control-edit {
+	text-decoration: none;
+}
+
+.menu-item-control-edit .add,
+.menu-item-control-edit .edit {
+	display: none;
+}
+
+#available-menu-items .menu-item-control-edit .add,
+#menu-items-right .menu-item-control-edit .edit,
+#wp_inactive_menu_items .menu-item-control-edit .edit {
+	display: inline;
+}
+
+.editmenu-item {
+	margin: 0 auto 15px;
+}
+
+.editmenu-item .menu-item-inside {
+	display: block;
+	border-width: 1px;
+	border-style: solid;
+	padding: 10px;
+	-moz-border-radius: 6px;
+	-khtml-border-radius: 6px;
+	-webkit-border-radius: 6px;
+	border-radius: 6px;
+}
+
+.menu-item-holder {
+	padding-top: 2px;
+}
+
+.menu-item-holder p.description {
+	margin: 5px 15px 8px;
+}
+
+.menu-item-position {
+	margin-top: 8px;
+}
+
+.menu-name-arrow {
+	float: right;
+	height: 29px;
+	width: 26px;
+}
+
+#menu-item-dropdowns {
+	padding: 0;
+}
+
+.menu-item-dropdown {
+	float:left;
+	margin:0 15px 20px 15px;
+}
+
+.menu-item-dropdown p {
+	margin-top: .5em;
+}
+
+.menu-item-title .in-menu-item-title {
+	font-size: 11px;
+	white-space: nowrap;
+}
+
+#removing-menu-item {
+	display: none;
+	font-weight: normal;
+	padding-left: 15px;
+	font-size: 12px;
+}
+
+.menu-item-control-noform,
+#access-off,
+.menu-items_access .menu-item-action,
+.menu-items_access .menu-name-arrow,
+.menu-items_access #access-on,
+.menu-items_access .menu-item-holder .description {
+	display: none;
+}
+
+.menu-items_access .menu-item-holder,
+.menu-items_access #menu-item-list {
+	padding-top: 10px;
+}
+
+.menu-items_access #access-off {
+	display: inline;
+}
+
+.menu-items_access #wpbody-content .menu-item-title-action,
+.menu-items_access #wpbody-content .menu-item-control-edit,
+.menu-items_access .closed .menu-items-sortables,
+.menu-items_access .closed .menu-item-holder {
+	display: block;
+}
+
+.menu-items_access .closed .menu-name {
+	-moz-border-radius-bottomleft: 0;
+	-moz-border-radius-bottomright: 0;
+	-webkit-border-bottom-right-radius: 0;
+	-webkit-border-bottom-left-radius: 0;
+	-khtml-border-bottom-right-radius: 0;
+	-khtml-border-bottom-left-radius: 0;
+	border-bottom-right-radius: 0;
+	border-bottom-left-radius: 0;
+}
+
+.menu-items_access .menu-name,
+.menu-items_access .menu-item .menu-item-top {
+	cursor: default;
+}
+
Index: wp-admin/css/colors-fresh.dev.css
===================================================================
--- wp-admin/css/colors-fresh.dev.css	(revision 12749)
+++ wp-admin/css/colors-fresh.dev.css	(working copy)
@@ -3,7 +3,8 @@
 }
 
 * html input,
-* html .widget {
+* html .widget, 
+* html .menu-item {
 	border-color: #dfdfdf;
 }
 
@@ -131,6 +132,7 @@
 }
 
 .widget .widget-top,
+.menu-item .menu-item-top,
 .postbox h3,
 .stuffbox h3 {
 	background: #dfdfdf url("../images/gray-grad.png") repeat-x left top;
@@ -644,7 +646,9 @@
 }
 
 .widget,
-#widget-list .widget-top,
+.menu-item,
+#widget-list .widget-top, 
+#menu-item-list .menu-item-top,
 .postbox,
 #titlediv,
 #poststuff .postarea,
@@ -652,7 +656,8 @@
 	border-color: #dfdfdf;
 }
 
-.widget,
+.widget, 
+.menu-item,
 .postbox {
 	background-color: #fff;
 }
@@ -661,7 +666,8 @@
 	color: #464646;
 }
 
-.widget .widget-top,
+#widget-list .widget-top, 
+#menu-item-list .menu-item-top,
 .ui-sortable .postbox h3:hover {
 	color: #000;
 }
@@ -741,6 +747,7 @@
 .file-error,
 abbr.required,
 .widget-control-remove:hover,
+.menu-item-control-remove:hover,
 table.widefat .delete a:hover,
 table.widefat .trash a:hover,
 table.widefat .spam a:hover,
@@ -1014,7 +1021,8 @@
 #editorcontainer,
 #post-status-info,
 #titlediv #title,
-.editwidget .widget-inside {
+.editwidget .widget-inside,
+.editmenu-item .menu-item-inside {
 	border-color: #dfdfdf;
 }
 
@@ -1616,24 +1624,30 @@
 }
 
 div.widgets-sortables,
-#widgets-left .inactive {
+div.menu-items-sortables,
+#widgets-left .inactive,
+#menu-items-left .inactive {
 	background-color: #f1f1f1;
 	border-color: #ddd;
 }
 
-#available-widgets .widget-holder {
+#available-widgets .widget-holder,
+#special-menu-items .menu-item-holder,
+#available-menu-items .menu-item-holder {
 	background-color: #fff;
 	border-color: #ddd;
 }
 
-#widgets-left .sidebar-name {
+#widgets-left .sidebar-name, 
+#menu-items-left .menu-name {
 	background-color: #aaa;
 	background-image: url(../images/ed-bg.gif);
 	text-shadow: #fff 0 1px 0;
 	border-color: #dfdfdf;
 }
 
-#widgets-right .sidebar-name {
+#widgets-right .sidebar-name,
+#menu-items-right .menu-name {
 	background-image: url(../images/fav.png);
 	text-shadow: #3f3f3f 0 -1px 0;
 	background-color: #636363;
@@ -1642,27 +1656,34 @@
 }
 
 .sidebar-name:hover,
-#removing-widget {
+.menu-name:hover,
+#removing-widget,
+#removing-menu-item {
 	color: #d54e21;
 }
 
-#removing-widget span {
+#removing-widget span,
+#removing-menu-item span {
 	color: black;
 }
 
-#widgets-left .sidebar-name-arrow {
+#widgets-left .sidebar-name-arrow,
+#menu-items-left .menu-name-arrow {
 	background: transparent url(../images/menu-bits.gif) no-repeat scroll left -109px;
 }
 
-#widgets-right .sidebar-name-arrow {
+#widgets-right .sidebar-name-arrow,
+#menu-items-right .menu-name-arrow {
 	background: transparent url(../images/fav-arrow.gif) no-repeat scroll 0 -1px;
 }
 
-.in-widget-title {
+.in-widget-title,
+.in-menu-item-title {
 	color: #606060;
 }
 
-.deleting .widget-title * {
+.deleting .widget-title *,
+.deleting .menu-item-title * {
 	color: #aaa;
 }
 
Index: wp-admin/css/menus-rtl.css
===================================================================
--- wp-admin/css/menus-rtl.css	(revision 0)
+++ wp-admin/css/menus-rtl.css	(revision 0)
@@ -0,0 +1,11 @@
+
+ul#menu-item-list li.menu-item-list-item div.menu-item-description {
+	margin: 0 200px 0 0;
+	padding: 0 4em 0 0;
+}
+.menu-item-control-save,
+.menu-item-control-remove {
+	margin-right: 0;
+	margin-left: 8px;
+	float: right;
+}
Index: wp-admin/css/wp-admin.dev.css
===================================================================
--- wp-admin/css/wp-admin.dev.css	(revision 12749)
+++ wp-admin/css/wp-admin.dev.css	(working copy)
@@ -1653,6 +1653,7 @@
 }
 
 .widget .widget-top,
+.menu-item .menu-item-top,
 .postbox h3 {
 	cursor: move;
 	-webkit-user-select: none;
@@ -1700,6 +1701,7 @@
 }
 
 .widget,
+.menu-item,
 .postbox,
 .stuffbox {
 	margin-bottom: 20px;
@@ -1713,6 +1715,7 @@
 }
 
 .widget .widget-top,
+.menu-item .menu-item-top,
 .postbox h3,
 .postbox h3,
 .stuffbox h3 {
