     }
 
     /**
+     * Actually pop up the menu. This can be used instead of show().
+     */
+    public function popUp (
+        trigger :DisplayObject, popUpwards :Boolean = true) :void
+    {
+        var r :Rectangle = trigger.getBounds(trigger.stage);
+
+        if (popUpwards) {
+            show(r.x, 0);
+            // then, reposition the y once we know our size
+            y = r.y - getExplicitOrMeasuredHeight();
+
+        } else {
+            // simply position it below the trigger
+            show(r.x, r.y + r.height);
+        }
+    }
+
+    /**
      * Callback for MenuEvent.ITEM_CLICK.
      */
     protected function itemClicked (event :MenuEvent) :void
     {
-        event.stopImmediatePropagation();
-        var element :Array = (event.item as Array);
-
-        CommandEvent.dispatch(mx_internal::parentDisplayObject,
-            String(element[2]), element[3]);
+        var cmd :String = getItemCommand(event.item);
+        if (cmd != null) {
+            event.stopImmediatePropagation();
+            var arg :Object = getItemArgument(event.item);
+            CommandEvent.dispatch(mx_internal::parentDisplayObject, cmd, arg);
+        }
     }
 
-    // our function for retrieving a label for a menu entry
-    protected function getLabelFor (obj :Object) :String
+    /**
+     * Get the command for the specified item, if any.
+     * Somewhat similar to bits in the DefaultDataDescriptor.
+     */
+    protected function getItemCommand (item :Object) :String
     {
-        var element :Array = (obj as Array);
-        return String(element[0]);
+        try {
+            if (item is XML) {
+                return String(item.@command);
+
+            } else if (item is Object) {
+                return String(item.command);
+            }
+        } catch (e :Error) {
+            // fall through
+        }
+
+        return null;
     }
 
-    // our function for retrieving an icon for a menu entry
-    protected function getIconFor (obj :Object) :Class
+    /**
+     * Get the command for the specified item, if any.
+     * Somewhat similar to bits in the DefaultDataDescriptor.
+     */
+    protected function getItemArgument (item :Object) :Object
     {
-        var element :Array = (obj as Array);
-        return Class(element[1]);
+        try {
+            if (item is XML) {
+                return item.@arg;
+
+            } else if (item is Object) {
+                return item.arg;
+            }
+        } catch (e :Error) {
+            // fall through
+        }
+
+        return null;
     }
 }
 }

package com.threerings.mx.controls {

import flash.display.DisplayObjectContainer;

import mx.controls.Menu;
import mx.core.mx_internal;

     * Factory method to create a command menu.
     *
     * @param parent The parent of this menu.
     * @param items an array of menu items.
     */
    public static function createMenu (
        parent :DisplayObjectContainer, items :Array) :CommandMenu
    {
        var menu :CommandMenu = new CommandMenu();
        menu.tabEnabled = false;
