Index: test/keystrokes/firefox/dojo_slider.py
===================================================================
--- test/keystrokes/firefox/dojo_slider.py	(revision 4092)
+++ test/keystrokes/firefox/dojo_slider.py	(working copy)
@@ -25,9 +25,9 @@
 sequence.append(WaitForFocus("Dojo Slider Widget Demo", acc_role=pyatspi.ROLE_DOCUMENT_FRAME))
 
 ########################################################################
-# Give the widget a moment to construct itself
+# Give the widget plenty of time to construct itself. 
 #
-sequence.append(PauseAction(5000))
+sequence.append(PauseAction(7000))
 
 ########################################################################
 # Tab to the first slider.  The following will be presented.
Index: test/keystrokes/firefox/sayAll_bugzilla_search.py
===================================================================
--- test/keystrokes/firefox/sayAll_bugzilla_search.py	(revision 4092)
+++ test/keystrokes/firefox/sayAll_bugzilla_search.py	(working copy)
@@ -66,16 +66,16 @@
      "SPEECH OUTPUT: 'text'",
      "SPEECH OUTPUT: 'Search button'",
      "SPEECH OUTPUT: 'Classification:'",
-     "SPEECH OUTPUT: 'multi-select List with 8 items'",
+     "SPEECH OUTPUT: 'Admin multi-select List with 8 items'",
      "SPEECH OUTPUT: 'Product:'",
-     "SPEECH OUTPUT: 'multi-select List with 379 items'",
+     "SPEECH OUTPUT: 'accerciser multi-select List with 379 items'",
      "SPEECH OUTPUT: 'Component link'",
      "SPEECH OUTPUT: ':'",
-     "SPEECH OUTPUT: 'multi-select List with 1248 items'",
+     "SPEECH OUTPUT: 'abiscan multi-select List with 1248 items'",
      "SPEECH OUTPUT: 'Version:'",
-     "SPEECH OUTPUT: 'multi-select List with 857 items'",
+     "SPEECH OUTPUT: '0.0.1 multi-select List with 857 items'",
      "SPEECH OUTPUT: 'Target Milestone:'",
-     "SPEECH OUTPUT: 'multi-select List with 555 items'",
+     "SPEECH OUTPUT: '--- multi-select List with 555 items'",
      "SPEECH OUTPUT: 'A Comment:'",
      "SPEECH OUTPUT: 'contains the string combo box'",
      "SPEECH OUTPUT: 'text'",
@@ -88,15 +88,16 @@
      "SPEECH OUTPUT: 'text'",
      "SPEECH OUTPUT: 'separator'",
      "SPEECH OUTPUT: 'Status:'",
-     "SPEECH OUTPUT: 'multi-select List with 8 items'",
+     "SPEECH OUTPUT: 'UNCONFIRMED multi-select List with 8 items'",
      "SPEECH OUTPUT: 'Resolution:'",
-     "SPEECH OUTPUT: 'multi-select List with 12 items'",
+     "SPEECH OUTPUT: 'FIXED multi-select List with 12 items'",
      "SPEECH OUTPUT: 'Severity:'",
-     "SPEECH OUTPUT: 'multi-select List with 7 items'",
+     "SPEECH OUTPUT: 'blocker multi-select List with 7 items'",
      "SPEECH OUTPUT: 'Priority:'",
-     "SPEECH OUTPUT: 'multi-select List with 5 items'",
+     "SPEECH OUTPUT: 'Immediate multi-select List with 5 items'",
      "SPEECH OUTPUT: 'OS:'",
-     "SPEECH OUTPUT: 'multi-select List with 21 items'",
+     "SPEECH OUTPUT: 'All multi-select List with 21 items'",
+     "SPEECH OUTPUT: 'Email and Numbering'",
      "SPEECH OUTPUT: 'Any one of:'",
      "SPEECH OUTPUT: 'check box checked'",
      "SPEECH OUTPUT: ' the bug assignee'",
@@ -128,18 +129,19 @@
      "SPEECH OUTPUT: 'bugs numbered:'",
      "SPEECH OUTPUT: 'text'",
      "SPEECH OUTPUT: '(comma-separated list)'",
+     "SPEECH OUTPUT: 'Bug Changes'",
      "SPEECH OUTPUT: 'Only bugs changed between:'",
      "SPEECH OUTPUT: 'text'",
      "SPEECH OUTPUT: ' and text Now  ",
      "(YYYY-MM-DD or relative dates)'",
      "SPEECH OUTPUT: 'where one or more of the following changed:'",
-     "SPEECH OUTPUT: 'multi-select List with 26 items'",
+     "SPEECH OUTPUT: '[Bug creation] multi-select List with 26 items'",
      "SPEECH OUTPUT: 'and the new value was:'",
      "SPEECH OUTPUT: 'text'",
      "SPEECH OUTPUT: 'GNOME version:'",
-     "SPEECH OUTPUT: 'multi-select List with 14 items'",
+     "SPEECH OUTPUT: 'Unspecified multi-select List with 14 items'",
      "SPEECH OUTPUT: 'GNOME target:'",
-     "SPEECH OUTPUT: 'multi-select List with 12 items'",
+     "SPEECH OUTPUT: 'Unspecified multi-select List with 12 items'",
      "SPEECH OUTPUT: 'Sort results by: Reuse same sort as last time combo box'",
      "SPEECH OUTPUT: 'Search button'",
      "SPEECH OUTPUT: '    check box not checked  and remember these as my default search options'",
Index: test/keystrokes/firefox/sayAll_html_test_page.py
===================================================================
--- test/keystrokes/firefox/sayAll_html_test_page.py	(revision 4092)
+++ test/keystrokes/firefox/sayAll_html_test_page.py	(working copy)
@@ -38,7 +38,7 @@
 sequence.append(KeyComboAction("KP_Add"))
 sequence.append(utils.AssertPresentationAction(
     "KP_Add to do a SayAll",
-    [     "SPEECH OUTPUT: 'Test Formats link'",
+    ["SPEECH OUTPUT: 'Test Formats link'",
      "SPEECH OUTPUT: '",
      " Alignment Text link ",
      " Indent Text link ",
@@ -51,19 +51,7 @@
      "",
      " separator link Text Formats",
      "",
-     "This sentence is bold. This sentence is italicized. This sentence is underlined. This sentence uses strikethrough. This sentence has the words sentence in superscript. This sentence has the word sentence in subscript. This is a Heading 1. heading  '",
-     "SPEECH OUTPUT: 'level 1'",
-     "SPEECH OUTPUT: 'This is a Heading 2. heading  '",
-     "SPEECH OUTPUT: 'level 2'",
-     "SPEECH OUTPUT: 'This is a Heading 3. heading  '",
-     "SPEECH OUTPUT: 'level 3'",
-     "SPEECH OUTPUT: 'This is a Heading 4. heading  '",
-     "SPEECH OUTPUT: 'level 4'",
-     "SPEECH OUTPUT: 'This is a Heading 5. heading  '",
-     "SPEECH OUTPUT: 'level 5'",
-     "SPEECH OUTPUT: 'This is a Heading 6. heading  '",
-     "SPEECH OUTPUT: 'level 6'",
-     "SPEECH OUTPUT: 'This sentence is in Arial font. 1This sentence is in Comic Sans MSl font. ",
+     "This sentence is bold. This sentence is italicized. This sentence is underlined. This sentence uses strikethrough. This sentence has the words sentence in superscript. This sentence has the word sentence in subscript. This is a Heading 1. heading level 1 This is a Heading 2. heading level 2 This is a Heading 3. heading level 3 This is a Heading 4. heading level 4 This is a Heading 5. heading level 5 This is a Heading 6. heading level 6 This sentence is in Arial font. 1This sentence is in Comic Sans MSl font. ",
      "2This sentence is in Courier New Font. ",
      "3This sentence is in Garamondl font. ",
      "4This sentence is in Impact font. ",
@@ -74,9 +62,7 @@
      "aThis sentence is in font size 10 on a PC. bThis sentence is green. cThis sentence is in address format. dThis sentence is blinking. eThis sentence contains preformatted plain text.",
      "",
      " separator link Alignment",
-     " From Shakespeare's Hamlet heading  '",
-     "SPEECH OUTPUT: 'level 3'",
-     "SPEECH OUTPUT: 'I have of late but",
+     " From Shakespeare's Hamlet heading level 3 I have of late but",
      "wherefore I know not lost all my mirth,",
      "forgone all custom of exercises;",
      "and indeed, it goes so heavily with",
@@ -152,34 +138,22 @@
      " separator link HTML Form and Widgets",
      "",
      "Textfield : Enter your Name:  text text field using default type=text 1. Enter your Address:  text text field using SIZE and MAXLENGTH 2. Enter your City:  text 3. Enter your State:  text 4. Enter your Country:  text US text field using value 5. Enter your Zip:  text 6. What happens when a fixed-width font(the default) is used for a one-byte text input area, let's try it.. Enter one character:  text  ",
-     " separator  CheckBox: What are your favorite pets? heading  '",
-     "SPEECH OUTPUT: 'level 2'",
-     "SPEECH OUTPUT: 'check box not checked bird ",
+     " separator  CheckBox: What are your favorite pets? heading level 2 check box not checked bird ",
      " check box not checked fish ",
      " check box not checked wild animal ",
      " separator ",
-     "Radio Buttons: Would type of wine do you like? heading  '",
-     "SPEECH OUTPUT: 'level 2'",
-     "SPEECH OUTPUT: 'selected radio button cabernet sauvignon ",
+     "Radio Buttons: Would type of wine do you like? heading level 2 selected radio button cabernet sauvignon ",
      " not selected radio button merlot ",
      " not selected radio button nebbiolo ",
      " not selected radio button pinot noir ",
      " not selected radio button don't drink wine ",
-     " separator  Password Field: Who are you? heading  '",
-     "SPEECH OUTPUT: 'level 2'",
-     "SPEECH OUTPUT: 'Enter your Password: password separator Submit Buttons: heading  '",
-     "SPEECH OUTPUT: 'level 2'",
-     "SPEECH OUTPUT: 'Submit Query button submit button using default \"VALUE\" Click Here button submit button using assigned \"VALUE\", no \"NAME\" Send Out button submit button using assigned \"NAME\" & \"VALUE\" separator Form Multiline Text Areas: heading  '",
-     "SPEECH OUTPUT: 'level 2'",
-     "SPEECH OUTPUT: 'Enter any Comments you have about this Web page following: text multiline text area with default WRAP=NO WRAP text multiline text area with WRAP=SOFT text multiline text area with WRAP=HARD separator Pulldown menus: heading  '",
-     "SPEECH OUTPUT: 'level 2'",
-     "SPEECH OUTPUT: 'Regular Pizza order? Three Cheeses combo box  selection without \"multiple\" act as a pull-down menu Gourmet Pizza order? multi-select List with 7 items  selection with \"multiple\" act as a scrolling list ",
-     "and has a pre-selected \"option\" Extra Pizza Add-On order? List with 6 items  selection with size=3 with/without \"multiple\" act as a scrolling list ",
+     " separator  Password Field: Who are you? heading level 2 Enter your Password: password separator Submit Buttons: heading level 2 Submit Query button submit button using default \"VALUE\" Click Here button submit button using assigned \"VALUE\", no \"NAME\" Send Out button submit button using assigned \"NAME\" & \"VALUE\" separator Form Multiline Text Areas: heading level 2 Enter any Comments you have about this Web page following: text multiline text area with default WRAP=NO WRAP text multiline text area with WRAP=SOFT text multiline text area with WRAP=HARD separator Pulldown menus: heading level 2 Regular Pizza order? Three Cheeses combo box  selection without \"multiple\" act as a pull-down menu Gourmet Pizza order? Vegetarian Gourmet multi-select List with 7 items  selection with \"multiple\" act as a scrolling list ",
+     "and has a pre-selected \"option\" Extra Pizza Add-On order? mushrooms List with 6 items  selection with size=3 with/without \"multiple\" act as a scrolling list ",
      "and has a pre-selected \"option\" Drink order? diet coke combo box separator ",
      " separator link List",
      "",
      "Welcome to a list of lists ",
-     "Lists are not only fun to make, they are fun to use. They help us: 1. remember what the heck we are doing each day 2. arrange long and arbitrary lines of text into ordered lists that are pleasing to the eye and suggest some sense of priority, even if it is artificial 3. look really cool when we carry them around on yellow Post-Its tm. 4. and that other thing I keep forgetting. Your ordered lists can start at a strange number, like VI. And use roman numerals, g. You might try using letters as well, H. Maybe you prefer Big Letters, ix. or small roman numerals • But discs belong to unordered lists 50. Though you can set the value in a list item! Unordered list :   list • listing item   list • first sublevel   list • look for the bullet on   list • each sublevel • they should all be different, except here. • second sublevel • or you can specify a square • if your TYPE is circle • or even a disc • Franz Liszt • was a composer who was not square • would have liked the Who • feeling listless. TYPE=CIRCLE • blah, blah, blah (square) • whine, whine, whine(disc) ",
+     "Lists are not only fun to make, they are fun to use. They help us: 1. remember what the heck we are doing each day 2. arrange long and arbitrary lines of text into ordered lists that are pleasing to the eye and suggest some sense of priority, even if it is artificial 3. look really cool when we carry them around on yellow Post-Its tm. 4. and that other thing I keep forgetting. Your ordered lists can start at a strange number, like VI. And use roman numerals, g. You might try using letters as well, H. Maybe you prefer Big Letters, ix. or small roman numerals • But discs belong to unordered lists 50. Though you can set the value in a list item! Unordered list :   • listing item   • first sublevel   • look for the bullet on   • each sublevel • they should all be different, except here. • second sublevel • or you can specify a square • if your TYPE is circle • or even a disc • Franz Liszt • was a composer who was not square • would have liked the Who • feeling listless. TYPE=CIRCLE • blah, blah, blah (square) • whine, whine, whine(disc) ",
      " separator link Tag",
      "Bold Tag with other Physical Character Style Tags. Bold Tag with : • Big : This line has both Bold tag and the Big tag. (outside the Bold tag) • Blink : This line has both the Bold tag and the Blink tag. (outside the Bold tag) • Font : This line has the Bold tag and the Font face tag set to \"Courier\" ,color=darkgreen and size =-1.(outside the Bold tag) • Italics : Text that is both Bold and Italic. (outside the Bold tag) • Small : This line has both Bold tag and the Small tag; hence I should be smaller !! (outside the Bold tag) • Strikethrough : I should be Bold and Strikethroughed. (outside the Bold tag) • Subscript : I'm bold and I have asubscript • Superscript : I'm bold too and I have a superscript • Typewriter : This line has the Bold tag and the Typewriter tag. (outside the Bold tag) • Underline : I'm bold and I should be underlined. (outside the Bold tag) separator  Bold Tag with Content Character Style Tags Bold Tag with : • Cite : The part after the exclamation is in Cite Tags !!!! (Chitra, 1996) (outside the Bold tag) • Code : #include \"main.h\"(outside the Bold tag) • Definition : The word &ltCharacter Styles> are surrounded by the definition tag. • Emphasis : I am using the Bold and the Emphasis tag. (outside the Bold tag) • Keyboard : Inside bold and keyboard tags. (outside the Bold tag) • Sample : Well !! I'm using the bold and the sample Tag. (outside the Bold tag) • Strong : I have the Bold and the Strong tags around me !!(outside the Bold tag) • Variable : you_tell_me. Yup !! the Bold and Variable tag. (outside the Bold tag) separator Superscript Tag with other Physical Character Style Tags: Superscript Tag with : • Bold : This line has both Bold tag and the Superscript tag. (outside the Superscript tag) • Big : This line has both Big tag andI'm the Superscript. (outside the Superscript tag) • Blink : This line has both the Blink tag and Superscriptt tag. (outside the Superscript tag) • Font : This line has the Superscript tag and the Font face tag set to \"Courier\" ,color=darkgreen and size =-1.(outside the Superscript tag) • Italics : Text that is Italic and has a Superscript.(outside the Superscript tag) • Small : This line has both Superscript tag and the Small tag; hence I should be smaller !!(outside the Superscript tag) • Strikethrough : I should have a Superscript and be Strikethroughed.(outside the Superscript tag) • Subscript : I have a subscript and it has a Superscript • Superscript : I have a superscript and it again has a SUPERSCRIPT • Typewriter : This line has the Superscript tag and the Typewriter tag. (outside the Superscript tag) • Underline : I'm Superscript and I should be underlined. (outside the Superscript tag) separator Superscript Tag with Content Character Style Tags Superscript Tag with : • Cite : The part after the exclamation is in Cite Tags and is a Sup !!!! (Chitra, 1996) (outside the Superscript tag) • Code : I have a Superscript #include \"main.h\"(outside the Superscript tag) • Definition : The word &ltCharacter Styles> are surrounded by the definition tag and is a Sup. • Emphasis : I am using the Superscript and the Emphasis tag. (outside the Superscript tag) • Keyboard : I have the Superscript and keyboard tags. (outside the Superscript tag) • Sample : Well !! I'm using the Superscript and the sample Tag. (outside the Superscript tag) • Strong : I have the Superscript and the Strong tags !!(outside the Superscript tag) • Variable : you_tell_me. Yup !! the Superscript and Variable tag. (outside the Superscript tag) separator link Table",
      "",
@@ -191,9 +165,7 @@
      "SPEECH OUTPUT: 'C D A'",
      "SPEECH OUTPUT: 'a b c d'",
      "SPEECH OUTPUT: 'C D'",
-     "SPEECH OUTPUT: 'separator Table showing text flow: heading  '",
-     "SPEECH OUTPUT: 'level 4'",
-     "SPEECH OUTPUT: 'separator This is text placed above the table and Table Title caption table head table head table head cell 1 cell 2 cell 3 continuing below the table!!! ",
+     "SPEECH OUTPUT: ' separator Table showing text flow: heading level 4 separator This is text placed above the table and Table Title caption table head table head table head cell 1 cell 2 cell 3 continuing below the table!!! ",
      " separator Table Border Tests separator Table showing the default table BORDER=1 :   caption table head table head table head cell 1 cell 2 cell 3 separator ",
      "Tables showing different border values: ",
      "  Table with BORDER=1 caption table head table head table head cell 1 cell 2 cell 3 Table with BORDER=2 caption table head table head table head cell 1 cell 2 cell 3 Table with BORDER=3 caption table head table head table head cell 1 cell 2 cell 3 Table with BORDER=4 caption table head table head table head cell 1 cell 2 cell 3 Table with BORDER=5 caption table head table head table head cell 1 cell 2 cell 3 Table with BORDER=6 caption table head table head table head cell 1 cell 2 cell 3 ",
@@ -207,28 +179,28 @@
      "Table with CELLSPACING=0 & a border:   caption table head table head table head table head table head cell 1 cell 2 cell 3 cell 4 cell 5 separator ",
      "Tables showing different cellspacing values: ",
      "  Table with CELLSPACING=3 caption table head table head table head cell 1 cell 2 cell 3 Table with CELLSPACING=4 caption table head table head table head cell 1 cell 2 cell 3 Table with CELLSPACING=5 caption table head table head table head cell 1 cell 2 cell 3 Table with CELLSPACING=8 caption table head table head table head cell 1 cell 2 cell 3 Table with CELLSPACING=10 caption table head table head table head cell 1 cell 2 cell 3 ",
-     "  Table with CELLSPACING=30 caption table head table head table head cell 1 cell 2 cell 3 separator  Tables Columnspan Test separator Table Header Cells spanning multiple columns:   list   caption Header 1 ",
+     "  Table with CELLSPACING=30 caption table head table head table head cell 1 cell 2 cell 3 separator  Tables Columnspan Test separator Table Header Cells spanning multiple columns:     caption Header 1 ",
      "span=2 cols Header 2 ",
      "span=5 cols Header 3 ",
      "span=10 cols row 1 row 1 row 1 row 1 row 1 row 1 row 1 row 1 row 1 row 1 row 1 row 1 row 1 row 1 row 1 row 1 row 1 row 2 row 2 row 2 row 2 row 2 row 2 row 2 row 2 row 2 row 2 row 2 row 2 row 2 row 2 row 2 row 2 row 2 row 3 row 3 row 3 row 3 row 3 row 3 row 3 row 3 row 3 row 3 row 3 row 3 row 3 row 3 row 3 row 3 row 3 separator ",
-     "Table with data cells spanning multiple columns:   list   caption Head 1 Head 1 Head 1 Head 1 Head 1 Head 1 Head 1 Head 1 Head 1 Head 1 Head 1 Head 1 Head 1 Head 1 Head 1 Head 1 Head 1 Data Cell 1 ",
+     "Table with data cells spanning multiple columns:     caption Head 1 Head 1 Head 1 Head 1 Head 1 Head 1 Head 1 Head 1 Head 1 Head 1 Head 1 Head 1 Head 1 Head 1 Head 1 Head 1 Head 1 Data Cell 1 ",
      "span=2 cols Data Cell 2 ",
      "span=5 cols Data Cell 3 ",
-     "span=10 cols row 1 row 1 row 1 row 1 row 1 row 1 row 1 row 1 row 1 row 1 row 1 row 1 row 1 row 1 row 1 row 1 row 1 row 2 row 2 row 2 row 2 row 2 row 2 row 2 row 2 row 2 row 2 row 2 row 2 row 2 row 2 row 2 row 2 row 2 row 3 row 3 row 3 row 3 row 3 row 3 row 3 row 3 row 3 row 3 row 3 row 3 row 3 row 3 row 3 row 3 row 3 separator Table with nested header & data cells spanning multiple columns:   list   caption Header 1 ",
+     "span=10 cols row 1 row 1 row 1 row 1 row 1 row 1 row 1 row 1 row 1 row 1 row 1 row 1 row 1 row 1 row 1 row 1 row 1 row 2 row 2 row 2 row 2 row 2 row 2 row 2 row 2 row 2 row 2 row 2 row 2 row 2 row 2 row 2 row 2 row 2 row 3 row 3 row 3 row 3 row 3 row 3 row 3 row 3 row 3 row 3 row 3 row 3 row 3 row 3 row 3 row 3 row 3 separator Table with nested header & data cells spanning multiple columns:     caption Header 1 ",
      "span=8 cols Header 2 ",
      "span=10 cols Data Cell 1 ",
      "span=3 cols Data Cell 2 ",
      "span=5 cols Data Cell 3 ",
      "span=7 cols Data Cell 4 ",
      "span=3 cols row 1 row 1 row 1 row 1 row 1 row 1 row 1 row 1 row 1 row 1 row 1 row 1 row 1 row 1 row 1 row 1 row 1 row 1 row 2 row 2 row 2 row 2 row 2 row 2 row 2 row 2 row 2 row 2 row 2 row 2 row 2 row 2 row 2 row 2 row 2 row 2 row 3 row 3 row 3 row 3 row 3 row 3 row 3 row 3 row 3 row 3 row 3 row 3 row 3 row 3 row 3 row 3 row 3 row 3 separator ",
-     "  Tables Rowspan Test separator Table Header Cells spanning multiple rows: list   caption Header 1 ",
+     "  Tables Rowspan Test separator Table Header Cells spanning multiple rows:   caption Header 1 ",
      "span=2 rows col 1 col 2 col 3 col 4 col 5 col 6 col 7 col 8 col 9 col 1 col 2 col 3 col 4 col 5 col 6 col 7 col 8 col 9 Header 2 ",
      "span=5 rows col 1 col 2 col 3 col 4 col 5 col 6 col 7 col 8 col 9 col 1 col 2 col 3 col 4 col 5 col 6 col 7 col 8 col 9 col 1 col 2 col 3 col 4 col 5 col 6 col 7 col 8 col 9 col 1 col 2 col 3 col 4 col 5 col 6 col 7 col 8 col 9 col 1 col 2 col 3 col 4 col 5 col 6 col 7 col 8 col 9 Header 3 ",
-     "span=3 rows col 1 col 2 col 3 col 4 col 5 col 6 col 7 col 8 col 9 col 1 col 2 col 3 col 4 col 5 col 6 col 7 col 8 col 9 col 1 col 2 col 3 col 4 col 5 col 6 col 7 col 8 col 9 separator Table Data Cells spanning multiple rows: list   caption Head Data 1 ",
+     "span=3 rows col 1 col 2 col 3 col 4 col 5 col 6 col 7 col 8 col 9 col 1 col 2 col 3 col 4 col 5 col 6 col 7 col 8 col 9 col 1 col 2 col 3 col 4 col 5 col 6 col 7 col 8 col 9 separator Table Data Cells spanning multiple rows:   caption Head Data 1 ",
      "span=2 rows col 1 col 2 col 3 col 4 col 5 col 6 col 7 col 8 col 9 Head col 1 col 2 col 3 col 4 col 5 col 6 col 7 col 8 col 9 Head Data 2 ",
      "span=5 rows col 1 col 2 col 3 col 4 col 5 col 6 col 7 col 8 col 9 Head col 1 col 2 col 3 col 4 col 5 col 6 col 7 col 8 col 9 Head col 1 col 2 col 3 col 4 col 5 col 6 col 7 col 8 col 9 Head col 1 col 2 col 3 col 4 col 5 col 6 col 7 col 8 col 9 Head col 1 col 2 col 3 col 4 col 5 col 6 col 7 col 8 col 9 Head Data 3 ",
      "span=3 rows col 1 col 2 col 3 col 4 col 5 col 6 col 7 col 8 col 9 Head col 1 col 2 col 3 col 4 col 5 col 6 col 7 col 8 col 9 Head col 1 col 2 col 3 col 4 col 5 col 6 col 7 col 8 col 9 separator ",
-     "Nested Table Header Cells & Data Cells spanning multiple rows:   list   caption Header 1 ",
+     "Nested Table Header Cells & Data Cells spanning multiple rows:     caption Header 1 ",
      "span=7 rows Data 1 ",
      "span=2 rows col 1 col 2 col 3 col 4 col 5 col 6 col 7 col 8 col 9 col 1 col 2 col 3 col 4 col 5 col 6 col 7 col 8 col 9 Data 2 ",
      "span=5 rows col 1 col 2 col 3 col 4 col 5 col 6 col 7 col 8 col 9 col 1 col 2 col 3 col 4 col 5 col 6 col 7 col 8 col 9 col 1 col 2 col 3 col 4 col 5 col 6 col 7 col 8 col 9 col 1 col 2 col 3 col 4 col 5 col 6 col 7 col 8 col 9 col 1 col 2 col 3 col 4 col 5 col 6 col 7 col 8 col 9 Header 2 ",
@@ -253,7 +225,7 @@
      " separator Caption align to bottom of table",
      "",
      "",
-     " Table's caption on the bottom caption gif link image link Checkbox1 check box checked Row1 Column3",
+     " Table's caption on the bottom caption gif link image Checkbox1 check box checked Row1 Column3",
      " Embedded table caption 1Checkbox1 check box checked ",
      " 2 Button button ",
      " 3",
Index: test/keystrokes/firefox/line_nav_wiki.py
===================================================================
--- test/keystrokes/firefox/line_nav_wiki.py	(revision 4092)
+++ test/keystrokes/firefox/line_nav_wiki.py	(working copy)
@@ -53,9 +53,7 @@
     "Line Down",
     ["BRAILLE LINE:  'live.gnome.org h1 Search $l Titles Button Text Button'",
      "     VISIBLE:  'live.gnome.org h1 Search $l Titl', cursor=1",
-     "SPEECH OUTPUT: 'live.gnome.org heading  '",
-     "SPEECH OUTPUT: 'level 1'",
-     "SPEECH OUTPUT: 'text Search Titles button grayed Text button grayed'"]))
+     "SPEECH OUTPUT: 'live.gnome.org heading level 1 text Search Titles button grayed Text button grayed'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
@@ -95,8 +93,7 @@
     "Line Down", 
     ["BRAILLE LINE:  'Welcome to Orca! h1'",
      "     VISIBLE:  'Welcome to Orca! h1', cursor=1",
-     "SPEECH OUTPUT: 'Welcome to Orca! heading  '",
-     "SPEECH OUTPUT: 'level 1'"]))
+     "SPEECH OUTPUT: 'Welcome to Orca! heading level 1'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
@@ -192,8 +189,7 @@
     "Line Down", 
     ["BRAILLE LINE:  'About h1'",
      "     VISIBLE:  'About h1', cursor=1",
-     "SPEECH OUTPUT: 'About heading  '",
-     "SPEECH OUTPUT: 'level 1'"]))
+     "SPEECH OUTPUT: 'About heading level 1'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
@@ -239,7 +235,7 @@
 sequence.append(KeyComboAction("Down"))
 sequence.append(utils.AssertPresentationAction(
     "Line Down", 
-    [ "BRAILLE LINE:  'been led by the Accessibility Program Office of Sun Microsystems, Inc. Link'",
+    ["BRAILLE LINE:  'been led by the Accessibility Program Office of Sun Microsystems, Inc. Link'",
      "     VISIBLE:  'been led by the Accessibility Pr', cursor=1",
      "SPEECH OUTPUT: 'been led by the Accessibility Program Office of Sun Microsystems, Inc. link'"]))
 
@@ -297,8 +293,7 @@
     "Line Down", 
     ["BRAILLE LINE:  'Audio Guides h1'",
      "     VISIBLE:  'Audio Guides h1', cursor=1",
-     "SPEECH OUTPUT: 'Audio Guides heading  '",
-     "SPEECH OUTPUT: 'level 1'"]))
+     "SPEECH OUTPUT: 'Audio Guides heading level 1'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
@@ -354,8 +349,7 @@
     "Line Down", 
     ["BRAILLE LINE:  'Download/Installation h1'",
      "     VISIBLE:  'Download/Installation h1', cursor=1",
-     "SPEECH OUTPUT: 'Download/Installation heading  '",
-     "SPEECH OUTPUT: 'level 1'"]))
+     "SPEECH OUTPUT: 'Download/Installation heading level 1'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
@@ -395,8 +389,7 @@
     "Line Down", 
     ["BRAILLE LINE:  'Configuration/Use h1'",
      "     VISIBLE:  'Configuration/Use h1', cursor=1",
-     "SPEECH OUTPUT: 'Configuration/Use heading  '",
-     "SPEECH OUTPUT: 'level 1'"]))
+     "SPEECH OUTPUT: 'Configuration/Use heading level 1'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
@@ -484,8 +477,7 @@
     "Line Down",
     ["BRAILLE LINE:  'Accessible Applications h1'",
      "     VISIBLE:  'Accessible Applications h1', cursor=1",
-     "SPEECH OUTPUT: 'Accessible Applications heading  '",
-     "SPEECH OUTPUT: 'level 1'"]))
+     "SPEECH OUTPUT: 'Accessible Applications heading level 1'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
@@ -581,8 +573,7 @@
     "Line Down",
     ["BRAILLE LINE:  'How Can I Help? h1'",
      "     VISIBLE:  'How Can I Help? h1', cursor=1",
-     "SPEECH OUTPUT: 'How Can I Help? heading  '",
-     "SPEECH OUTPUT: 'level 1'"]))
+     "SPEECH OUTPUT: 'How Can I Help? heading level 1'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
@@ -598,8 +589,7 @@
     "Line Down",
     ["BRAILLE LINE:  'More Information h1'",
      "     VISIBLE:  'More Information h1', cursor=1",
-     "SPEECH OUTPUT: 'More Information heading  '",
-     "SPEECH OUTPUT: 'level 1'"]))
+     "SPEECH OUTPUT: 'More Information heading level 1'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
@@ -719,8 +709,7 @@
     "Line Down",
     ["BRAILLE LINE:  'User h3'",
      "     VISIBLE:  'User h3', cursor=1",
-     "SPEECH OUTPUT: 'User heading  '",
-     "SPEECH OUTPUT: 'level 3'"]))
+     "SPEECH OUTPUT: 'User heading level 3'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
@@ -736,8 +725,7 @@
     "Line Down",
     ["BRAILLE LINE:  'Page h3'",
      "     VISIBLE:  'Page h3', cursor=1",
-     "SPEECH OUTPUT: 'Page heading  '",
-     "SPEECH OUTPUT: 'level 3'"]))
+     "SPEECH OUTPUT: 'Page heading level 3'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
@@ -778,8 +766,7 @@
     "Line Down",
     ["BRAILLE LINE:  'GNOME World Wide h3'",
      "     VISIBLE:  'GNOME World Wide h3', cursor=1",
-     "SPEECH OUTPUT: 'GNOME World Wide heading  '",
-     "SPEECH OUTPUT: 'level 3'"]))
+     "SPEECH OUTPUT: 'GNOME World Wide heading level 3'"]))
 
 ########################################################################
 # Up Arrow to the Top.
@@ -823,8 +810,7 @@
     "Line Up",
     ["BRAILLE LINE:  'Page h3'",
      "     VISIBLE:  'Page h3', cursor=1",
-     "SPEECH OUTPUT: 'Page heading  '",
-     "SPEECH OUTPUT: 'level 3'"]))
+     "SPEECH OUTPUT: 'Page heading level 3'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
@@ -840,8 +826,7 @@
     "Line Up",
     ["BRAILLE LINE:  'User h3'",
      "     VISIBLE:  'User h3', cursor=1",
-     "SPEECH OUTPUT: 'User heading  '",
-     "SPEECH OUTPUT: 'level 3'"]))
+     "SPEECH OUTPUT: 'User heading level 3'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
@@ -961,8 +946,7 @@
     "Line Up",
     ["BRAILLE LINE:  'More Information h1'",
      "     VISIBLE:  'More Information h1', cursor=1",
-     "SPEECH OUTPUT: 'More Information heading  '",
-     "SPEECH OUTPUT: 'level 1'"]))
+     "SPEECH OUTPUT: 'More Information heading level 1'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
@@ -978,8 +962,7 @@
     "Line Up",
     ["BRAILLE LINE:  'How Can I Help? h1'",
      "     VISIBLE:  'How Can I Help? h1', cursor=1",
-     "SPEECH OUTPUT: 'How Can I Help? heading  '",
-     "SPEECH OUTPUT: 'level 1'"]))
+     "SPEECH OUTPUT: 'How Can I Help? heading level 1'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
@@ -1075,8 +1058,7 @@
     "Line Up",
     ["BRAILLE LINE:  'Accessible Applications h1'",
      "     VISIBLE:  'Accessible Applications h1', cursor=1",
-     "SPEECH OUTPUT: 'Accessible Applications heading  '",
-     "SPEECH OUTPUT: 'level 1'"]))
+     "SPEECH OUTPUT: 'Accessible Applications heading level 1'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
@@ -1164,8 +1146,7 @@
     "Line Up", 
     ["BRAILLE LINE:  'Configuration/Use h1'",
      "     VISIBLE:  'Configuration/Use h1', cursor=1",
-     "SPEECH OUTPUT: 'Configuration/Use heading  '",
-     "SPEECH OUTPUT: 'level 1'"]))
+     "SPEECH OUTPUT: 'Configuration/Use heading level 1'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
@@ -1205,8 +1186,7 @@
     "Line Up", 
     ["BRAILLE LINE:  'Download/Installation h1'",
      "     VISIBLE:  'Download/Installation h1', cursor=1",
-     "SPEECH OUTPUT: 'Download/Installation heading  '",
-     "SPEECH OUTPUT: 'level 1'"]))
+     "SPEECH OUTPUT: 'Download/Installation heading level 1'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
@@ -1262,8 +1242,7 @@
     "Line Up", 
     ["BRAILLE LINE:  'Audio Guides h1'",
      "     VISIBLE:  'Audio Guides h1', cursor=1",
-     "SPEECH OUTPUT: 'Audio Guides heading  '",
-     "SPEECH OUTPUT: 'level 1'"]))
+     "SPEECH OUTPUT: 'Audio Guides heading level 1'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
@@ -1367,8 +1346,7 @@
     "Line Up", 
     ["BRAILLE LINE:  'About h1'",
      "     VISIBLE:  'About h1', cursor=1",
-     "SPEECH OUTPUT: 'About heading  '",
-     "SPEECH OUTPUT: 'level 1'"]))
+     "SPEECH OUTPUT: 'About heading level 1'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
@@ -1464,8 +1442,7 @@
     "Line Up", 
     ["BRAILLE LINE:  'Welcome to Orca! h1'",
      "     VISIBLE:  'Welcome to Orca! h1', cursor=1",
-     "SPEECH OUTPUT: 'Welcome to Orca! heading  '",
-     "SPEECH OUTPUT: 'level 1'"]))
+     "SPEECH OUTPUT: 'Welcome to Orca! heading level 1'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
@@ -1505,9 +1482,7 @@
     "Line Up",
     ["BRAILLE LINE:  'live.gnome.org h1 Search $l Titles Button Text Button'",
      "     VISIBLE:  'live.gnome.org h1 Search $l Titl', cursor=1",
-     "SPEECH OUTPUT: 'live.gnome.org heading  '",
-     "SPEECH OUTPUT: 'level 1'",
-     "SPEECH OUTPUT: 'text Search Titles button grayed Text button grayed'"]))
+     "SPEECH OUTPUT: 'live.gnome.org heading level 1 text Search Titles button grayed Text button grayed'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
Index: test/keystrokes/firefox/sayAll_enter_bug.py
===================================================================
--- test/keystrokes/firefox/sayAll_enter_bug.py	(revision 4092)
+++ test/keystrokes/firefox/sayAll_enter_bug.py	(working copy)
@@ -52,8 +52,7 @@
      "SPEECH OUTPUT: 'New bug link'",
      "SPEECH OUTPUT: ' · Browse link  · Search link  · Reports link  · Account link  · Admin link  · Help link'",
      "SPEECH OUTPUT: 'Logged In joanmarie.diggs@gmail.com | Log Out link'",
-     "SPEECH OUTPUT: 'Enter Bug: orca – This page lets you enter a new bug into Bugzilla. heading  '",
-     "SPEECH OUTPUT: 'level 1'",
+     "SPEECH OUTPUT: 'Enter Bug: orca – This page lets you enter a new bug into Bugzilla. heading level 1'",
      "SPEECH OUTPUT: 'blank'",
      "SPEECH OUTPUT: 'Before reporting a bug, please read the bug writing guidelines link , please look at the list of most frequently reported bugs link , and please search link  or browse link  for the bug.'",
      "SPEECH OUTPUT: 'blank'",
@@ -62,10 +61,10 @@
      "SPEECH OUTPUT: 'Product:'",
      "SPEECH OUTPUT: 'orca'",
      "SPEECH OUTPUT: 'Version:'",
-     "SPEECH OUTPUT: 'List with 9 items'",
+     "SPEECH OUTPUT: '2.21.x List with 9 items'",
      "SPEECH OUTPUT: 'Component link'",
      "SPEECH OUTPUT: ':'",
-     "SPEECH OUTPUT: 'List with 5 items'",
+     "SPEECH OUTPUT: 'braille List with 5 items'",
      "SPEECH OUTPUT: ' '",
      "SPEECH OUTPUT: 'GNOME version link'",
      "SPEECH OUTPUT: ':'",
Index: test/keystrokes/firefox/html_struct_nav_large_obj.py
===================================================================
--- test/keystrokes/firefox/html_struct_nav_large_obj.py	(revision 4092)
+++ test/keystrokes/firefox/html_struct_nav_large_obj.py	(working copy)
@@ -34,8 +34,7 @@
     "Top of file", 
     ["BRAILLE LINE:  'Text Attributes h1'",
      "     VISIBLE:  'Text Attributes h1', cursor=1",
-     "SPEECH OUTPUT: 'Text Attributes heading  '",
-     "SPEECH OUTPUT: 'level 1'"]))
+     "SPEECH OUTPUT: 'Text Attributes heading level 1'"]))
 
 ########################################################################
 # Navigate to the first 'large chunk'.  It is the 1st paragraph under 'From 
Index: test/keystrokes/firefox/line_nav_multi_line_text.py
===================================================================
--- test/keystrokes/firefox/line_nav_multi_line_text.py	(revision 4092)
+++ test/keystrokes/firefox/line_nav_multi_line_text.py	(working copy)
@@ -91,8 +91,7 @@
     "Line Down",
     ["BRAILLE LINE:  'Hello h3'",
      "     VISIBLE:  'Hello h3', cursor=1",
-     "SPEECH OUTPUT: 'Hello heading  '",
-     "SPEECH OUTPUT: 'level 3'"]))
+     "SPEECH OUTPUT: 'Hello heading level 3'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
@@ -132,8 +131,7 @@
     "Line Down",
     ["BRAILLE LINE:  'World h3'",
      "     VISIBLE:  'World h3', cursor=1",
-     "SPEECH OUTPUT: 'World heading  '",
-     "SPEECH OUTPUT: 'level 3'"]))
+     "SPEECH OUTPUT: 'World heading level 3'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
@@ -200,8 +198,7 @@
     "Line Up",
     ["BRAILLE LINE:  'World h3'",
      "     VISIBLE:  'World h3', cursor=1",
-     "SPEECH OUTPUT: 'World heading  '",
-     "SPEECH OUTPUT: 'level 3'"]))
+     "SPEECH OUTPUT: 'World heading level 3'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
@@ -241,8 +238,7 @@
     "Line Up",
     ["BRAILLE LINE:  'Hello h3'",
      "     VISIBLE:  'Hello h3', cursor=1",
-     "SPEECH OUTPUT: 'Hello heading  '",
-     "SPEECH OUTPUT: 'level 3'"]))
+     "SPEECH OUTPUT: 'Hello heading level 3'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
Index: test/keystrokes/firefox/sayAll_simple_form.py
===================================================================
--- test/keystrokes/firefox/sayAll_simple_form.py	(revision 4092)
+++ test/keystrokes/firefox/sayAll_simple_form.py	(working copy)
@@ -52,7 +52,7 @@
      "SPEECH OUTPUT: 'Check one or more: Red check box not checked Blue check box not checked Green check box not checked'",
      "SPEECH OUTPUT: 'Make a selection: Water combo box'",
      "SPEECH OUTPUT: 'Which sports do you like?",
-     " multi-select List with 4 items'",
+     " Hockey multi-select List with 4 items'",
      "SPEECH OUTPUT: 'Dashing picture of Willie Walker image'",
      "SPEECH OUTPUT: '",
      "Ain't he handsome (please say yes)? not selected radio button Yes not selected radio button No'"]))
Index: test/keystrokes/firefox/html_struct_nav_lists.py
===================================================================
--- test/keystrokes/firefox/html_struct_nav_lists.py	(revision 4092)
+++ test/keystrokes/firefox/html_struct_nav_lists.py	(working copy)
@@ -37,8 +37,7 @@
     "Top of file", 
     ["BRAILLE LINE:  'Welcome to a List of Lists h1'",
      "     VISIBLE:  'Welcome to a List of Lists h1', cursor=1",
-     "SPEECH OUTPUT: 'Welcome to a List of Lists heading  '",
-     "SPEECH OUTPUT: 'level 1'"]))
+     "SPEECH OUTPUT: 'Welcome to a List of Lists heading level 1'"]))
 
 ########################################################################
 # Press L to move to the first list. 
Index: test/keystrokes/firefox/line_nav_heading_section.py
===================================================================
--- test/keystrokes/firefox/line_nav_heading_section.py	(revision 4092)
+++ test/keystrokes/firefox/line_nav_heading_section.py	(working copy)
@@ -38,8 +38,7 @@
     "Top of file",
     ["BRAILLE LINE:  'Heading 1. h1'",
      "     VISIBLE:  'Heading 1. h1', cursor=1",
-     "SPEECH OUTPUT: 'Heading 1. heading  '",
-     "SPEECH OUTPUT: 'level 1'"]))
+     "SPEECH OUTPUT: 'Heading 1. heading level 1'"]))
 
 ########################################################################
 # Down Arrow.
@@ -50,8 +49,7 @@
     "Line Down",
     ["BRAILLE LINE:  'Heading 2. h1'",
      "     VISIBLE:  'Heading 2. h1', cursor=1",
-     "SPEECH OUTPUT: 'Heading 2. heading  '",
-     "SPEECH OUTPUT: 'level 1'"]))
+     "SPEECH OUTPUT: 'Heading 2. heading level 1'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
@@ -67,8 +65,7 @@
     "Line Down",
     ["BRAILLE LINE:  'Heading 3. h1'",
      "     VISIBLE:  'Heading 3. h1', cursor=1",
-     "SPEECH OUTPUT: 'Heading 3. heading  '",
-     "SPEECH OUTPUT: 'level 1'"]))
+     "SPEECH OUTPUT: 'Heading 3. heading level 1'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
@@ -84,8 +81,7 @@
     "Line Down",
     ["BRAILLE LINE:  'Heading 4. h1'",
      "     VISIBLE:  'Heading 4. h1', cursor=1",
-     "SPEECH OUTPUT: 'Heading 4. heading  '",
-     "SPEECH OUTPUT: 'level 1'"]))
+     "SPEECH OUTPUT: 'Heading 4. heading level 1'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
@@ -101,8 +97,7 @@
     "Line Down",
     ["BRAILLE LINE:  'Heading 5. h1'",
      "     VISIBLE:  'Heading 5. h1', cursor=1",
-     "SPEECH OUTPUT: 'Heading 5. heading  '",
-     "SPEECH OUTPUT: 'level 1'"]))
+     "SPEECH OUTPUT: 'Heading 5. heading level 1'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
@@ -110,8 +105,7 @@
     "Line Down",
     ["BRAILLE LINE:  'Heading 6. h1'",
      "     VISIBLE:  'Heading 6. h1', cursor=1",
-     "SPEECH OUTPUT: 'Heading 6. heading  '",
-     "SPEECH OUTPUT: 'level 1'",]))
+     "SPEECH OUTPUT: 'Heading 6. heading level 1'"]))
 
 ########################################################################
 # Up Arrow.
@@ -122,8 +116,7 @@
     "Line Up",
     ["BRAILLE LINE:  'Heading 5. h1'",
      "     VISIBLE:  'Heading 5. h1', cursor=1",
-     "SPEECH OUTPUT: 'Heading 5. heading  '",
-     "SPEECH OUTPUT: 'level 1'"]))
+     "SPEECH OUTPUT: 'Heading 5. heading level 1'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
@@ -139,8 +132,7 @@
     "Line Up",
     ["BRAILLE LINE:  'Heading 4. h1'",
      "     VISIBLE:  'Heading 4. h1', cursor=1",
-     "SPEECH OUTPUT: 'Heading 4. heading  '",
-     "SPEECH OUTPUT: 'level 1'"]))
+     "SPEECH OUTPUT: 'Heading 4. heading level 1'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
@@ -156,8 +148,7 @@
     "Line Up",
     ["BRAILLE LINE:  'Heading 3. h1'",
      "     VISIBLE:  'Heading 3. h1', cursor=1",
-     "SPEECH OUTPUT: 'Heading 3. heading  '",
-     "SPEECH OUTPUT: 'level 1'"]))
+     "SPEECH OUTPUT: 'Heading 3. heading level 1'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
@@ -173,8 +164,7 @@
     "Line Up",
     ["BRAILLE LINE:  'Heading 2. h1'",
      "     VISIBLE:  'Heading 2. h1', cursor=1",
-     "SPEECH OUTPUT: 'Heading 2. heading  '",
-     "SPEECH OUTPUT: 'level 1'"]))
+     "SPEECH OUTPUT: 'Heading 2. heading level 1'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
@@ -182,8 +172,7 @@
     "Line Up",
     ["BRAILLE LINE:  'Heading 1. h1'",
      "     VISIBLE:  'Heading 1. h1', cursor=1",
-     "SPEECH OUTPUT: 'Heading 1. heading  '",
-     "SPEECH OUTPUT: 'level 1'"]))
+     "SPEECH OUTPUT: 'Heading 1. heading level 1'"]))
 
 ########################################################################
 # Move to the location bar by pressing Control+L.  When it has focus
Index: test/keystrokes/firefox/html_role_lists.py
===================================================================
--- test/keystrokes/firefox/html_role_lists.py	(revision 4092)
+++ test/keystrokes/firefox/html_role_lists.py	(working copy)
@@ -37,8 +37,7 @@
     "Top of file", 
     ["BRAILLE LINE:  'Welcome to a List of Lists h1'",
      "     VISIBLE:  'Welcome to a List of Lists h1', cursor=1",
-     "SPEECH OUTPUT: 'Welcome to a List of Lists heading  '",
-     "SPEECH OUTPUT: 'level 1'"]))
+     "SPEECH OUTPUT: 'Welcome to a List of Lists heading level 1'"]))
 
 ########################################################################
 # Press Down Arrow to move through the lists.
Index: test/keystrokes/firefox/sayAll_multi_line_text.py
===================================================================
--- test/keystrokes/firefox/sayAll_multi_line_text.py	(revision 4092)
+++ test/keystrokes/firefox/sayAll_multi_line_text.py	(working copy)
@@ -49,11 +49,7 @@
     "KP_Add to do a SayAll",
     ["SPEECH OUTPUT: 'Table test foo bar foo",
      "foo bar",
-     "bar Hello heading  '",
-     "SPEECH OUTPUT: 'level 3'",
-     "SPEECH OUTPUT: '• This is a test link  that is not very interesting. • But it looks like link  a real-world example. • And that's link  why this silly test is here. So it's far more interesting link  than it looks. World heading  '",
-     "SPEECH OUTPUT: 'level 3'",
-     "SPEECH OUTPUT: '• The thing is link  we can't copy content. • So we must link  create silly tests. • Oh link  well. At least it's over link .'"]))
+     "bar Hello heading level 3 • This is a test link  that is not very interesting. • But it looks like link  a real-world example. • And that's link  why this silly test is here. So it's far more interesting link  than it looks. World heading level 3 • The thing is link  we can't copy content. • So we must link  create silly tests. • Oh link  well. At least it's over link .'"]))
 
 ########################################################################
 # Move to the location bar by pressing Control+L.  When it has focus
Index: test/keystrokes/firefox/sayAll_entries.py
===================================================================
--- test/keystrokes/firefox/sayAll_entries.py	(revision 4092)
+++ test/keystrokes/firefox/sayAll_entries.py	(working copy)
@@ -37,8 +37,7 @@
     "Top of file",
     ["BRAILLE LINE:  'Here are some entries h2'",
      "     VISIBLE:  'Here are some entries h2', cursor=1",
-     "SPEECH OUTPUT: 'Here are some entries heading  '",
-     "SPEECH OUTPUT: 'level 2'"]))
+     "SPEECH OUTPUT: 'Here are some entries heading level 2'"]))
 
 ########################################################################
 # SayAll to the End.
@@ -47,23 +46,20 @@
 sequence.append(KeyComboAction("KP_Add"))
 sequence.append(utils.AssertPresentationAction(
     "KP_Add to do a SayAll",
-    ["SPEECH OUTPUT: 'Here are some entries heading  '",
-     "SPEECH OUTPUT: 'level 2'",
+    ["SPEECH OUTPUT: 'Here are some entries heading level 2'",
      "SPEECH OUTPUT: 'Type something link  rather amusing link  here: text'",
      "SPEECH OUTPUT: 'Amusing numbers fall between text  and text .'",
      "SPEECH OUTPUT: 'text'",
      "SPEECH OUTPUT: 'I'm a label'",
      "SPEECH OUTPUT: 'text'",
      "SPEECH OUTPUT: 'Am I a label as well?'",
-     "SPEECH OUTPUT: 'What the heck should we do here? heading  '",
-     "SPEECH OUTPUT: 'level 2'",
+     "SPEECH OUTPUT: 'What the heck should we do here? heading level 2'",
      "SPEECH OUTPUT: 'Looking at what follows visually, I'm not sure what I would type/i.e. what the labels are.'",
      "SPEECH OUTPUT: 'text'",
      "SPEECH OUTPUT: 'Too far away to be a label.'",
      "SPEECH OUTPUT: 'Distance doesn't count on the left'",
      "SPEECH OUTPUT: 'text'",
-     "SPEECH OUTPUT: 'Sometimes labels can be below the fields due to <br /> heading  '",
-     "SPEECH OUTPUT: 'level 2'",
+     "SPEECH OUTPUT: 'Sometimes labels can be below the fields due to <br /> heading level 2'",
      "SPEECH OUTPUT: 'text'",
      "SPEECH OUTPUT: '",
      "First Name'",
@@ -73,8 +69,7 @@
      "SPEECH OUTPUT: 'text'",
      "SPEECH OUTPUT: '",
      "Last Name'",
-     "SPEECH OUTPUT: 'Other times it's due to layout tables heading  '",
-     "SPEECH OUTPUT: 'level 2'",
+     "SPEECH OUTPUT: 'Other times it's due to layout tables heading level 2'",
      "SPEECH OUTPUT: 'text'",
      "SPEECH OUTPUT: 'text'",
      "SPEECH OUTPUT: 'text'",
@@ -82,8 +77,7 @@
      "SPEECH OUTPUT: 'Middle",
      "initial'",
      "SPEECH OUTPUT: 'Last name link'",
-     "SPEECH OUTPUT: 'Second verse same as the first (only now the labels are above the fields) heading  '",
-     "SPEECH OUTPUT: 'level 2'",
+     "SPEECH OUTPUT: 'Second verse same as the first (only now the labels are above the fields) heading level 2'",
      "SPEECH OUTPUT: 'First Name'",
      "SPEECH OUTPUT: 'Middle",
      "initial'",
@@ -91,8 +85,7 @@
      "SPEECH OUTPUT: 'text'",
      "SPEECH OUTPUT: 'text'",
      "SPEECH OUTPUT: 'text'",
-     "SPEECH OUTPUT: 'Decisions, decisions.... When in doubt, closest table cell text wins heading  '",
-     "SPEECH OUTPUT: 'level 2'",
+     "SPEECH OUTPUT: 'Decisions, decisions.... When in doubt, closest table cell text wins heading level 2'",
      "SPEECH OUTPUT: 'First name'",
      "SPEECH OUTPUT: 'Middle",
      "initial'",
@@ -113,8 +106,7 @@
      "SPEECH OUTPUT: 'Given name'",
      "SPEECH OUTPUT: 'initial'",
      "SPEECH OUTPUT: 'Surname'",
-     "SPEECH OUTPUT: 'Decisions, decisions.... We should try to figure out if we're in a grid of fields. heading  '",
-     "SPEECH OUTPUT: 'level 2'",
+     "SPEECH OUTPUT: 'Decisions, decisions.... We should try to figure out if we're in a grid of fields. heading level 2'",
      "SPEECH OUTPUT: 'First name'",
      "SPEECH OUTPUT: 'Middle",
      "initial'",
@@ -132,8 +124,7 @@
      "SPEECH OUTPUT: 'text'",
      "SPEECH OUTPUT: 'text'",
      "SPEECH OUTPUT: 'text'",
-     "SPEECH OUTPUT: 'We mustn't forget images as labels -- even if that practice is lame heading  '",
-     "SPEECH OUTPUT: 'level 2'",
+     "SPEECH OUTPUT: 'We mustn't forget images as labels -- even if that practice is lame heading level 2'",
      "SPEECH OUTPUT: 'bandaid graphic image'",
      "SPEECH OUTPUT: 'text'",
      "SPEECH OUTPUT: 'text'",
Index: test/keystrokes/firefox/label_guess_entries.py
===================================================================
--- test/keystrokes/firefox/label_guess_entries.py	(revision 4092)
+++ test/keystrokes/firefox/label_guess_entries.py	(working copy)
@@ -40,8 +40,7 @@
     "Top of file",
     ["BRAILLE LINE:  'Here are some entries h2'",
      "     VISIBLE:  'Here are some entries h2', cursor=1",
-     "SPEECH OUTPUT: 'Here are some entries heading  '",
-     "SPEECH OUTPUT: 'level 2'"]))
+     "SPEECH OUTPUT: 'Here are some entries heading level 2'"]))
 
 ########################################################################
 # Press Insert+Tab to move from form field to form field.
Index: test/keystrokes/firefox/sayAll_heading_section.py
===================================================================
--- test/keystrokes/firefox/sayAll_heading_section.py	(revision 4092)
+++ test/keystrokes/firefox/sayAll_heading_section.py	(working copy)
@@ -36,8 +36,7 @@
     "Top of file",
     ["BRAILLE LINE:  'Heading 1. h1'",
      "     VISIBLE:  'Heading 1. h1', cursor=1",
-     "SPEECH OUTPUT: 'Heading 1. heading  '",
-     "SPEECH OUTPUT: 'level 1'"]))
+     "SPEECH OUTPUT: 'Heading 1. heading level 1'"]))
 
 ########################################################################
 # SayAll to the End.
@@ -46,18 +45,11 @@
 sequence.append(KeyComboAction("KP_Add"))
 sequence.append(utils.AssertPresentationAction(
     "KP_Add to do a SayAll",
-    ["SPEECH OUTPUT: 'Heading 1. heading  '",
-     "SPEECH OUTPUT: 'level 1'",
-     "SPEECH OUTPUT: 'Heading 2. heading  '",
-     "SPEECH OUTPUT: 'level 1'",
-     "SPEECH OUTPUT: 'sect 1 Heading 3. heading  '",
-     "SPEECH OUTPUT: 'level 1'",
-     "SPEECH OUTPUT: 'sect 2 Heading 4. heading  '",
-     "SPEECH OUTPUT: 'level 1'",
-     "SPEECH OUTPUT: 'sect 3 Heading 5. heading  '",
-     "SPEECH OUTPUT: 'level 1'",
-     "SPEECH OUTPUT: 'Heading 6. heading  '",
-     "SPEECH OUTPUT: 'level 1'"]))
+    ["SPEECH OUTPUT: 'Heading 1. heading level 1'",
+     "SPEECH OUTPUT: 'Heading 2. heading level 1'",
+     "SPEECH OUTPUT: 'sect 1 Heading 3. heading level 1'",
+     "SPEECH OUTPUT: 'sect 2 Heading 4. heading level 1 sect 3 Heading 5. heading level 1",
+     "SPEECH OUTPUT: 'Heading 6. heading level 1'"]))
 
 ########################################################################
 # Move to the location bar by pressing Control+L.  When it has focus
Index: test/keystrokes/firefox/sayAll_empty_anchor.py
===================================================================
--- test/keystrokes/firefox/sayAll_empty_anchor.py	(revision 4092)
+++ test/keystrokes/firefox/sayAll_empty_anchor.py	(working copy)
@@ -37,8 +37,7 @@
     ["BRAILLE LINE:  'FAQ h1'",
      "     VISIBLE:  'FAQ h1', cursor=1",
      "SPEECH OUTPUT: 'FAQ '",
-     "SPEECH OUTPUT: 'heading  '",
-     "SPEECH OUTPUT: 'level 1'"]))
+     "SPEECH OUTPUT: 'heading level 1'"]))
 
 ########################################################################
 # SayAll to the End.
@@ -48,10 +47,8 @@
 sequence.append(utils.AssertPresentationAction(
     "KP_Add to do a SayAll",
     ["SPEECH OUTPUT: 'FAQ '",
-     "SPEECH OUTPUT: 'heading  '",
-     "SPEECH OUTPUT: 'level 1'",
-     "SPEECH OUTPUT: 'Battery heading  '",
-     "SPEECH OUTPUT: 'level 2'",
+     "SPEECH OUTPUT: 'heading level 1'",
+     "SPEECH OUTPUT: 'Battery heading level 2'",
      "SPEECH OUTPUT: 'Q. What's a battery? link'",
      "SPEECH OUTPUT: 'Q. Which way is up? link'",
      "SPEECH OUTPUT: 'blank'",
@@ -59,15 +56,13 @@
      "SPEECH OUTPUT: 'blank'",
      "SPEECH OUTPUT: '",
      "FOO'",
-     "SPEECH OUTPUT: 'heading  '",
-     "SPEECH OUTPUT: 'level 2'",
+     "SPEECH OUTPUT: 'heading level 2'",
      "SPEECH OUTPUT: 'Q. Why would someone put a line break in a heading? link'",
      "SPEECH OUTPUT: 'blank'",
      "SPEECH OUTPUT: 'Q. What is the airspeed velocity of an unladen swallow? link'",
      "SPEECH OUTPUT: 'blank'",
      "SPEECH OUTPUT: '",
-     "Battery heading  '",
-     "SPEECH OUTPUT: 'level 2'",
+     "Battery heading level 2'",
      "SPEECH OUTPUT: 'Q. What is a battery?",
      "A. Look it up.'",
      "SPEECH OUTPUT: 'Q. Which way is up?",
Index: test/keystrokes/firefox/html_struct_nav_list_item.py
===================================================================
--- test/keystrokes/firefox/html_struct_nav_list_item.py	(revision 4092)
+++ test/keystrokes/firefox/html_struct_nav_list_item.py	(working copy)
@@ -37,8 +37,7 @@
     "Top of file", 
     ["BRAILLE LINE:  'Welcome to a List of Lists h1'",
      "     VISIBLE:  'Welcome to a List of Lists h1', cursor=1",
-     "SPEECH OUTPUT: 'Welcome to a List of Lists heading  '",
-     "SPEECH OUTPUT: 'level 1'"]))
+     "SPEECH OUTPUT: 'Welcome to a List of Lists heading level 1'"]))
 
 ########################################################################
 # Press L to move to the first list. 
Index: test/keystrokes/firefox/page_summary.py
===================================================================
--- test/keystrokes/firefox/page_summary.py	(revision 4092)
+++ test/keystrokes/firefox/page_summary.py	(working copy)
@@ -35,8 +35,7 @@
     "Navigate to 'This is a Heading 6.'",
     ["BRAILLE LINE:  'This is a Heading 6. h6'",
      "     VISIBLE:  'This is a Heading 6. h6', cursor=1",
-     "SPEECH OUTPUT: 'This is a Heading 6. heading  '",
-     "SPEECH OUTPUT: 'level 6'"]))
+     "SPEECH OUTPUT: 'This is a Heading 6. heading level 6'"]))
 
 ########################################################################
 # Do double-click "Where Am I" via KP_Enter. 
Index: test/keystrokes/firefox/line_nav_empty_anchor.py
===================================================================
--- test/keystrokes/firefox/line_nav_empty_anchor.py	(revision 4092)
+++ test/keystrokes/firefox/line_nav_empty_anchor.py	(working copy)
@@ -39,8 +39,7 @@
     ["BRAILLE LINE:  'FAQ h1'",
      "     VISIBLE:  'FAQ h1', cursor=1",
      "SPEECH OUTPUT: 'FAQ '",
-     "SPEECH OUTPUT: 'heading  '",
-     "SPEECH OUTPUT: 'level 1'"]))
+     "SPEECH OUTPUT: 'heading level 1'"]))
 
 ########################################################################
 # Down Arrow.
@@ -51,8 +50,7 @@
     "Line Down",
     ["BRAILLE LINE:  'Battery h2'",
      "     VISIBLE:  'Battery h2', cursor=1",
-     "SPEECH OUTPUT: 'Battery heading  '",
-     "SPEECH OUTPUT: 'level 2'"]))
+     "SPEECH OUTPUT: 'Battery heading level 2'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
@@ -87,8 +85,7 @@
     ["BRAILLE LINE:  ''",
      "     VISIBLE:  '', cursor=0",
      "SPEECH OUTPUT: '",
-     " heading  '",
-     "SPEECH OUTPUT: 'level 2'"]))
+     " heading level 2'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
@@ -97,8 +94,7 @@
     ["BRAILLE LINE:  'FOO h2'",
      "     VISIBLE:  'FOO h2', cursor=1",
      "SPEECH OUTPUT: 'FOO'",
-     "SPEECH OUTPUT: 'heading  '",
-     "SPEECH OUTPUT: 'level 2'"]))
+     "SPEECH OUTPUT: 'heading level 2'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
@@ -125,8 +121,7 @@
     ["BRAILLE LINE:  ''",
      "     VISIBLE:  '', cursor=0",
      "SPEECH OUTPUT: '",
-     " heading  '",
-     "SPEECH OUTPUT: 'level 2'"]))
+     " heading level 2'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
@@ -134,8 +129,7 @@
     "Line Down",
     ["BRAILLE LINE:  'Battery h2'",
      "     VISIBLE:  'Battery h2', cursor=1",
-     "SPEECH OUTPUT: 'Battery heading  '",
-     "SPEECH OUTPUT: 'level 2'"]))
+     "SPEECH OUTPUT: 'Battery heading level 2'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
@@ -240,8 +234,7 @@
     "Line Up",
     ["BRAILLE LINE:  'Battery h2'",
      "     VISIBLE:  'Battery h2', cursor=1",
-     "SPEECH OUTPUT: 'Battery heading  '",
-     "SPEECH OUTPUT: 'level 2'"]))
+     "SPEECH OUTPUT: 'Battery heading level 2'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
@@ -250,8 +243,7 @@
     ["BRAILLE LINE:  ''",
      "     VISIBLE:  '', cursor=0",
      "SPEECH OUTPUT: '",
-     " heading  '",
-     "SPEECH OUTPUT: 'level 2'"]))
+     " heading level 2'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
@@ -278,8 +270,7 @@
     ["BRAILLE LINE:  'FOO h2'",
      "     VISIBLE:  'FOO h2', cursor=1",
      "SPEECH OUTPUT: 'FOO'",
-     "SPEECH OUTPUT: 'heading  '",
-     "SPEECH OUTPUT: 'level 2'"]))
+     "SPEECH OUTPUT: 'heading level 2'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
@@ -288,8 +279,7 @@
     ["BRAILLE LINE:  ''",
      "     VISIBLE:  '', cursor=0",
      "SPEECH OUTPUT: '",
-     " heading  '",
-     "SPEECH OUTPUT: 'level 2'"]))
+     " heading level 2'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
@@ -323,8 +313,7 @@
     "Line Up",
     ["BRAILLE LINE:  'Battery h2'",
      "     VISIBLE:  'Battery h2', cursor=1",
-     "SPEECH OUTPUT: 'Battery heading  '",
-     "SPEECH OUTPUT: 'level 2'"]))
+     "SPEECH OUTPUT: 'Battery heading level 2'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
@@ -333,8 +322,7 @@
     ["BRAILLE LINE:  'FAQ h1'",
      "     VISIBLE:  'FAQ h1', cursor=1",
      "SPEECH OUTPUT: 'FAQ '",
-     "SPEECH OUTPUT: 'heading  '",
-     "SPEECH OUTPUT: 'level 1'"]))
+     "SPEECH OUTPUT: 'heading level 1'"]))
 
 ########################################################################
 # Move to the location bar by pressing Control+L.  When it has focus
Index: test/keystrokes/firefox/sayAll_wiki.py
===================================================================
--- test/keystrokes/firefox/sayAll_wiki.py	(revision 4092)
+++ test/keystrokes/firefox/sayAll_wiki.py	(working copy)
@@ -53,8 +53,7 @@
      "SPEECH OUTPUT: 'Support link'",
      "SPEECH OUTPUT: 'Development link'",
      "SPEECH OUTPUT: 'Community link'",
-     "SPEECH OUTPUT: 'live.gnome.org heading  '",
-     "SPEECH OUTPUT: 'level 1'",
+     "SPEECH OUTPUT: 'live.gnome.org heading level 1'",
      "SPEECH OUTPUT: 'text Search'",
      "SPEECH OUTPUT: 'Titles button grayed Text button grayed'",
      "SPEECH OUTPUT: 'Home link'",
@@ -65,8 +64,7 @@
      "SPEECH OUTPUT: 'en Español link'",
      "SPEECH OUTPUT: 'Home link'",
      "SPEECH OUTPUT: ' | Download/Installation link  | Configuration/Use link  | Accessible Applications link  | Mailing List link  ( Archives link ) | FAQ link  | DocIndex link'",
-     "SPEECH OUTPUT: 'Welcome to Orca! heading  '",
-     "SPEECH OUTPUT: 'level 1'",
+     "SPEECH OUTPUT: 'Welcome to Orca! heading level 1'",
      "SPEECH OUTPUT: 'Orca Logo link image'",
      "SPEECH OUTPUT: 'HOT HOT HOT: Notes on access to Firefox 3.0 link'",
      "SPEECH OUTPUT: 'Contents'",
@@ -78,38 +76,31 @@
      "SPEECH OUTPUT: '6. Accessible Applications link'",
      "SPEECH OUTPUT: '7. How Can I Help? link'",
      "SPEECH OUTPUT: '8. More Information link'",
-     "SPEECH OUTPUT: 'About heading  '",
-     "SPEECH OUTPUT: 'level 1'",
+     "SPEECH OUTPUT: 'About heading level 1'",
      "SPEECH OUTPUT: 'Orca is a free, open source, flexible, extensible, and powerful assistive technology for people with visual impairments. Using various combinations of speech synthesis, braille, and magnification, Orca helps provide access to applications and toolkits that support the AT-SPI (e.g., the GNOME desktop). The development of Orca has been led by the Accessibility Program Office of Sun Microsystems, Inc. link  with contributions from many community members link .'",
      "SPEECH OUTPUT: 'The complete list of work to do, including bugs and feature requests, along with known problems in other components, is maintained in Bugzilla link  (please see our notes on how we use Bugzilla link ).'",
      "SPEECH OUTPUT: 'Please join and participate on the Orca mailing list link  ( archives link ): it's a helpful, kind, and productive environment composed of users and developers.'",
-     "SPEECH OUTPUT: 'Audio Guides heading  '",
-     "SPEECH OUTPUT: 'level 1'",
+     "SPEECH OUTPUT: 'Audio Guides heading level 1'",
      "SPEECH OUTPUT: 'Darragh Ó Héiligh link'",
      "SPEECH OUTPUT: ' has created several audio guides for Orca. This is a fantastic contribution (THANKS!)!!! The audio guides can be found at http://www.digitaldarragh.com/linuxat.asp link  and include the following:'",
      "SPEECH OUTPUT: '• Walk through of the installation of Ubuntu 7.4. Very helpful tutorial link'",
      "SPEECH OUTPUT: '• Review of Fedora 7 and the Orca screen reader for the Gnome graphical desktop link'",
      "SPEECH OUTPUT: '• Guide to installing the latest versions of Firefox and Orca link'",
-     "SPEECH OUTPUT: 'Download/Installation heading  '",
-     "SPEECH OUTPUT: 'level 1'",
+     "SPEECH OUTPUT: 'Download/Installation heading level 1'",
      "SPEECH OUTPUT: 'As of GNOME 2.16, Orca is a part of the GNOME platform. As a result, Orca is already provided by default on a number of operating system distributions, including Open Solaris link  and Ubuntu link .'",
      "SPEECH OUTPUT: 'Please also refer to the Download/Installation page link  for detailed information on various distributions as well as installing Orca directly from source.'",
-     "SPEECH OUTPUT: 'Configuration/Use heading  '",
-     "SPEECH OUTPUT: 'level 1'",
+     "SPEECH OUTPUT: 'Configuration/Use heading level 1'",
      "SPEECH OUTPUT: 'The command to run orca is orca. You can enter this command by pressing Alt+F2 when logged in, waiting for a second or so, then typing orca and pressing return. Orca is designed to present information as you navigate the desktop using the built-in navigation mechanisms of GNOME link . These navigation mechanisms are consistent across most desktop applications.'",
      "SPEECH OUTPUT: 'You may sometimes wish to control Orca itself, such as bringing up the Orca Configuration GUI link  (accessed by pressing Insert+Space when Orca is running) and for using flat review mode to examine a window. Refer to Orca Keyboard Commands link (Laptop Layout) link  for more information on Orca-specific keyboard commands. The Orca Configuration GUI link  also includes a \"Key Bindings\" tab that allows you to get a complete list of Orca key bindings.'",
      "SPEECH OUTPUT: 'Please also refer to the Configuration/Use page link  for detailed information.'",
-     "SPEECH OUTPUT: 'Accessible Applications heading  '",
-     "SPEECH OUTPUT: 'level 1'",
+     "SPEECH OUTPUT: 'Accessible Applications heading level 1'",
      "SPEECH OUTPUT: 'Orca is designed to work with applications and toolkits that support the assistive technology service provider interface (AT-SPI). This includes the GNOME desktop and its applications, OpenOffice link , Firefox, and the Java platform. Some applications work better than others, however, and the Orca community continually works to provide compelling access to more and more applications.'",
      "SPEECH OUTPUT: 'On the Accessible Applications page link , you will find a growing list of information regarding various applications that can be accessed with Orca as well as tips and tricks for using them. The list is not to be a conclusive list of all applications. Rather, the goal is to provide a repository within which users can share experiences regarding applications they have tested.'",
      "SPEECH OUTPUT: 'See also the Application Specific Settings link  page for how to configure settings specific to an application.'",
      "SPEECH OUTPUT: 'Please also refer to the Accessible Applications page link  for detailed information.'",
-     "SPEECH OUTPUT: 'How Can I Help? heading  '",
-     "SPEECH OUTPUT: 'level 1'",
+     "SPEECH OUTPUT: 'How Can I Help? heading level 1'",
      "SPEECH OUTPUT: 'There's a bunch you can do! Please refer to the How Can I Help page link  for detailed information.'",
-     "SPEECH OUTPUT: 'More Information heading  '",
-     "SPEECH OUTPUT: 'level 1'",
+     "SPEECH OUTPUT: 'More Information heading level 1'",
      "SPEECH OUTPUT: '• Frequently Asked Questions: FAQ link'",
      "SPEECH OUTPUT: '• Mailing list: orca-list@gnome.org link  ( Archives link )'",
      "SPEECH OUTPUT: '• Bug database: GNOME Bug Tracking System (Bugzilla) link  ( current bug list link )'",
@@ -122,17 +113,14 @@
      "SPEECH OUTPUT: 'separator'",
      "SPEECH OUTPUT: 'CategoryAccessibility link'",
      "SPEECH OUTPUT: 'Orca (last edited 2007-12-07 22:09:22 by WillieWalker link )'",
-     "SPEECH OUTPUT: 'User heading  '",
-     "SPEECH OUTPUT: 'level 3'",
+     "SPEECH OUTPUT: 'User heading level 3'",
      "SPEECH OUTPUT: 'Login link'",
-     "SPEECH OUTPUT: 'Page heading  '",
-     "SPEECH OUTPUT: 'level 3'",
+     "SPEECH OUTPUT: 'Page heading level 3'",
      "SPEECH OUTPUT: 'Immutable Page'",
      "SPEECH OUTPUT: 'Info link'",
      "SPEECH OUTPUT: 'Attachments link'",
      "SPEECH OUTPUT: '.*combo box'",
-     "SPEECH OUTPUT: 'GNOME World Wide heading  '",
-     "SPEECH OUTPUT: 'level 3'",
+     "SPEECH OUTPUT: 'GNOME World Wide heading level 3'",
      "SPEECH OUTPUT: 'GnomeWorldWide link image'",
      "SPEECH OUTPUT: 'Copyright © 2005, 2006, 2007 The GNOME Project link .",
      "Hosted by Red Hat link .'"]))
Index: test/keystrokes/firefox/line_nav_bugzilla_search.py
===================================================================
--- test/keystrokes/firefox/line_nav_bugzilla_search.py	(revision 4092)
+++ test/keystrokes/firefox/line_nav_bugzilla_search.py	(working copy)
@@ -99,7 +99,7 @@
     "Line Down",
     ["BRAILLE LINE:  'List'",
      "     VISIBLE:  'List', cursor=0",
-     "SPEECH OUTPUT: 'multi-select List with 8 items'"]))
+     "SPEECH OUTPUT: 'Admin multi-select List with 8 items'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
@@ -115,7 +115,7 @@
     "Line Down",
     ["BRAILLE LINE:  'List'",
      "     VISIBLE:  'List', cursor=0",
-     "SPEECH OUTPUT: 'multi-select List with 379 items'"]))
+     "SPEECH OUTPUT: 'accerciser multi-select List with 379 items'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
@@ -131,7 +131,7 @@
     "Line Down",
     ["BRAILLE LINE:  'List'",
      "     VISIBLE:  'List', cursor=0",
-     "SPEECH OUTPUT: 'multi-select List with 1248 items'"]))
+     "SPEECH OUTPUT: 'abiscan multi-select List with 1248 items'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
@@ -147,7 +147,7 @@
     "Line Down",
     ["BRAILLE LINE:  'List'",
      "     VISIBLE:  'List', cursor=0",
-     "SPEECH OUTPUT: 'multi-select List with 857 items'"]))
+     "SPEECH OUTPUT: '0.0.1 multi-select List with 857 items'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
@@ -163,7 +163,7 @@
     "Line Down",
     ["BRAILLE LINE:  'List'",
      "     VISIBLE:  'List', cursor=0",
-     "SPEECH OUTPUT: 'multi-select List with 555 items'"]))
+     "SPEECH OUTPUT: '--- multi-select List with 555 items'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
@@ -211,7 +211,7 @@
     "Line Down",
     ["BRAILLE LINE:  'List'",
      "     VISIBLE:  'List', cursor=0",
-     "SPEECH OUTPUT: 'multi-select List with 8 items'"]))
+     "SPEECH OUTPUT: 'UNCONFIRMED multi-select List with 8 items'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
@@ -227,7 +227,7 @@
     "Line Down",
     ["BRAILLE LINE:  'List'",
      "     VISIBLE:  'List', cursor=0",
-     "SPEECH OUTPUT: 'multi-select List with 12 items'"]))
+     "SPEECH OUTPUT: 'FIXED multi-select List with 12 items'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
@@ -243,7 +243,7 @@
     "Line Down",
     ["BRAILLE LINE:  'List'",
      "     VISIBLE:  'List', cursor=0",
-     "SPEECH OUTPUT: 'multi-select List with 7 items'"]))
+     "SPEECH OUTPUT: 'blocker multi-select List with 7 items'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
@@ -259,7 +259,7 @@
     "Line Down",
     ["BRAILLE LINE:  'List'",
      "     VISIBLE:  'List', cursor=0",
-     "SPEECH OUTPUT: 'multi-select List with 5 items'"]))
+     "SPEECH OUTPUT: 'Immediate multi-select List with 5 items'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
@@ -275,7 +275,7 @@
     "Line Down",
     ["BRAILLE LINE:  'List'",
      "     VISIBLE:  'List', cursor=0",
-     "SPEECH OUTPUT: 'multi-select List with 21 items'"]))
+     "SPEECH OUTPUT: 'All multi-select List with 21 items'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
@@ -459,7 +459,7 @@
     "Line Down",
     ["BRAILLE LINE:  ' $l and Now $l'",
      "     VISIBLE:  ' $l and Now $l', cursor=1",
-     "SPEECH OUTPUT: 'Only bugs changed between: text and text Now  ",
+     "SPEECH OUTPUT: 'Only bugs changed between: text and text Now",
      "'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -484,7 +484,7 @@
     "Line Down",
     ["BRAILLE LINE:  'List'",
      "     VISIBLE:  'List', cursor=0",
-     "SPEECH OUTPUT: 'multi-select List with 26 items'"]))
+     "SPEECH OUTPUT: '[Bug creation] multi-select List with 26 items'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
@@ -516,7 +516,7 @@
     "Line Down",
     ["BRAILLE LINE:  'List'",
      "     VISIBLE:  'List', cursor=0",
-     "SPEECH OUTPUT: 'multi-select List with 14 items'"]))
+     "SPEECH OUTPUT: 'Unspecified multi-select List with 14 items'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
@@ -532,7 +532,7 @@
     "Line Down",
     ["BRAILLE LINE:  'List'",
      "     VISIBLE:  'List', cursor=0",
-     "SPEECH OUTPUT: 'multi-select List with 12 items'"]))
+     "SPEECH OUTPUT: 'Unspecified multi-select List with 12 items'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
@@ -695,7 +695,7 @@
     "Line Up",
     ["BRAILLE LINE:  'List'",
      "     VISIBLE:  'List', cursor=0",
-     "SPEECH OUTPUT: 'multi-select List with 12 items'"]))
+     "SPEECH OUTPUT: 'Unspecified multi-select List with 12 items'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
@@ -711,7 +711,7 @@
     "Line Up",
     ["BRAILLE LINE:  'List'",
      "     VISIBLE:  'List', cursor=0",
-     "SPEECH OUTPUT: 'multi-select List with 14 items'"]))
+     "SPEECH OUTPUT: 'Unspecified multi-select List with 14 items'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
@@ -743,7 +743,7 @@
     "Line Up",
     ["BRAILLE LINE:  'List'",
      "     VISIBLE:  'List', cursor=0",
-     "SPEECH OUTPUT: 'multi-select List with 26 items'"]))
+     "SPEECH OUTPUT: '[Bug creation] multi-select List with 26 items'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
@@ -767,7 +767,7 @@
     "Line Up",
     ["BRAILLE LINE:  ' $l and Now $l'",
      "     VISIBLE:  ' $l and Now $l', cursor=1",
-     "SPEECH OUTPUT: 'Only bugs changed between: text and text Now  ",
+     "SPEECH OUTPUT: 'Only bugs changed between: text and text Now",
      "'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -952,7 +952,7 @@
     "Line Up",
     ["BRAILLE LINE:  'List'",
      "     VISIBLE:  'List', cursor=0",
-     "SPEECH OUTPUT: 'multi-select List with 21 items'"]))
+     "SPEECH OUTPUT: 'All multi-select List with 21 items'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
@@ -968,7 +968,7 @@
     "Line Up",
     ["BRAILLE LINE:  'List'",
      "     VISIBLE:  'List', cursor=0",
-     "SPEECH OUTPUT: 'multi-select List with 5 items'"]))
+     "SPEECH OUTPUT: 'Immediate multi-select List with 5 items'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
@@ -984,7 +984,7 @@
     "Line Up",
     ["BRAILLE LINE:  'List'",
      "     VISIBLE:  'List', cursor=0",
-     "SPEECH OUTPUT: 'multi-select List with 7 items'"]))
+     "SPEECH OUTPUT: 'blocker multi-select List with 7 items'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
@@ -1000,7 +1000,7 @@
     "Line Up",
     ["BRAILLE LINE:  'List'",
      "     VISIBLE:  'List', cursor=0",
-     "SPEECH OUTPUT: 'multi-select List with 12 items'"]))
+     "SPEECH OUTPUT: 'FIXED multi-select List with 12 items'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
@@ -1016,7 +1016,7 @@
     "Line Up",
     ["BRAILLE LINE:  'List'",
      "     VISIBLE:  'List', cursor=0",
-     "SPEECH OUTPUT: 'multi-select List with 8 items'"]))
+     "SPEECH OUTPUT: 'UNCONFIRMED multi-select List with 8 items'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
@@ -1064,7 +1064,7 @@
     "Line Up",
     ["BRAILLE LINE:  'List'",
      "     VISIBLE:  'List', cursor=0",
-     "SPEECH OUTPUT: 'multi-select List with 555 items'"]))
+     "SPEECH OUTPUT: '--- multi-select List with 555 items'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
@@ -1080,7 +1080,7 @@
     "Line Up",
     ["BRAILLE LINE:  'List'",
      "     VISIBLE:  'List', cursor=0",
-     "SPEECH OUTPUT: 'multi-select List with 857 items'"]))
+     "SPEECH OUTPUT: '0.0.1 multi-select List with 857 items'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
@@ -1096,7 +1096,7 @@
     "Line Up",
     ["BRAILLE LINE:  'List'",
      "     VISIBLE:  'List', cursor=0",
-     "SPEECH OUTPUT: 'multi-select List with 1248 items'"]))
+     "SPEECH OUTPUT: 'abiscan multi-select List with 1248 items'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
@@ -1112,7 +1112,7 @@
     "Line Up",
     ["BRAILLE LINE:  'List'",
      "     VISIBLE:  'List', cursor=0",
-     "SPEECH OUTPUT: 'multi-select List with 379 items'"]))
+     "SPEECH OUTPUT: 'accerciser multi-select List with 379 items'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
@@ -1128,7 +1128,7 @@
     "Line Up",
     ["BRAILLE LINE:  'List'",
      "     VISIBLE:  'List', cursor=0",
-     "SPEECH OUTPUT: 'multi-select List with 8 items'"]))
+     "SPEECH OUTPUT: 'Admin multi-select List with 8 items'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
Index: test/keystrokes/firefox/sayAll_role_lists.py
===================================================================
--- test/keystrokes/firefox/sayAll_role_lists.py	(revision 4092)
+++ test/keystrokes/firefox/sayAll_role_lists.py	(working copy)
@@ -35,8 +35,7 @@
     "Top of file", 
     ["BRAILLE LINE:  'Welcome to a List of Lists h1'",
      "     VISIBLE:  'Welcome to a List of Lists h1', cursor=1",
-     "SPEECH OUTPUT: 'Welcome to a List of Lists heading  '",
-     "SPEECH OUTPUT: 'level 1'"]))
+     "SPEECH OUTPUT: 'Welcome to a List of Lists heading level 1'"]))
 
 ########################################################################
 # SayAll to the End.
@@ -45,8 +44,7 @@
 sequence.append(KeyComboAction("KP_Add"))
 sequence.append(utils.AssertPresentationAction(
     "KP_Add to do a SayAll",
-    ["SPEECH OUTPUT: 'Welcome to a List of Lists heading  '",
-     "SPEECH OUTPUT: 'level 1'",
+    ["SPEECH OUTPUT: 'Welcome to a List of Lists heading level 1'",
      "SPEECH OUTPUT: 'Lists are not only fun to make, they are fun to use. They help us: 1. remember what the heck we are doing each day 2. arrange long and arbitrary lines of text into ordered lists that are pleasing to the eye and suggest some sense of priority, even if it is artificial 3. look really cool when we carry them around on yellow Post-Itstm. 4. and that other thing I keep forgetting. Your ordered lists can start at a strange number, like: VI. And use roman numerals, g. You might try using letters as well, H. Maybe you prefer Big Letters, ix. or small roman numerals • But discs belong to unordered lists 50. Though you can set the value in a list item! Unordered list: • listing item • first sublevel • look for the bullet on • each sublevel • they should all be different, except here. • second sublevel • or you can specify a square • if your TYPE is circle • or even a disc • Franz Liszt • was a composer who was not square • would have liked the Who • feeling listless • blah, blah, blah • whine, whine, whine'"]))
 
 ########################################################################
Index: test/keystrokes/firefox/line_nav_enter_bug.py
===================================================================
--- test/keystrokes/firefox/line_nav_enter_bug.py	(revision 4092)
+++ test/keystrokes/firefox/line_nav_enter_bug.py	(working copy)
@@ -62,11 +62,9 @@
      "     VISIBLE:  'Enter Bug: orca', cursor=0",
      "BRAILLE LINE:  'Enter Bug: orca – This page lets you enter a new bug into Bugzilla. h1'",
      "     VISIBLE:  'Enter Bug: orca – This page le', cursor=1",
-     "SPEECH OUTPUT: 'Enter Bug: orca – This page lets you enter a new bug into Bugzilla. heading  '",
-     "SPEECH OUTPUT: 'level 1'",
+     "SPEECH OUTPUT: 'Enter Bug: orca – This page lets you enter a new bug into Bugzilla. heading level 1'",
      "SPEECH OUTPUT: 'Enter Bug: orca page'",
-     "SPEECH OUTPUT: 'Enter Bug: orca – This page lets you enter a new bug into Bugzilla. heading  '",
-     "SPEECH OUTPUT: 'level 1'"]))
+     "SPEECH OUTPUT: 'Enter Bug: orca – This page lets you enter a new bug into Bugzilla. heading level 1'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
@@ -115,7 +113,7 @@
     "Line Down",
     ["BRAILLE LINE:  'Version: List Component Link : List'",
      "     VISIBLE:  'Version: List Component Link : L', cursor=1",
-     "SPEECH OUTPUT: 'Version: List with 9 items Component link : List with 5 items'"]))
+     "SPEECH OUTPUT: 'Version: 2.21.x List with 9 items Component link : braille List with 5 items'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
@@ -423,7 +421,7 @@
     "Line Up",
     ["BRAILLE LINE:  'Version: List Component Link : List'",
      "     VISIBLE:  'Version: List Component Link : L', cursor=1",
-     "SPEECH OUTPUT: 'Version: List with 9 items Component link : List with 5 items'"]))
+     "SPEECH OUTPUT: 'Version: 2.21.x List with 9 items Component link : braille List with 5 items'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
@@ -472,8 +470,7 @@
     "Line Up",
     ["BRAILLE LINE:  'Enter Bug: orca – This page lets you enter a new bug into Bugzilla. h1'",
      "     VISIBLE:  'Enter Bug: orca – This page le', cursor=1",
-     "SPEECH OUTPUT: 'Enter Bug: orca – This page lets you enter a new bug into Bugzilla. heading  '",
-     "SPEECH OUTPUT: 'level 1'"]))
+     "SPEECH OUTPUT: 'Enter Bug: orca – This page lets you enter a new bug into Bugzilla. heading level 1'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
Index: test/keystrokes/firefox/line_nav_simple_form.py
===================================================================
--- test/keystrokes/firefox/line_nav_simple_form.py	(revision 4092)
+++ test/keystrokes/firefox/line_nav_simple_form.py	(working copy)
@@ -62,7 +62,7 @@
 sequence.append(KeyComboAction("Down"))
 sequence.append(utils.AssertPresentationAction(
     "3. line Down",
-    [     "BRAILLE LINE:  'Tell me a little more about yourself:'",
+    ["BRAILLE LINE:  'Tell me a little more about yourself:'",
      "     VISIBLE:  'Tell me a little more about your', cursor=1",
      "SPEECH OUTPUT: 'Tell me a little more about yourself:",
      "'"]))
@@ -146,7 +146,7 @@
     "13. line Down",
     ["BRAILLE LINE:  'List'",
      "     VISIBLE:  'List', cursor=0",
-     "SPEECH OUTPUT: 'multi-select List with 4 items'"]))
+     "SPEECH OUTPUT: 'Hockey multi-select List with 4 items'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
@@ -199,7 +199,7 @@
     "3. line Up",
     ["BRAILLE LINE:  'List'",
      "     VISIBLE:  'List', cursor=0",
-     "SPEECH OUTPUT: 'multi-select List with 4 items'"]))
+     "SPEECH OUTPUT: 'Hockey multi-select List with 4 items'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
Index: src/orca/scripts/apps/gnome-window-properties/speech_generator.py
===================================================================
--- src/orca/scripts/apps/gnome-window-properties/speech_generator.py	(revision 4092)
+++ src/orca/scripts/apps/gnome-window-properties/speech_generator.py	(working copy)
@@ -49,7 +49,7 @@
         utterances = []
         utterances.extend(self._getSpeechForObjectLabel(obj))
         utterances.extend(self._getSpeechForObjectName(obj))
-        utterances.extend(self._getSpeechForObjectRole(obj))
+        utterances.extend(self.getSpeechForObjectRole(obj))
 
         self._debugGenerator("gnome-window-properties._getSpeechForAlert",
                              obj,
Index: src/orca/scripts/apps/soffice/speech_generator.py
===================================================================
--- src/orca/scripts/apps/soffice/speech_generator.py	(revision 4092)
+++ src/orca/scripts/apps/soffice/speech_generator.py	(working copy)
@@ -80,7 +80,7 @@
             utterances.extend(name)
 
         if not already_focused:
-            utterances.extend(self._getSpeechForObjectRole(obj))
+            utterances.extend(self.getSpeechForObjectRole(obj))
 
         utterances.extend(self._getSpeechForObjectAvailability(obj))
 
Index: src/orca/scripts/toolkits/Gecko/speech_generator.py
===================================================================
--- src/orca/scripts/toolkits/Gecko/speech_generator.py	(revision 4092)
+++ src/orca/scripts/toolkits/Gecko/speech_generator.py	(working copy)
@@ -65,17 +65,32 @@
 
     def getSpeechForObjectRole(self, obj, role=None):
         """Prevents some roles from being spoken."""
-        if obj.getRole() in [pyatspi.ROLE_PARAGRAPH,
-                             pyatspi.ROLE_SECTION,
-                             pyatspi.ROLE_LABEL,
-                             pyatspi.ROLE_FORM,
-                             pyatspi.ROLE_LIST_ITEM,
-                             pyatspi.ROLE_MENU_ITEM,
-                             pyatspi.ROLE_UNKNOWN]:
-            return []
-        else:
-            return [rolenames.getSpeechForRoleName(obj, role)]
+        doNotSpeak = [pyatspi.ROLE_FORM,
+                      pyatspi.ROLE_LABEL,
+                      pyatspi.ROLE_MENU_ITEM,
+                      pyatspi.ROLE_PARAGRAPH,
+                      pyatspi.ROLE_SECTION,
+                      pyatspi.ROLE_UNKNOWN]
 
+        if self._script.inDocumentContent(obj):
+            doNotSpeak.append(pyatspi.ROLE_TABLE_CELL)
+            if not self._script.isAriaWidget(obj):
+                doNotSpeak.append(pyatspi.ROLE_LIST_ITEM)
+                doNotSpeak.append(pyatspi.ROLE_LIST)
+
+        utterances = []
+        if not obj.getRole() in doNotSpeak:
+            utterances.append(rolenames.getSpeechForRoleName(obj, role))
+            if obj.getRole() == pyatspi.ROLE_HEADING:
+                level = self._script.getHeadingLevel(obj)
+                if level:
+                    # Translators: this is in reference to a heading level
+                    # in HTML (e.g., For <h3>, the level is 3).
+                    #
+                    utterances.append(_("level %d") % level)
+
+        return utterances
+
     def _getSpeechForDocumentFrame(self, obj, already_focused):
         """Gets the speech for a document frame.
 
@@ -327,28 +342,27 @@
 
         utterances = []
 
-        if obj.getState().contains(pyatspi.STATE_FOCUSED):
-            label = self._script.getDisplayedLabel(obj)
-            if not label:
-                if not self._script.inDocumentContent():
-                    label = obj.name
-                else:
-                    label = self._script.guessTheLabel(obj)
+        label = self._script.getDisplayedLabel(obj)
+        if not label:
+            if not self._script.inDocumentContent():
+                label = obj.name
+            else:
+                label = self._script.guessTheLabel(obj)
 
-            if not already_focused and label:
-                utterances.append(label)
+        if not already_focused and label:
+            utterances.append(label)
 
-            item = None
-            selection = obj.querySelection()
-            for i in xrange(obj.childCount):
-                if selection.isChildSelected(i):
-                    item = obj[i]
-                    break
-            item = item or obj[0]
-            if item:
-                name = self._getSpeechForObjectName(item)
-                if name != label:
-                    utterances.extend(name)
+        item = None
+        selection = obj.querySelection()
+        for i in xrange(obj.childCount):
+            if selection.isChildSelected(i):
+                item = obj[i]
+                break
+        item = item or obj[0]
+        if item:
+            name = self._getSpeechForObjectName(item)
+            if name != label:
+                utterances.extend(name)
 
         if not already_focused:
             if obj.getState().contains(pyatspi.STATE_MULTISELECTABLE):
Index: src/orca/scripts/toolkits/Gecko/script.py
===================================================================
--- src/orca/scripts/toolkits/Gecko/script.py	(revision 4092)
+++ src/orca/scripts/toolkits/Gecko/script.py	(working copy)
@@ -1017,7 +1017,6 @@
                 [line, startOffset, endOffset] = \
                     text.getTextAtOffset(characterOffset,
                                          pyatspi.TEXT_BOUNDARY_LINE_START)
-
                 beginAt = 0
                 if line.strip():
                     terminators = ['. ', '? ', '! ']
@@ -1044,15 +1043,8 @@
             utterances = self.getUtterancesFromContents(contents)
             clumped = self.clumpUtterances(utterances)
             for i in xrange(len(clumped)):
-                [obj, startOffset, endOffset] = \
+                [obj, startOffset, endOffset, text] = \
                                              contents[min(i, len(contents)-1)]
-                if obj.getRole() == pyatspi.ROLE_LABEL \
-                   and len(obj.getRelationSet()):
-                    # This label is labelling something and will be spoken
-                    # in conjunction with the object with which it is
-                    # associated.
-                    #
-                    continue
                 [string, voice] = clumped[i]
                 string = self.adjustForRepeats(string)
                 yield [speechserver.SayAllContext(obj, string,
@@ -1849,7 +1841,7 @@
         Arguments:
         - obj: the Accessible
         - offset: the character offset within obj
-        - contents: a list of (obj, startOffset, endOffset) tuples
+        - contents: a list of (obj, startOffset, endOffset, string) tuples
 
         Returns the index of the item if found; -1 if not found.
         """
@@ -1859,7 +1851,7 @@
 
         index = -1
         for content in contents:
-            [candidate, start, end] = content
+            [candidate, start, end, string] = content
 
             # When we get the line contents, we include a focusable list
             # as a list and combo box as a combo box because that is what
@@ -1930,7 +1922,7 @@
         index = self.findObjectOnLine(obj, offset, contents)
         if index < 0:
             self.currentLineContents = self.getLineContentsAtOffset(obj,
-                                                                     offset)
+                                                                    offset)
         self.speakContents(self.currentLineContents)
         self.updateBraille(obj)
 
@@ -1990,7 +1982,7 @@
 
         focusedRegion = None
         for content in contents:
-            [obj, startOffset, endOffset] = content
+            [obj, startOffset, endOffset, string] = content
             if not obj:
                 continue
 
@@ -2195,7 +2187,7 @@
         if obj.getRole() != pyatspi.ROLE_ENTRY:
             self.speakContents(wordContents)
         else:
-            [textObj, startOffset, endOffset] = wordContents[0]
+            [textObj, startOffset, endOffset, word] = wordContents[0]
             word = textObj.queryText().getText(startOffset, endOffset)
             speech.speakUtterances([word], self.getACSS(textObj, word))
 
@@ -3311,9 +3303,9 @@
 
         return string
 
-    def getObjectsFromEOCs(self, obj, offset, boundary):
+    def getObjectsFromEOCs(self, obj, offset, boundary=None):
         """Expands the current object replacing EMBEDDED_OBJECT_CHARACTERS
-        with [obj, startOffset, endOffset] tuples.
+        with [obj, startOffset, endOffset, string] tuples.
 
         Arguments
         - obj: the object whose EOCs we need to expand into tuples
@@ -3326,7 +3318,7 @@
         if not obj:
             return []
 
-        elif obj.getRole() == pyatspi.ROLE_TABLE:
+        elif boundary and obj.getRole() == pyatspi.ROLE_TABLE:
             # If this is a table, move to the first cell -- or the caption,
             # if present.
             # [[[TODOS - JD:
@@ -3344,29 +3336,45 @@
         objects = []
         text = self.queryNonEmptyText(obj)
         if text:
-            [string, start, end] = text.getTextAfterOffset(offset, boundary)
+            if boundary:
+                [string, start, end] = \
+                    text.getTextAfterOffset(offset, boundary)
+            else:
+                start = offset
+                end = text.characterCount
+                string = text.getText(start, end)
         else:
             string = ""
             start = 0
             end = 1
-        objects.append([obj, start, end])
 
-        pattern = re.compile(self.EMBEDDED_OBJECT_CHARACTER)
         unicodeText = string.decode("UTF-8")
+        objects.append([obj, start, end, unicodeText])
+
+        pattern = re.compile(self.EMBEDDED_OBJECT_CHARACTER)
         matches = re.finditer(pattern, unicodeText)
+
+        offset = 0
         for m in matches:
             # Adjust the last object's endOffset to the last character
             # before the EOC.
             #
             childOffset = m.start(0) + start
-            objects[-1][2] = childOffset
-            if objects[-1][1] == objects[-1][2]:
+            lastObj = objects[-1]
+            lastObj[2] = childOffset
+            if lastObj[1] == lastObj[2]:
                 # A zero-length object is an indication of something
                 # whose sole contents was an EOC.  Delete it from the
                 # list.
                 #
                 objects.pop()
+            else:
+                # Adjust the string to reflect just this segment.
+                #
+                lastObj[3] = unicodeText[offset:m.start(0)]
 
+            offset = m.start(0) + 1
+ 
             # Recursively tack on the child's objects.
             #
             childIndex = self.getChildIndex(obj, childOffset)
@@ -3376,12 +3384,13 @@
             # Tack on the remainder of the original object, if any.
             #
             if end > childOffset + 1:
-                objects.append([obj, childOffset + 1, end])
-
-        if obj.getRole() == pyatspi.ROLE_IMAGE and obj.childCount:
+                restOfText = unicodeText[offset:len(unicodeText)]
+                objects.append([obj, childOffset + 1, end, restOfText])                
+ 
+        if obj.getRole() in [pyatspi.ROLE_IMAGE, pyatspi.ROLE_TABLE]:
             # Imagemaps that don't have alternative text won't implement
             # the text interface, but they will have children (essentially
-            # EOCs) that we need to get.
+            # EOCs) that we need to get. The same is true for tables.
             #
             toAdd = []
             for child in obj:
@@ -4555,8 +4564,8 @@
             return None
 
     def getWordContentsAtOffset(self, obj, characterOffset, boundary=None):
-        """Returns an ordered list where each element is composed of
-        an [obj, startOffset, endOffset] tuple.  The list is created
+        """Returns an ordered list where each element is composed of an
+        [obj, startOffset, endOffset, string] tuple.  The list is created
         via an in-order traversal of the document contents starting at
         the given object and characterOffset.  The first element in
         the list represents the beginning of the word.  The last
@@ -4587,8 +4596,8 @@
         return contents
 
     def getLineContentsAtOffset(self, obj, offset):
-        """Returns an ordered list where each element is composed of
-        an [obj, startOffset, endOffset] tuple.  The list is created
+        """Returns an ordered list where each element is composed of an
+        [obj, startOffset, endOffset, string] tuple.  The list is created
         via an in-order traversal of the document contents starting at
         the given object and characterOffset.  The first element in
         the list represents the beginning of the line.  The last
@@ -4669,7 +4678,7 @@
         lastExtents = (0, 0, 0, 0)
         done = False
         while not done:
-            [firstObj, start, end] = objects[0]
+            [firstObj, start, end, string] = objects[0]
             isAria = not self.isNavigableAria(firstObj)
 
             text = self.queryNonEmptyText(firstObj)
@@ -4709,7 +4718,7 @@
         lastExtents = (0, 0, 0, 0)
         done = False
         while not done:
-            [lastObj, start, end] = objects[-1]
+            [lastObj, start, end, string] = objects[-1]
             isAria = not self.isNavigableAria(lastObj)
 
             text = self.queryNonEmptyText(lastObj)
@@ -4778,39 +4787,13 @@
 
     def getObjectContentsAtOffset(self, obj, characterOffset):
         """Returns an ordered list where each element is composed of
-        an [obj, startOffset, endOffset] tuple.  The list is created
-        via an in-order traversal of the document contents starting and
-        stopping at the given object.
+        an [obj, startOffset, endOffset, string] tuple.  The list is 
+        created via an in-order traversal of the document contents 
+        starting and stopping at the given object.
         """
 
-        #if not obj.getState().contains(pyatspi.STATE_SHOWING):
-        #    return [[None, -1, -1]]
-        contents = []
-        if obj.getRole() == pyatspi.ROLE_TABLE:
-            for child in obj:
-                contents.extend(self.getObjectContentsAtOffset(child, 0))
-            return contents
+        return self.getObjectsFromEOCs(obj, characterOffset)
 
-        elif not self.queryNonEmptyText(obj):
-            return [[obj, -1, -1]]
-
-        text = self.getUnicodeText(obj)
-        for offset in range(characterOffset, len(text)):
-            if text[offset] == self.EMBEDDED_OBJECT_CHARACTER:
-                child = obj[self.getChildIndex(obj, offset)]
-                if child:
-                    contents.extend(self.getObjectContentsAtOffset(child, 0))
-            elif len(contents):
-                [currentObj, startOffset, endOffset] = contents[-1]
-                if obj == currentObj:
-                    contents[-1] = [obj, startOffset, offset + 1]
-                else:
-                    contents.append([obj, offset, offset + 1])
-            else:
-                contents.append([obj, offset, offset + 1])
-
-        return contents
-
     ####################################################################
     #                                                                  #
     # Methods to speak current objects.                                #
@@ -4829,30 +4812,43 @@
         return acss
 
     def getUtterancesFromContents(self, contents, speakRole=True):
-        """Returns a list of [text, acss] tuples based upon the
-        list of [obj, startOffset, endOffset] tuples passed in.
+        """Returns a list of [text, acss] tuples based upon the list
+        of [obj, startOffset, endOffset, string] tuples passed in.
 
         Arguments:
-        -contents: a list of [obj, startOffset, endOffset] tuples
+        -contents: a list of [obj, startOffset, endOffset, string] tuples
         -speakRole: if True, speak the roles of objects
         """
 
         if not len(contents):
             return []
 
+        # Even if we want to speakRole, we don't want to do that for the
+        # document frame.  And we're going to special-case headings so that
+        # that we don't overspeak heading role info, which we're in danger
+        # of doing if a heading includes links or images.
+        #
+        doNotSpeakRoles = [pyatspi.ROLE_DOCUMENT_FRAME, pyatspi.ROLE_HEADING]
+
         utterances = []
         for content in contents:
-            [obj, startOffset, endOffset] = content
-            if not obj:
+            [obj, startOffset, endOffset, string] = content
+            role = obj.getRole()
+
+            # If we don't have an object, there's nothing to do. If we have
+            # a string, but it consists solely of spaces, we have nothing to
+            # say. If it's a label for an object in our contents, we'll get
+            # that label via the speech generator for the object.
+            #
+            if not obj \
+               or len(string) and not len(string.strip(" ")) \
+               or self.isLabellingContents(obj, contents):
                 continue
 
-            # If this is a label that's labelling something else, we'll
-            # get the label via a speech generator -- unless it's a
-            # focusable list that doesn't have focus.
+            # If it is a "useless" image (i.e. not a link, no associated
+            # text), ignore it.
             #
-            labelledContent = self.isLabellingContents(obj, contents)
-            if labelledContent \
-               and labelledContent.getRole() != pyatspi.ROLE_LIST:
+            elif role == pyatspi.ROLE_IMAGE and self.isUselessObject(obj):
                 continue
 
             # The radio button's label gets added to the context in
@@ -4867,83 +4863,39 @@
                 if label:
                     utterances.append([label, self.getACSS(obj, label)])
 
-            # We only want to announce the heading role and level if we
-            # have found the final item in that heading, or if that
-            # heading contains no children.
+            # If we don't have a string, then use the speech generator.
+            # Otherwise, we'll want to speak the string and possibly the
+            # role.
             #
-            containingHeading = \
-                self.getAncestor(obj,
-                                 [pyatspi.ROLE_HEADING],
-                                 [pyatspi.ROLE_DOCUMENT_FRAME])
-            isLastObject = contents.index(content) == (len(contents) - 1)
-            if obj.getRole() == pyatspi.ROLE_HEADING:
-                speakThisRole = isLastObject or not obj.childCount
+            if not len(string) \
+               or role in [pyatspi.ROLE_ENTRY, pyatspi.ROLE_PASSWORD_TEXT]:
+                utterance = self.speechGenerator.getSpeech(obj, False)
             else:
-                # We also don't want to speak the role if it's a documement
-                # frame or a table cell.  In addition, if the object is an
-                # entry or password_text, _getSpeechForText() will add the
-                # role after the label and before any text that is present
-                # in that field.  We don't want to repeat the role.
-                #
-                speakThisRole = \
-                    not obj.getRole() in [pyatspi.ROLE_DOCUMENT_FRAME,
-                                          pyatspi.ROLE_TABLE_CELL,
-                                          pyatspi.ROLE_ENTRY,
-                                          pyatspi.ROLE_PASSWORD_TEXT]
-            text = self.queryNonEmptyText(obj)
-            if self.isAriaWidget(obj):
-                # Treat ARIA widgets like normal default.py widgets
-                #
-                speakThisRole = False
-                strings = self.speechGenerator.getSpeech(obj, False)
-            elif text \
-               and not obj.getRole() in [pyatspi.ROLE_ENTRY,
-                                         pyatspi.ROLE_PASSWORD_TEXT,
-                                         pyatspi.ROLE_RADIO_BUTTON,
-                                         pyatspi.ROLE_MENU_ITEM]:
-                strings = [text.getText(startOffset, endOffset)]
-                if strings == [' '] and len(contents) > 1:
-                    strings = []
-            elif self.isLayoutOnly(obj):
-                continue
-            else:
-                strings = self.speechGenerator.getSpeech(obj, False)
-
-        # Pylint is confused and flags these errors:
-        #
-        # E1101:6957:Script.getUtterancesFromContents: Instance of
-        # 'SpeechGenerator' has no 'getSpeechForObjectRole' member
-        # E1101:6962:Script.getUtterancesFromContents: Instance of
-        # 'SpeechGenerator' has no 'getSpeechForObjectRole' member
-        #
-        # So for now, we just disable these errors in this method.
-        #
-        # pylint: disable-msg=E1101
-
-            if speakRole and speakThisRole:
-                if text:
-                    strings.extend(\
-                       self.speechGenerator.getSpeechForObjectRole(obj))
-
-                if containingHeading and isLastObject:
-                    obj = containingHeading
-                    strings.extend(\
+                utterance = [string]
+                if speakRole and not role in doNotSpeakRoles:
+                    utterance.extend(\
                         self.speechGenerator.getSpeechForObjectRole(obj))
+  
+            # If the object is a heading, or is contained within a heading,
+            # speak that role information at the end of the object.
+            #
+            isLastObject = (contents.index(content) == (len(contents) - 1))
+            isHeading = (role == pyatspi.ROLE_HEADING)
+            if speakRole and (isLastObject or isHeading):
+                if isHeading:
+                    heading = obj
+                else:
+                    heading = self.getAncestor(obj,
+                                               [pyatspi.ROLE_HEADING],
+                                               [pyatspi.ROLE_DOCUMENT_FRAME])
 
-            for string in strings:
-                utterances.append([string, self.getACSS(obj, string)])
+                if heading:
+                    utterance.extend(\
+                        self.speechGenerator.getSpeechForObjectRole(heading))
 
-            if speakRole and \
-               speakThisRole and \
-               obj.getRole() == pyatspi.ROLE_HEADING:
-                level = self.getHeadingLevel(obj)
-                if level:
-                    utterances.append([" ", self.getACSS(obj, " ")])
-                    # Translators: this is in reference to a heading level
-                    # in HTML (e.g., For <h3>, the level is 3).
-                    #
-                    utterances.append([_("level %d") % level, None])
-
+            for item in utterance:
+                utterances.append([item, self.getACSS(obj, item)])
+  
         return utterances
 
     def clumpUtterances(self, utterances):
@@ -5155,7 +5107,7 @@
         if not len(contents):
             return
 
-        [obj, startOffset, endOffset] = contents[0]
+        [obj, startOffset, endOffset, string] = contents[0]
         if len(contents) == 1 \
            and endOffset - startOffset == 1 \
            and self.getCharacterAtOffset(obj, startOffset) == " ":
@@ -5168,7 +5120,7 @@
             contents = \
                 self.getWordContentsAtOffset(obj, characterOffset, boundary)
             if len(contents):
-                [obj, startOffset, endOffset] = contents[0]
+                [obj, startOffset, endOffset, string] = contents[0]
 
         self.setCaretPosition(obj, startOffset)
         self.updateBraille(obj)
@@ -5195,7 +5147,7 @@
         if not (len(contents) and contents[-1][2]):
             return
 
-        [obj, startOffset, endOffset] = contents[-1]
+        [obj, startOffset, endOffset, string] = contents[-1]
         self.setCaretPosition(obj, endOffset)
         self.updateBraille(obj)
         self.speakContents(contents)
Index: src/orca/speechgenerator.py
===================================================================
--- src/orca/speechgenerator.py	(revision 4092)
+++ src/orca/speechgenerator.py	(working copy)
@@ -209,7 +209,7 @@
         else:
             return []
 
-    def _getSpeechForObjectRole(self, obj, role=None):
+    def getSpeechForObjectRole(self, obj, role=None):
         if (obj.getRole() != pyatspi.ROLE_UNKNOWN):
             return [rolenames.getSpeechForRoleName(obj, role)]
         else:
@@ -314,7 +314,7 @@
             if name != label:
                 utterances.extend(name)
             utterances.extend(self._getSpeechForAllTextSelection(obj))
-            utterances.extend(self._getSpeechForObjectRole(obj, role))
+            utterances.extend(self.getSpeechForObjectRole(obj, role))
 
         utterances.extend(self._getSpeechForObjectAvailability(obj))
 
@@ -440,10 +440,10 @@
                 utterances.extend(name)
             if obj.getRole() == pyatspi.ROLE_TABLE_CELL:
                 utterances.extend(
-                  self._getSpeechForObjectRole(
+                  self.getSpeechForObjectRole(
                     obj, pyatspi.ROLE_CHECK_BOX))
             else:
-                utterances.extend(self._getSpeechForObjectRole(obj))
+                utterances.extend(self.getSpeechForObjectRole(obj))
             utterances.append(checkedState)
             utterances.extend(self._getSpeechForObjectAvailability(obj))
             utterances.extend(self._getSpeechForRequiredObject(obj))
@@ -524,7 +524,7 @@
             utterances.extend(name)
 
         if not already_focused:
-            utterances.extend(self._getSpeechForObjectRole(obj))
+            utterances.extend(self.getSpeechForObjectRole(obj))
 
         utterances.extend(self._getSpeechForObjectAvailability(obj))
 
@@ -670,7 +670,7 @@
             if name != label:
                 utterances.extend(name)
             utterances.extend(self._getSpeechForAllTextSelection(obj))
-            utterances.extend(self._getSpeechForObjectRole(obj))
+            utterances.extend(self.getSpeechForObjectRole(obj))
 
             # If this application has more than one unfocused alert or
             # dialog window, then speak '<m> unfocused dialogs'
@@ -1001,7 +1001,7 @@
             utterances.append(settings.speechReadOnlyString)
 
         if obj.getRole() != pyatspi.ROLE_PARAGRAPH:
-            utterances.extend(self._getSpeechForObjectRole(obj))
+            utterances.extend(self.getSpeechForObjectRole(obj))
 
         [text, caretOffset, startOffset] = self._script.getTextLineAtCaret(obj)
         utterances.append(text)
@@ -1104,7 +1104,7 @@
             name = self._getSpeechForObjectName(obj)
             if name != label:
                 utterances.extend(name)
-            utterances.extend(self._getSpeechForObjectRole(obj))
+            utterances.extend(self.getSpeechForObjectRole(obj))
 
         utterances.append(percentage)
 
@@ -1170,7 +1170,7 @@
             #utterances.extend(self._getSpeechForObjectLabel(obj))
             utterances.extend(self._getSpeechForObjectName(obj))
             utterances.append(selectionState)
-            utterances.extend(self._getSpeechForObjectRole(obj))
+            utterances.extend(self.getSpeechForObjectRole(obj))
             utterances.extend(self._getSpeechForObjectAvailability(obj))
         else:
             utterances.append(selectionState)
@@ -1278,7 +1278,7 @@
             #
             if not utterances:
                 utterances.extend(self._getSpeechForObjectName(obj))
-            utterances.extend(self._getSpeechForObjectRole(obj))
+            utterances.extend(self.getSpeechForObjectRole(obj))
             utterances.append(valueString)
             utterances.extend(self._getSpeechForObjectAvailability(obj))
             utterances.extend(self._getSpeechForRequiredObject(obj))
@@ -1333,7 +1333,7 @@
             utterances.extend(self._getSpeechForObjectLabel(obj))
             if not utterances:
                 utterances.extend(self._getSpeechForObjectName(obj))
-            utterances.extend(self._getSpeechForObjectRole(obj))
+            utterances.extend(self.getSpeechForObjectRole(obj))
             utterances.append(valueString)
             utterances.extend(self._getSpeechForObjectAvailability(obj))
 
@@ -1719,7 +1719,7 @@
             name = self._getSpeechForObjectName(obj)
             if name != label:
                 utterances.extend(name)
-            utterances.extend(self._getSpeechForObjectRole(obj))
+            utterances.extend(self.getSpeechForObjectRole(obj))
             utterances.append(checkedState)
             utterances.extend(self._getSpeechForObjectAvailability(obj))
         else:
