Index: test/keystrokes/gtk-demo/role_combo_box.py
===================================================================
--- test/keystrokes/gtk-demo/role_combo_box.py	(revision 3372)
+++ test/keystrokes/gtk-demo/role_combo_box.py	(working copy)
@@ -52,7 +52,7 @@
     "Warning combo box item Where Am I",
     ["BRAILLE LINE:  'gtk-demo Application Combo boxes Frame Some stock icons Panel  ComboWarning Warning'",
      "     VISIBLE:  'Warning', cursor=1",
-     "SPEECH OUTPUT: ' menu'",
+     "SPEECH OUTPUT: 'menu'",
      "SPEECH OUTPUT: 'Warning'",
      "SPEECH OUTPUT: ''",
      "SPEECH OUTPUT: 'item 1 of 5'",
@@ -81,7 +81,7 @@
     "New combo box item Where Am I",
     ["BRAILLE LINE:  'gtk-demo Application Combo boxes Frame Some stock icons Panel  ComboWarning New'",
      "     VISIBLE:  'New', cursor=1",
-     "SPEECH OUTPUT: ' menu'",
+     "SPEECH OUTPUT: 'menu'",
      "SPEECH OUTPUT: 'New'",
      "SPEECH OUTPUT: ''",
      "SPEECH OUTPUT: 'item 3 of 5'",
Index: test/keystrokes/gtk-demo/role_push_button.py
===================================================================
--- test/keystrokes/gtk-demo/role_push_button.py	(revision 3372)
+++ test/keystrokes/gtk-demo/role_push_button.py	(working copy)
@@ -60,7 +60,7 @@
      "     VISIBLE:  'OK Button', cursor=1",
      "SPEECH OUTPUT: 'OK'",
      "SPEECH OUTPUT: 'button'",
-     "SPEECH OUTPUT: ' Alt o'"]))
+     "SPEECH OUTPUT: 'Alt o'"]))
 
 ########################################################################
 # Tab to the Cancel button.
Index: test/keystrokes/gtk-demo/role_check_box.py
===================================================================
--- test/keystrokes/gtk-demo/role_check_box.py	(revision 3372)
+++ test/keystrokes/gtk-demo/role_check_box.py	(working copy)
@@ -49,7 +49,7 @@
     ["BRAILLE LINE:  'gtk-demo Application Panes Frame Horizontal Panel < > Resize CheckBox'",
      "     VISIBLE:  '< > Resize CheckBox', cursor=1",
      "SPEECH OUTPUT: 'Resize check box not checked'",
-     "SPEECH OUTPUT: ' Alt r'"]))
+     "SPEECH OUTPUT: 'Alt r'"]))
 
 ########################################################################
 # Now, change its state.
@@ -78,7 +78,7 @@
     ["BRAILLE LINE:  'gtk-demo Application Panes Frame Horizontal Panel <x> Resize CheckBox'",
      "     VISIBLE:  '<x> Resize CheckBox', cursor=1",
      "SPEECH OUTPUT: 'Resize check box checked'",
-     "SPEECH OUTPUT: ' Alt r'"]))
+     "SPEECH OUTPUT: 'Alt r'"]))
 
 ########################################################################
 # Change the state back and move on to a few more check boxes.  The
Index: test/keystrokes/gtk-demo/role_radio_button.py
===================================================================
--- test/keystrokes/gtk-demo/role_radio_button.py	(revision 3372)
+++ test/keystrokes/gtk-demo/role_radio_button.py	(working copy)
@@ -52,7 +52,7 @@
      "SPEECH OUTPUT: 'All radio button'",
      "SPEECH OUTPUT: 'selected'",
      "SPEECH OUTPUT: 'item 1 of 3'",
-     "SPEECH OUTPUT: ' Alt a'"]))
+     "SPEECH OUTPUT: 'Alt a'"]))
 
 ########################################################################
 # Down arrow to the "Range" radio button.
@@ -90,7 +90,7 @@
      "SPEECH OUTPUT: 'Range radio button'",
      "SPEECH OUTPUT: 'selected'",
      "SPEECH OUTPUT: 'item 3 of 3'",
-     "SPEECH OUTPUT: ' Alt n'"]))
+     "SPEECH OUTPUT: 'Alt n'"]))
 
 ########################################################################
 # Put everything back and close the demo.
Index: test/keystrokes/gtk-demo/role_combo_box2.py
===================================================================
--- test/keystrokes/gtk-demo/role_combo_box2.py	(revision 3372)
+++ test/keystrokes/gtk-demo/role_combo_box2.py	(working copy)
@@ -57,7 +57,7 @@
      "SPEECH OUTPUT: 'combo box'",
      "SPEECH OUTPUT: 'All sheets'",
      "SPEECH OUTPUT: 'item 1 of 3'",
-     "SPEECH OUTPUT: ' Alt o'"]))
+     "SPEECH OUTPUT: 'Alt o'"]))
 
 ########################################################################
 # Down arrow to select the "Even sheets" item in the combo box.
@@ -89,7 +89,7 @@
      "SPEECH OUTPUT: 'combo box'",
      "SPEECH OUTPUT: 'Even sheets'",
      "SPEECH OUTPUT: 'item 2 of 3'",
-     "SPEECH OUTPUT: ' Alt o'"]))
+     "SPEECH OUTPUT: 'Alt o'"]))
 
 ########################################################################
 # Put things back the way they were and close the demo.
Index: test/keystrokes/gtk-demo/role_menu.py
===================================================================
--- test/keystrokes/gtk-demo/role_menu.py	(revision 3372)
+++ test/keystrokes/gtk-demo/role_menu.py	(working copy)
@@ -49,12 +49,12 @@
     "File menu Where Am I",
     ["BRAILLE LINE:  'gtk-demo Application Application Window Frame File Menu'",
      "     VISIBLE:  'File Menu', cursor=1",
-     "SPEECH OUTPUT: ' menu bar'",
+     "SPEECH OUTPUT: 'menu bar'",
      "SPEECH OUTPUT: 'File'",
      "SPEECH OUTPUT: 'menu'",
      "SPEECH OUTPUT: ''",
      "SPEECH OUTPUT: 'item 1 of 3'",
-     "SPEECH OUTPUT: 'Alt f'"]))
+     "SPEECH OUTPUT: 'f'"]))
 
 ########################################################################
 # Right arrow to the "Preferences" menu.
@@ -80,12 +80,12 @@
     "Preferences menu Where Am I",
     ["BRAILLE LINE:  'gtk-demo Application Application Window Frame Preferences Menu'",
      "     VISIBLE:  'Preferences Menu', cursor=1",
-     "SPEECH OUTPUT: ' menu bar'",
+     "SPEECH OUTPUT: 'menu bar'",
      "SPEECH OUTPUT: 'Preferences'",
      "SPEECH OUTPUT: 'menu'",
      "SPEECH OUTPUT: ''",
      "SPEECH OUTPUT: 'item 2 of 3'",
-     "SPEECH OUTPUT: 'Alt p'"]))
+     "SPEECH OUTPUT: 'p'"]))
 
 ########################################################################
 # Go down to the "Color" menu.
Index: test/keystrokes/gtk-demo/role_spin_button.py
===================================================================
--- test/keystrokes/gtk-demo/role_spin_button.py	(revision 3372)
+++ test/keystrokes/gtk-demo/role_spin_button.py	(working copy)
@@ -67,7 +67,7 @@
      "SPEECH OUTPUT: 'Hue:'",
      "SPEECH OUTPUT: 'spin button'",
      "SPEECH OUTPUT: '240'",
-     "SPEECH OUTPUT: ' Alt h'"]))
+     "SPEECH OUTPUT: 'Alt h'"]))
 
 ########################################################################
 # Do an extended "Where Am I" via double KP_Enter.
@@ -86,11 +86,11 @@
      "SPEECH OUTPUT: 'Hue:'",
      "SPEECH OUTPUT: 'spin button'",
      "SPEECH OUTPUT: '240'",
-     "SPEECH OUTPUT: ' Alt h'",
+     "SPEECH OUTPUT: 'Alt h'",
      "SPEECH OUTPUT: 'Hue:'",
      "SPEECH OUTPUT: 'spin button'",
      "SPEECH OUTPUT: '240'",
-     "SPEECH OUTPUT: ' Alt h'"]))
+     "SPEECH OUTPUT: 'Alt h'"]))
 
 ########################################################################
 # Change the value by arrowing down.
@@ -163,7 +163,7 @@
      "SPEECH OUTPUT: 'Hue:'",
      "SPEECH OUTPUT: 'spin button'",
      "SPEECH OUTPUT: '240'",
-     "SPEECH OUTPUT: ' Alt h'"]))
+     "SPEECH OUTPUT: 'Alt h'"]))
 
 ########################################################################
 # Close the Color Chooser dialog
Index: test/keystrokes/gtk-demo/role_text_multiline.py
===================================================================
--- test/keystrokes/gtk-demo/role_text_multiline.py	(revision 3372)
+++ test/keystrokes/gtk-demo/role_text_multiline.py	(working copy)
@@ -32,7 +32,7 @@
 
 sequence.append(WaitForFocus(acc_role=pyatspi.ROLE_TEXT))
 sequence.append(utils.StartRecordingAction())
-sequence.append(TypeAction("This is a test.", 500))
+sequence.append(TypeAction("This is a test.", 500, 500))
 sequence.append(KeyComboAction("Return", 500))
 sequence.append(utils.AssertPresentationAction(
     "Typing",
Index: src/orca/speechgenerator.py
===================================================================
--- src/orca/speechgenerator.py	(revision 3372)
+++ src/orca/speechgenerator.py	(working copy)
@@ -161,21 +161,12 @@
         Returns a list of utterances to be spoken.
         """
 
-        result = self._script.getAcceleratorAndShortcut(obj)
-
-        accelerator = result[0]
-        #shortcut = result[1]
-
         utterances = []
 
-        # [[[TODO: WDW - various stuff preserved while we work out the
-        # desired verbosity here.]]]
-        #
-        #if len(shortcut) > 0:
-        #    utterances.append(_("shortcut") + " " + shortcut)
-        #    utterances.append(accelerator)
+        result = self._script.getKeyBinding(obj)
+        accelerator = result[2]
+
         if len(accelerator) > 0:
-            #utterances += (_("accelerator") + " " + accelerator)
             utterances.append(accelerator)
 
         return utterances
Index: src/orca/default.py
===================================================================
--- src/orca/default.py	(revision 3372)
+++ src/orca/default.py	(working copy)
@@ -5505,60 +5505,74 @@
 
         return nodes
 
-    def getAcceleratorAndShortcut(self, obj):
-        """Gets the accelerator string (and possibly shortcut) for the given
-        object.
+    def getKeyBinding(self, obj):
+        """Gets the mnemonic, accelerator string and possibly shortcut
+        for the given object.  These are based upon the first accessible
+        action for the object.
 
         Arguments:
         - obj: the Accessible object
 
-        A list containing the accelerator and shortcut for the given object,
-        where the first element is the accelerator and the second element is
-        the shortcut.
+      
+        Returns: list containing strings: [mnemonic, accelerator, shortcut]
         """
 
         try:
             action = obj.queryAction()
         except NotImplementedError:
-            return ["", ""]
+            return ["", "", ""]
 
-        # [[[TODO: WDW - assumes the first keybinding is all that we care about.
-        # Logged as bugzilla bug 319741.]]]
+        # Action is a string in the format, where the mnemonic and/or
+        # accelerator can be missing.
         #
+        # <mnemonic>;<full-path>;<accelerator>
+        #
+        # The keybindings in <full-path> should be separated by ":"
+        #
         bindingStrings = action.getKeyBinding(0).split(';')
 
-        # [[[TODO: WDW - assumes menu items have three bindings.  Logged as
-        # bugzilla bug 319741.]]]
-        #
         if len(bindingStrings) == 3:
-            #mnemonic       = bindingStrings[0]
+            mnemonic       = bindingStrings[0]
             fullShortcut   = bindingStrings[1]
             accelerator    = bindingStrings[2]
         elif len(bindingStrings) > 0:
+            mnemonic       = ""
             fullShortcut   = bindingStrings[0]
             try:
                 accelerator = bindingStrings[1]
             except:
                 accelerator = ""
         else:
+            mnemonic       = ""
             fullShortcut   = ""
             accelerator    = ""
 
         fullShortcut = fullShortcut.replace("<","")
         fullShortcut = fullShortcut.replace(">"," ")
-        fullShortcut = fullShortcut.replace(":"," ")
+        fullShortcut = fullShortcut.replace(":"," ").strip()
 
-        # If the accelerator string includes a Space, make sure we speak it.
+        # If the accelerator or mnemonic strings includes a Space,
+        # make sure we speak it.
         #
+        if mnemonic.endswith(" "):
+            # Translators: this is the spoken word for the space character
+            #
+            mnemonic += _("space")
+        mnemonic = mnemonic.replace("<","")
+        mnemonic = mnemonic.replace(">"," ").strip()
+
         if accelerator.endswith(" "):
             # Translators: this is the spoken word for the space character
             #
             accelerator += _("space")
-        accelerator  = accelerator.replace("<","")
-        accelerator  = accelerator.replace(">"," ")
+        accelerator = accelerator.replace("<","")
+        accelerator = accelerator.replace(">"," ").strip()
 
-        return [accelerator, fullShortcut]
+        debug.println(debug.LEVEL_FINEST, "default.getKeyBinding: " \
+                      + repr([mnemonic, fullShortcut, accelerator]))
 
+        return [mnemonic, fullShortcut, accelerator]
+
     def getKnownApplications(self):
         """Retrieves the list of currently running apps for the desktop
         as a list of Accessible objects.
Index: src/orca/where_am_I.py
===================================================================
--- src/orca/where_am_I.py	(revision 3372)
+++ src/orca/where_am_I.py	(working copy)
@@ -70,7 +70,7 @@
            \n  label=%s \
            \n  name=%s \
            \n  role=%s \
-           \n  mnemonics=%s \
+           \n  keybinding=%s \
            \n  parent label= %s \
            \n  parent name=%s \
            \n  parent role=%s \
@@ -79,7 +79,7 @@
             (self._getObjLabel(obj),
              self._getObjName(obj),
              obj.getRoleName(),
-             self._script.getAcceleratorAndShortcut(obj),
+             self._script.getKeyBinding(obj),
              self._getObjLabel(obj.parent),
              self._getObjName(obj.parent),
              obj.parent.getRoleName(),
@@ -160,7 +160,7 @@
         1. label
         2. role
         3. state
-        4. mnemonic (i.e. Alt plus the underlined letter), if any
+        4. accelerator (i.e. Alt plus the underlined letter), if any
         """
 
         utterances = []
@@ -169,8 +169,8 @@
         text = text + " " + self._getCheckBoxState(obj)
         utterances.append(text)
 
-        text = self._getObjMnemonic(obj)
-        utterances.append(text)
+        accelerator = self._getObjAccelerator(obj)
+        utterances.append(accelerator)
 
         debug.println(self._debugLevel, "check box utterances=%s" \
                       % utterances)
@@ -185,7 +185,7 @@
         3. role
         4. state
         5. relative position
-        6. mnemonic (i.e. Alt plus the underlined letter), if any
+        6. accelerator (i.e. Alt plus the underlined letter), if any
         """
 
         utterances = []
@@ -217,7 +217,7 @@
         text = self._getPositionInGroup(obj)
         utterances.append(text)
 
-        text = self._getObjMnemonic(obj)
+        text = self._getObjAccelerator(obj)
         utterances.append(text)
 
         debug.println(self._debugLevel, "radio button utterances=%s" % \
@@ -232,7 +232,7 @@
         2. role
         3. current value
         4. relative position
-        5. mnemonic (i.e. Alt plus the underlined letter), if any
+        5. accelerator (i.e. Alt plus the underlined letter), if any
         """
 
         utterances = []
@@ -249,8 +249,8 @@
         text = self._getPositionInList(obj[0], name)
         utterances.append(text)
 
-        text = self._getObjMnemonic(obj)
-        utterances.append(text)
+        accelerator = self._getObjAccelerator(obj)
+        utterances.append(accelerator)
 
         debug.println(self._debugLevel, "combo box utterances=%s" % \
                       utterances)
@@ -263,7 +263,7 @@
         1. label
         2. role
         3. current value
-        4. mnemonic (i.e. Alt plus the underlined letter), if any
+        4. accelerator (i.e. Alt plus the underlined letter), if any
         """
 
         utterances = []
@@ -276,7 +276,7 @@
         name = self._getObjName(obj)
         utterances.append(name)
         
-        text = self._getObjMnemonic(obj)
+        text = self._getObjAccelerator(obj)
         utterances.append(text)
 
         debug.println(self._debugLevel, "spin button utterances=%s" % \
@@ -289,7 +289,7 @@
 
         1. label
         2. role
-        3. mnemonic (i.e. Alt plus the underlined letter), if any
+        3. accelerator (i.e. Alt plus the underlined letter), if any
         """
 
         utterances = []
@@ -299,7 +299,7 @@
         text = rolenames.getSpeechForRoleName(obj)
         utterances.append(text)
 
-        text = self._getObjMnemonic(obj)
+        text = self._getObjAccelerator(obj)
         utterances.append(text)
 
         debug.println(self._debugLevel, "push button utterances=%s" % \
@@ -314,7 +314,7 @@
         2. role
         3. value
         4. percentage (if possible)
-        5. mnemonic (i.e. Alt plus the underlined letter), if any
+        5. accelerator (i.e. Alt plus the underlined letter), if any
         """
 
         utterances = []
@@ -330,7 +330,7 @@
         #
         utterances.append(_("%s percent") % values[1])
 
-        text = self._getObjMnemonic(obj)
+        text = self._getObjAccelerator(obj)
         utterances.append(text)
 
         debug.println(self._debugLevel, "slider utterances=%s" % \
@@ -344,15 +344,15 @@
 
         1. Name of the menu containing the item, followed by its role
         2. item name, followed by its role (if a menu) followed by its
-        accelerator key, if any
+        accelerator key binding, if any
         3. relative position
-        4. mnemonic (i.e. Alt plus the underlined letter), if any
+        4. mnemonic (i.e. the underlined letter), if any
         """
 
         utterances = []
         text = self.getObjLabelAndName(obj.parent) + " " + \
                rolenames.getSpeechForRoleName(obj.parent)
-        utterances.append(text)
+        utterances.append(text.strip())
 
         text = self.getObjLabelAndName(obj)
         utterances.append(text)
@@ -391,24 +391,19 @@
                 text = _("not selected")
             utterances.append(text)
 
-        text = self._getObjAccelerator(obj)
+        text = self._getObjAccelerator(obj, False, False)
         utterances.append(text)
 
         name = self._getObjName(obj)
         text = self._getPositionInList(obj.parent, name)
         utterances.append(text)
 
-        text = self._getObjShortcut(obj)
+        if obj.parent \
+           and obj.parent.getRole() in [pyatspi.ROLE_MENU, 
+                                        pyatspi.ROLE_MENU_BAR]:
+            text = self._getObjMnemonic(obj)
+            utterances.append(text)
 
-        # The object's shortcut will be the full list of keys (e.g.
-        # Alt FO for the open menu item in the File menu). We only
-        # want to speak the shortcut associated with the menu item.
-        #
-        if text and obj.parent and obj.parent.getRole() == pyatspi.ROLE_MENU:
-            text = text[-1]
-        
-        utterances.append(text)
-
         debug.println(self._debugLevel, "menu item utterances=%s" % \
                       utterances)
         speech.speakUtterances(utterances)
@@ -420,7 +415,7 @@
         1. role
         2. label + 'page'
         3. relative position
-        4. mnemonic (i.e. Alt plus the underlined letter), if any
+        4. accelerator (i.e. Alt plus the underlined letter), if any
         """
 
         utterances = []
@@ -436,7 +431,7 @@
         text = self._getPositionInList(obj.parent, name)
         utterances.append(text)
 
-        text = self._getObjMnemonic(obj)
+        text = self._getObjAccelerator(obj)
         utterances.append(text)
 
         debug.println(self._debugLevel, "page utterances=%s" % \
@@ -455,7 +450,7 @@
             attibute information before  (bold "text")
             by 'selected' (single press)
             C. if the current line is blank/empty, 'blank'
-        4. mnemonic (i.e. Alt plus the underlined letter), if any
+        4. accelerator (i.e. Alt plus the underlined letter), if any
 
         Gaim, gedit, OpenOffice Writer and Terminal
         """
@@ -496,7 +491,7 @@
             text = Q_("text|selected")
             utterances.append(text)
 
-        text = self._getObjMnemonic(obj)
+        text = self._getObjAccelerator(obj)
         utterances.append(text)
 
         debug.println(self._debugLevel, "text utterances=%s" % \
@@ -609,7 +604,8 @@
         utterances = []
 
         text = self._getObjLabel(obj)
-        utterances.append(text)
+        if text:
+            utterances.append(text)
 
         text = rolenames.getSpeechForRoleName(obj)
         utterances.append(text)
@@ -658,7 +654,6 @@
     def _speakParagraph(self, obj, doubleClick):
         """Speak a paragraph object.
         """
-
         self._speakText(obj, doubleClick)
 
     def _speakIconPanel(self, obj, doubleClick):
@@ -1001,45 +996,37 @@
 
         return text
 
-    def _getObjMnemonic(self, obj):
-        """Returns the accellerator and/or shortcut for the object,
-        if either exists.
-        """
-
-        results = self._script.getAcceleratorAndShortcut(obj)
-
-        text = ""
-        if not results[1]:
-            text = results[0]
-        else:
-            text = results[0] + " " +  results[1]
-
-        return text
-
-    def _getObjAccelerator(self, obj):
+    def _getObjAccelerator(self,
+                           obj, 
+                           fallbackToMnemonic=True,
+                           fallbackToFullPath=True):
         """Returns the accelerator for the object, if it exists.
         """
 
-        results = self._script.getAcceleratorAndShortcut(obj)
+        # We'll try the real accelerator first, but fallback to the
+        # mnemonic if there is no accelerator.  This is done because
+        # some implementations, such as the Java platform, will
+        # only give us the mnemonic sometimes.
+        #
+        results = self._script.getKeyBinding(obj)
+        if results[2]:
+            return results[2]
 
-        text = ""
-        if results[0]:
-            text = results[0]
+        mnemonic = results[0]
+        if mnemonic and fallbackToMnemonic:
+            return mnemonic
 
-        return text
+        if fallbackToFullPath:
+            return results[1]
 
-    def _getObjShortcut(self, obj):
-        """Returns the shortcut for the object, if it exists.
+        return ""
+
+    def _getObjMnemonic(self, obj):
+        """Returns the mnemonic (a letter) for the object, if it exists.
         """
+        results = self._script.getKeyBinding(obj)
+        return results[0][-1:]
 
-        results = self._script.getAcceleratorAndShortcut(obj)
-
-        text = ""
-        if results[1]:
-            text = results[1]
-
-        return text
-
     def _getSliderValues(self, obj):
         """Returns the slider's current value and percentage.
         """
Index: src/orca/braillegenerator.py
===================================================================
--- src/orca/braillegenerator.py	(revision 3372)
+++ src/orca/braillegenerator.py	(working copy)
@@ -164,21 +164,10 @@
 
         if settings.brailleVerbosityLevel == settings.VERBOSITY_LEVEL_VERBOSE:
             text = ""
-
-            result = self._script.getAcceleratorAndShortcut(obj)
-
-            accelerator = result[0]
-            #shortcut = result[1]
-
+            result = self._script.getKeyBinding(obj)
+            accelerator = result[2]
             if len(accelerator) > 0:
                 text += "(" + accelerator + ")"
-
-            # [[[TODO: WDW - various stuff preserved while we work out the
-            # desired verbosity here.]]]
-            #
-            #if len(shortcut) > 0:
-            #    text += "(" + shortcut + ")"
-
             return text
         else:
             return None
