[orca] Rewrite many of the utility methods for accessing Gecko content



commit 563a6c125c1ea855e26359530065dde4eeb6a222
Author: Joanmarie Diggs <jdiggs igalia com>
Date:   Wed May 27 22:54:45 2015 -0400

    Rewrite many of the utility methods for accessing Gecko content
    
    Fixes:
    * Performance through caching return values of frequently-called methods
    * Present "link" when arrowing into text descendants of links
    * Display inferred labels for radiobuttons and checkboxes in same
      order as if they were proper labels
    * Increase consistency between presentation of ARIA and native apps
    * Eliminate more unnecessary braille refreshing
    * Stop presenting content from the wrong document frame
    * Stop presenting images which are not rendered and have no alt text
    * Stop double-presenting inferred labels in SayAll
    * Present "link" as part of the same utterance when navigating by line
    * Fix bogus duplicate characters in braille
    * Fix treating inline block spans displayed on a single line as if they
      were on multiple lines
    
    Also remove UI tests for dialogs which no longer exist in Firefox.

 src/orca/braille_generator.py                      |    3 +
 src/orca/formatting.py                             |   26 +-
 src/orca/generator.py                              |   41 +-
 src/orca/label_inference.py                        |  147 +--
 src/orca/liveregions.py                            |    4 +-
 src/orca/script_utilities.py                       |   63 +-
 src/orca/scripts/apps/Instantbird/script.py        |    4 +-
 src/orca/scripts/apps/Thunderbird/Makefile.am      |    1 -
 src/orca/scripts/apps/Thunderbird/script.py        |   56 +-
 .../scripts/apps/Thunderbird/script_utilities.py   |   79 -
 src/orca/scripts/default.py                        |    3 +-
 src/orca/scripts/toolkits/Gecko/Makefile.am        |    1 -
 src/orca/scripts/toolkits/Gecko/bookmarks.py       |   10 +-
 .../scripts/toolkits/Gecko/braille_generator.py    |  190 +--
 src/orca/scripts/toolkits/Gecko/formatting.py      |   58 -
 src/orca/scripts/toolkits/Gecko/script.py          | 1329 ++++--------------
 .../scripts/toolkits/Gecko/script_utilities.py     | 1557 ++++++++++++++------
 .../scripts/toolkits/Gecko/speech_generator.py     |  552 +++----
 .../toolkits/Gecko/structural_navigation.py        |   20 +-
 .../scripts/toolkits/WebKitGtk/script_utilities.py |    3 +
 src/orca/speech_generator.py                       |   59 +-
 test/html/inline-block-spans.html                  |   25 +
 test/html/paragraphs-in-links.html                 |   11 +
 test/keystrokes/firefox/aria_alert.py              |    9 +-
 test/keystrokes/firefox/aria_alert_dialog.py       |   15 +-
 test/keystrokes/firefox/aria_button.py             |    4 +-
 test/keystrokes/firefox/aria_button_dojo.py        |   23 +-
 test/keystrokes/firefox/aria_button_toggle.py      |   28 +-
 test/keystrokes/firefox/aria_checkbox_dojo.py      |   12 +-
 test/keystrokes/firefox/aria_combobox_dojo.py      |   11 +-
 test/keystrokes/firefox/aria_dialog_dojo.py        |   10 +-
 test/keystrokes/firefox/aria_landmarks.py          |    6 +-
 test/keystrokes/firefox/aria_menu.py               |   70 +-
 test/keystrokes/firefox/aria_slider.py             |    4 +-
 test/keystrokes/firefox/aria_slider_dojo.py        |    8 +-
 test/keystrokes/firefox/aria_spinner_dojo.py       |    4 +-
 test/keystrokes/firefox/aria_tabcontainer_dojo.py  |   14 +-
 test/keystrokes/firefox/aria_tabpanel.py           |   18 +-
 test/keystrokes/firefox/aria_tabpanel2.py          |   14 +-
 test/keystrokes/firefox/aria_tabpanel_text_dojo.py |   17 +-
 test/keystrokes/firefox/aria_toolbar_dojo.py       |   17 +-
 test/keystrokes/firefox/aria_tree.py               |   18 -
 test/keystrokes/firefox/aria_tree_dojo.py          |   20 -
 test/keystrokes/firefox/aria_treegrid.py           |   16 +-
 test/keystrokes/firefox/find_wiki.py               |    9 +-
 test/keystrokes/firefox/flat_review_combo_box.py   |    2 +-
 .../firefox/focus_tracking_descriptions.py         |   40 +-
 test/keystrokes/firefox/focus_tracking_imagemap.py |   15 +-
 .../firefox/focus_tracking_link_child_of_body.py   |   16 +-
 test/keystrokes/firefox/focus_tracking_links.py    |    6 +-
 test/keystrokes/firefox/html_role_combo_box.py     |   46 +-
 test/keystrokes/firefox/html_role_links.py         |   39 +-
 .../firefox/html_role_list_item_where_am_i.py      |   16 +-
 .../firefox/html_struct_nav_activate_link.py       |   13 +-
 .../firefox/html_struct_nav_blockquote.py          |    2 +-
 .../firefox/html_struct_nav_bug_554616.py          |   20 +-
 .../firefox/html_struct_nav_bug_567984.py          |   31 +-
 .../firefox/html_struct_nav_descriptions.py        |   29 +-
 .../html_struct_nav_heading_in_div_with_text.py    |   52 +-
 .../html_struct_nav_headings_buried_deep.py        |   12 +-
 .../firefox/html_struct_nav_hidden_paragraphs.py   |   24 +-
 test/keystrokes/firefox/html_struct_nav_links.py   |   42 +-
 .../firefox/label_inference_bug_546815.py          |   64 +-
 .../firefox/label_inference_bugzilla_search.py     |  136 +-
 test/keystrokes/firefox/label_inference_entries.py |  153 +-
 test/keystrokes/firefox/label_inference_mailman.py |   48 +-
 test/keystrokes/firefox/line_nav_bug_546815.py     |  102 +-
 test/keystrokes/firefox/line_nav_bug_549128.py     |   30 +-
 test/keystrokes/firefox/line_nav_bug_552887a.py    |   64 +-
 test/keystrokes/firefox/line_nav_bug_554616.py     |   55 +-
 test/keystrokes/firefox/line_nav_bug_555055.py     |   90 +-
 test/keystrokes/firefox/line_nav_bug_577239.py     |    8 +-
 .../firefox/line_nav_bugzilla_search_down.py       |  154 +--
 .../firefox/line_nav_bugzilla_search_up.py         |  138 +-
 ...av_button_in_link_position_relative_on_focus.py |   14 +-
 test/keystrokes/firefox/line_nav_descriptions.py   |    9 +-
 test/keystrokes/firefox/line_nav_empty_anchor.py   |   30 +-
 test/keystrokes/firefox/line_nav_enter_bug.py      |  318 ++---
 test/keystrokes/firefox/line_nav_entries.py        |   98 +-
 test/keystrokes/firefox/line_nav_focused_link.py   |   11 +-
 .../firefox/line_nav_follow_same_page_link.py      |   16 +-
 .../firefox/line_nav_follow_same_page_link_2.py    |    4 +-
 test/keystrokes/firefox/line_nav_hidden_buttons.py |   34 +-
 test/keystrokes/firefox/line_nav_hidden_float.py   |    8 +-
 test/keystrokes/firefox/line_nav_hidden_label.py   |   47 +-
 test/keystrokes/firefox/line_nav_hidden_links.py   |   12 +-
 .../firefox/line_nav_home_end_on_blank_line.params |    1 -
 .../firefox/line_nav_home_end_on_blank_line.py     |   35 -
 .../firefox/line_nav_iframes_in_inline_block.py    |   26 +-
 .../firefox/line_nav_iframes_in_inline_block2.py   |   26 +-
 test/keystrokes/firefox/line_nav_image_in_link.py  |   23 +-
 .../keystrokes/firefox/line_nav_images_in_links.py |  103 +-
 .../firefox/line_nav_inline_block_spans.params     |    1 +
 .../firefox/line_nav_inline_block_spans.py         |   55 +
 .../line_nav_link_position_relative_on_focus.py    |    6 +-
 .../keystrokes/firefox/line_nav_multi_line_text.py |   45 +-
 test/keystrokes/firefox/line_nav_nested_tables.py  |  196 +---
 .../firefox/line_nav_paragraphs_in_links.params    |    1 +
 .../firefox/line_nav_paragraphs_in_links.py        |   71 +
 test/keystrokes/firefox/line_nav_pre_lines.py      |   74 +-
 test/keystrokes/firefox/line_nav_pre_links.py      |   34 +-
 test/keystrokes/firefox/line_nav_simple_form.py    |   81 +-
 test/keystrokes/firefox/line_nav_slash_test.py     |   40 +-
 test/keystrokes/firefox/line_nav_sun_java.py       |  184 +--
 .../firefox/line_nav_table_cell_links.py           |   37 +-
 test/keystrokes/firefox/line_nav_twitter_bug.py    |    8 +-
 test/keystrokes/firefox/line_nav_wiki_down.py      |  219 +--
 test/keystrokes/firefox/line_nav_wiki_up.py        |  221 +--
 test/keystrokes/firefox/link_where_am_i.py         |    8 +-
 test/keystrokes/firefox/longdesc_10.py             |    7 +-
 .../keystrokes/firefox/object_nav_links_in_text.py |   68 +-
 .../keystrokes/firefox/object_nav_links_on_line.py |    4 +
 .../firefox/object_nav_simple_form_down.py         |   62 +-
 .../firefox/object_nav_simple_form_up.py           |   48 +-
 test/keystrokes/firefox/say_all_blockquote.py      |    3 +-
 test/keystrokes/firefox/say_all_bug_591351_1.py    |    3 +-
 test/keystrokes/firefox/say_all_bugzilla_search.py |   44 +-
 test/keystrokes/firefox/say_all_empty_anchor.py    |   21 +-
 test/keystrokes/firefox/say_all_enter_bug.py       |   11 -
 test/keystrokes/firefox/say_all_entries.py         |   42 +-
 test/keystrokes/firefox/say_all_multi_line_text.py |    4 +-
 test/keystrokes/firefox/say_all_role_combo_box.py  |    3 -
 test/keystrokes/firefox/say_all_simple_form.py     |   22 +-
 test/keystrokes/firefox/say_all_wiki.py            |   24 +-
 test/keystrokes/firefox/spelling_errors.py         |  176 ++--
 test/keystrokes/firefox/ui_doc_tabs.py             |   16 +-
 test/keystrokes/firefox/ui_role_accel_label.py     |    1 +
 test/keystrokes/firefox/ui_role_check_menu_item.py |    1 +
 test/keystrokes/firefox/ui_role_combo_box.py       |  105 --
 test/keystrokes/firefox/ui_role_list_item.py       |   41 -
 test/keystrokes/firefox/ui_role_menu_bar.py        |    1 +
 test/keystrokes/firefox/ui_role_radio_button.py    |    3 +-
 test/keystrokes/firefox/ui_role_radio_menu_item.py |    2 +
 test/keystrokes/firefox/word_nav_links.py          |   34 +-
 test/keystrokes/firefox/word_nav_list_items.py     |    2 +-
 135 files changed, 3738 insertions(+), 5142 deletions(-)
---
diff --git a/src/orca/braille_generator.py b/src/orca/braille_generator.py
index f25fd94..23fceb2 100644
--- a/src/orca/braille_generator.py
+++ b/src/orca/braille_generator.py
@@ -297,6 +297,9 @@ class BrailleGenerator(generator.Generator):
             if result and parentResult:
                 result.append(braille.Region(" "))
             result.extend(parentResult)
+            if role == pyatspi.ROLE_EMBEDDED:
+                break
+
             parent = parent.parent
         result.reverse()
         return result
diff --git a/src/orca/formatting.py b/src/orca/formatting.py
index 1bea425..57179b7 100644
--- a/src/orca/formatting.py
+++ b/src/orca/formatting.py
@@ -96,15 +96,15 @@ formatting = {
             },
         'suffix': {
             'focused': '[]',
-            'unfocused': 'newNodeLevel + unselectedCell + ' + TUTORIAL,
-            'basicWhereAmI': TUTORIAL + ' + description',
+            'unfocused': 'newNodeLevel + unselectedCell + clickable + hasLongDesc + ' + TUTORIAL + ' + 
description',
+            'basicWhereAmI': TUTORIAL + ' + clickable + hasLongDesc + description',
             'detailedWhereAmI' : '[]'
             },
         'default': {
             'focused': '[]',
             'unfocused': 'labelOrName + allTextSelection + roleName + availability + ' + MNEMONIC + ' + 
accelerator + childWidget',
             'basicWhereAmI': 'labelOrName + roleName',
-            'detailedWhereAmI' : '[]'
+            'detailedWhereAmI' : 'pageSummary'
             },
         pyatspi.ROLE_ALERT: {
             'unfocused': 'expandedEOCs or (labelOrName + unrelatedLabels)'
@@ -118,6 +118,9 @@ formatting = {
             'basicWhereAmI': 'parentRoleName + labelAndName + selectedItemCount',
             'detailedWhereAmI': 'parentRoleName + labelAndName + selectedItemCount + selectedItems'
             },
+        pyatspi.ROLE_CAPTION: {
+            'unfocused': '((substring and currentLineText) or labelAndName) + roleName'
+            },
         pyatspi.ROLE_CHECK_BOX: {
             'focused': 'checkedState',
             'unfocused': 'labelOrName + roleName + checkedState + required + availability + ' + MNEMONIC + ' 
+ accelerator',
@@ -133,6 +136,9 @@ formatting = {
             'unfocused': 'label + roleName + value + required + availability + ' + MNEMONIC,
             'basicWhereAmI': 'label + roleName + value + percentage + ' + MNEMONIC + ' + accelerator + 
required'
             },
+        pyatspi.ROLE_COLUMN_HEADER: {
+            'unfocused': '((substring and currentLineText) or labelAndName) + roleName'
+            },
         pyatspi.ROLE_COMBO_BOX: {
             'focused': 'expandableState',
             'unfocused': 'label + name + roleName + positionInList + ' + MNEMONIC + ' + accelerator',
@@ -152,6 +158,10 @@ formatting = {
             'basicWhereAmI': 'label + readOnly + textRole + textContent + anyTextSelection + ' + MNEMONIC,
             'detailedWhereAmI': 'label + readOnly + textRole + textContentWithAttributes + anyTextSelection 
+ ' + MNEMONIC + ' + ' + TUTORIAL
             },
+        pyatspi.ROLE_EMBEDDED: {
+            'focused': 'labelOrName + roleName',
+            'unfocused': '(expandedEOCs or (labelOrName + unrelatedLabels)) + roleName'
+            },
         pyatspi.ROLE_ENTRY: {
             'focused': 'labelOrName + readOnly + textRole + (currentLineText or placeholderText) + 
allTextSelection',
             'unfocused': 'labelOrName + readOnly + textRole + (currentLineText or placeholderText) + 
allTextSelection + ' + MNEMONIC,
@@ -177,6 +187,9 @@ formatting = {
             'basicWhereAmI': 'parentRoleName + labelAndName + selectedItemCount',
             'detailedWhereAmI': 'parentRoleName + labelAndName + selectedItemCount + selectedItems'
             },
+        pyatspi.ROLE_IMAGE: {
+            'unfocused': 'labelAndName + roleName'
+            },
         pyatspi.ROLE_INFO_BAR: {
             'unfocused': 'labelAndName + unrelatedLabels'
             },
@@ -274,6 +287,9 @@ formatting = {
             'unfocused': 'labelOrName + radioState + roleName + availability + ' + MNEMONIC + ' + 
accelerator + positionInList',
             'basicWhereAmI': 'ancestors + labelOrName + roleName + radioState + accelerator + positionInList 
+ ' + MNEMONIC
             },
+        pyatspi.ROLE_ROW_HEADER: {
+            'unfocused': '((substring and currentLineText) or labelAndName) + roleName'
+            },
         pyatspi.ROLE_SCROLL_BAR: {
             'focused': 'value',
             'unfocused': 'labelOrName + roleName + value + required + availability + ' + MNEMONIC,
@@ -613,7 +629,9 @@ formatting = {
                                      asString((labelOrName or description) + expandableState + roleName),\
                                      indicator=asString(toggleState))]'
             },
-        #pyatspi.ROLE_TOOL_BAR: 'default'
+        pyatspi.ROLE_TOOL_BAR: {
+            'unfocused': '[Component(obj, asString(labelOrName + roleName))]',
+            },
         #pyatspi.ROLE_TREE: 'default'
         #pyatspi.ROLE_TREE_TABLE: 'default'
         #pyatspi.ROLE_WINDOW: 'default'
diff --git a/src/orca/generator.py b/src/orca/generator.py
index 24ee381..4fa154c 100644
--- a/src/orca/generator.py
+++ b/src/orca/generator.py
@@ -155,6 +155,9 @@ class Generator:
         else:
             del args['role']
 
+    def generateContents(self, contents, **args):
+        return []
+
     def generate(self, obj, **args):
         """Returns an array of strings (and possibly voice and audio
         specifications) that represent the complete presentatin for the
@@ -321,6 +324,16 @@ class Generator:
                 return result
             if description:
                 result.append(description)
+            else:
+                link = None
+                if obj.getRole() == pyatspi.ROLE_LINK:
+                    link = obj
+                elif obj.parent.getRole() == pyatspi.ROLE_LINK:
+                    link = obj.parent
+                if link:
+                    basename = self._script.utilities.linkBasename(link)
+                    if basename:
+                        result.append(basename)
         # To make the unlabeled icons in gnome-panel more accessible.
         try:
             role = args.get('role', obj.getRole())
@@ -422,23 +435,9 @@ class Generator:
     #####################################################################
 
     def _generateClickable(self, obj, **args):
-        if not args.get('mode', None):
-            args['mode'] = self._mode
-        args['stringType'] = 'clickable'
-
-        if self._script.utilities.isClickableElement(obj):
-            return [self._script.formatting.getString(**args)]
-
         return []
 
     def _generateHasLongDesc(self, obj, **args):
-        if not args.get('mode', None):
-            args['mode'] = self._mode
-        args['stringType'] = 'haslongdesc'
-
-        if self._script.utilities.hasLongDesc(obj):
-            return [self._script.formatting.getString(**args)]
-
         return []
 
     def _generateAvailability(self, obj, **args):
@@ -764,10 +763,14 @@ class Generator:
         """Returns an array of strings for use by speech and braille to present
         the size of a table."""
 
+        if self._script.utilities.isLayoutOnly(obj):
+            return []
+
         try:
             table = obj.queryTable()
         except:
             return []
+
         return [messages.tableSize(table.nRows, table.nColumns)]       
 
     def _generateTableCellRow(self, obj, **args):
@@ -849,7 +852,7 @@ class Generator:
     def _generateSubstring(self, obj, **args):
         start = args.get('startOffset')
         end = args.get('endOffset')
-        if start == None or end == None:
+        if start is None or end is None:
             return []
 
         substring = self._script.utilities.substring(obj, start, end)
@@ -952,6 +955,11 @@ class Generator:
         """Returns an array of strings for use by speech and braille that
         represent the nesting level of an object in a list.
         """
+        start = args.get('startOffset')
+        end = args.get('endOffset')
+        if start is not None and end is not None:
+            return []
+
         result = []
         if not args.get('mode', None):
             args['mode'] = self._mode
@@ -1031,3 +1039,6 @@ class Generator:
                     break
             parent = parent.parent
         return result
+
+    def _generatePageSummary(self, obj, **args):
+        return []
diff --git a/src/orca/label_inference.py b/src/orca/label_inference.py
index 3025bd4..69bf78f 100644
--- a/src/orca/label_inference.py
+++ b/src/orca/label_inference.py
@@ -219,11 +219,8 @@ class LabelInference:
             return rv
 
         extents = 0, 0, 0, 0
-        try:
-            text = obj.queryText()
-        except NotImplementedError:
-            pass
-        else:
+        text = self._script.utilities.queryNonEmptyText(obj)
+        if text:
             skipTextExtents = [pyatspi.ROLE_ENTRY, pyatspi.ROLE_PASSWORD_TEXT]
             if not obj.getRole() in skipTextExtents:
                 if endOffset == -1:
@@ -241,20 +238,20 @@ class LabelInference:
         """Gets the functional label text associated with the object obj."""
 
         if not self._isSimpleObject(obj):
-            return ''
+            return None, []
 
         if self._cannotLabel(obj):
-            return ''
+            return None, []
 
-        contents = self._script.utilities.getObjectsFromEOCs(obj)
+        contents = self._script.utilities.getObjectContentsAtOffset(obj, useCache=False)
         objects = [content[0] for content in contents]
         if list(filter(self._isWidget, objects)):
-            return ''
+            return None, []
 
-        strings = [content[3] or content[0].name for content in contents]
-        return ''.join(strings)
+        strings = [content[3] for content in contents]
+        return ''.join(strings), objects
 
-    def _getLineContents(self, obj):
+    def _getLineContents(self, obj, start=0):
         """Get the (obj, startOffset, endOffset, string) tuples for the line
         containing the object, obj."""
 
@@ -263,20 +260,11 @@ class LabelInference:
             return rv
 
         key = hash(obj)
-        start = None
         if self._isWidget(obj):
             start, end = self._script.utilities.getHyperlinkRange(obj)
             obj = obj.parent
 
-        try:
-            text = obj.queryText()
-        except:
-            start = 0
-        else:
-            if start == None:
-                start = max(0, text.caretOffset)
-
-        rv = self._script.utilities.getLineContentsAtOffset(obj, start)
+        rv = self._script.utilities.getLineContentsAtOffset(obj, start, True, False)
         self._lineCache[key] = rv
 
         return rv
@@ -331,9 +319,9 @@ class LabelInference:
         lExtents = self._getExtents(lObj, start, end)
         distance = extents[0] - (lExtents[0] + lExtents[2])
         if 0 <= distance <= proximity:
-            strings = [content[3] or content[0].name for content in onLeft]
-            result = ''.join(strings)
-            if result.strip():
+            strings = [content[3] for content in onLeft]
+            result = ''.join(strings).strip()
+            if result:
                 return result, [content[0] for content in onLeft]
 
         return None, []
@@ -378,9 +366,9 @@ class LabelInference:
         rExtents = self._getExtents(rObj, start, end)
         distance = rExtents[0] - (extents[0] + extents[2])
         if distance <= proximity or self._preferRight(obj):
-            strings = [content[3] or content[0].name for content in onRight]
-            result = ''.join(strings)
-            if result.strip():
+            strings = [content[3] for content in onRight]
+            result = ''.join(strings).strip()
+            if result:
                 return result, [content[0] for content in onRight]
 
         return None, []
@@ -398,51 +386,27 @@ class LabelInference:
         """
 
         thisLine = self._getLineContents(obj)
-        if not (thisLine and thisLine[0]):
-            return None, []
-
-        prevObj, start, end, string = thisLine[0]
-        if obj == prevObj:
-            start, end = self._script.utilities.getHyperlinkRange(prevObj)
-            prevObj = prevObj.parent
-
+        content = [o for o in thisLine if o[0] == obj]
         try:
-            text = prevObj.queryText()
-        except (AttributeError, NotImplementedError):
+            index = thisLine.index(content[0])
+        except IndexError:
             return None, []
-
-        objX, objY, objWidth, objHeight = self._getExtents(obj)
-        if not (objWidth and objHeight):
+        if index > 0:
             return None, []
 
-        start = max(start - 1, 0)
-        prevLine = self._script.utilities.getLineContentsAtOffset(prevObj, start)
-        if not (prevLine and prevLine[0]):
+        prevObj, prevOffset = self._script.utilities.previousContext(
+            thisLine[0][0], thisLine[0][1], True)
+        prevLine = self._getLineContents(prevObj, prevOffset)
+        if len(prevLine) != 1:
             return None, []
 
         prevObj, start, end, string = prevLine[0]
-        if string.strip() and not self._cannotLabel(prevObj):
+        if string.strip():
             x, y, width, height = self._getExtents(prevObj, start, end)
+            objX, objY, objWidth, objHeight = self._getExtents(obj)
             distance = objY - (y + height)
-            if 0 <= distance <= proximity:
-                return string, [prevObj]
-
-        while prevObj:
-            prevObj = self._getPreviousObject(prevObj)
-            x, y, width, height = self._getExtents(prevObj)
-            distance = objY - (y + height)
-            if distance > proximity:
-                return None, []
-            if prevObj.getRole() == pyatspi.ROLE_TABLE_CELL \
-               and not prevObj in [obj.parent, obj.parent.parent]:
-                return None, []
-            if distance < 0:
-                continue
-            if x + 150 < objX:
-                continue
-            string = self._createLabelFromContents(prevObj)
-            if string:
-                return string, [prevObj]
+            if 0 <= distance <= proximity and x <= objX:
+                return string.strip(), [prevObj]
 
         return None, []
 
@@ -462,28 +426,27 @@ class LabelInference:
             return None, []
 
         thisLine = self._getLineContents(obj)
-        if not (thisLine and thisLine[0]):
+        content = [o for o in thisLine if o[0] == obj]
+        try:
+            index = thisLine.index(content[0])
+        except IndexError:
             return None, []
-
-        lastObj, start, end, string = thisLine[-1]
-        if obj == lastObj:
-            start, end = self._script.utilities.getHyperlinkRange(obj)
-            lastObj = lastObj.parent
-
-        objX, objY, objWidth, objHeight = self._getExtents(obj)
-        if not (objWidth and objHeight):
+        if index > 0:
             return None, []
 
-        nextLine = self._script.utilities.getLineContentsAtOffset(lastObj, end)
-        if not (nextLine and nextLine[0]):
+        nextObj, nextOffset = self._script.utilities.nextContext(
+            thisLine[-1][0], thisLine[-1][2] - 1, True)
+        nextLine = self._getLineContents(nextObj, nextOffset)
+        if len(nextLine) != 1:
             return None, []
 
         nextObj, start, end, string = nextLine[0]
-        if string.strip() and not self._cannotLabel(nextObj):
+        if string.strip():
             x, y, width, height = self._getExtents(nextObj, start, end)
+            objX, objY, objWidth, objHeight = self._getExtents(obj)
             distance = y - (objY + objHeight)
             if 0 <= distance <= proximity:
-                return string, [nextObj]
+                return string.strip(), [nextObj]
 
         return None, []
 
@@ -524,29 +487,29 @@ class LabelInference:
 
         if col > 0 and not self._preferRight(obj):
             candidate = table.getAccessibleAt(row, col - 1)
-            label = self._createLabelFromContents(candidate)
-            if label.strip():
-                return label, [candidate]
+            label, sources = self._createLabelFromContents(candidate)
+            if label:
+                return label.strip(), sources
 
         if col < table.nColumns and not self._preventRight(obj):
             candidate = table.getAccessibleAt(row, col + 1)
             x, y, width, height = self._getExtents(candidate)
             distance = x - (objX + objWidth)
             if distance <= proximityForRight or self._preferRight(obj):
-                label = self._createLabelFromContents(candidate)
-                if label.strip():
-                    return label, [candidate]
+                label, sources = self._createLabelFromContents(candidate)
+                if label:
+                    return label.strip(), sources
 
         cellAbove = cellBelow = labelAbove = labelBelow = None
         if row > 0:
             cellAbove = table.getAccessibleAt(row - 1, col)
-            labelAbove = self._createLabelFromContents(cellAbove)
+            labelAbove, sourcesAbove = self._createLabelFromContents(cellAbove)
             if labelAbove and self._preferTop(obj):
-                return labelAbove, [cellAbove]
+                return labelAbove.strip(), sourcesAbove
 
         if row < table.nRows and not self._preventBelow(obj):
             cellBelow = table.getAccessibleAt(row + 1, col)
-            labelBelow = self._createLabelFromContents(cellBelow)
+            labelBelow, sourcesBelow = self._createLabelFromContents(cellBelow)
 
         if labelAbove and labelBelow:
             aboveX, aboveY, aboveWidth, aboveHeight = self._getExtents(cellAbove)
@@ -554,13 +517,13 @@ class LabelInference:
             dAbove = objY - (aboveY + aboveHeight)
             dBelow = belowY - (objY + objHeight)
             if dAbove <= dBelow:
-                return labelAbove, [cellAbove]
-            return labelBelow, [cellBelow]
+                return labelAbove.strip(), sourcesAbove
+            return labelBelow.strip(), sourcesBelow
 
         if labelAbove:
-            return labelAbove, [cellAbove]
+            return labelAbove.strip(), sourcesAbove
         if labelBelow:
-            return labelBelow, [cellBelow]
+            return labelBelow.strip(), sourcesBelow
 
         # None of the cells immediately surrounding this cell seem to be serving
         # as a functional label. Therefore, see if this table looks like a grid
@@ -574,8 +537,8 @@ class LabelInference:
         if [x for x in cells if x.childCount and x[0].getRole() != obj.getRole()]:
             return None, []
 
-        label = self._createLabelFromContents(firstRow[col])
+        label, sources = self._createLabelFromContents(firstRow[col])
         if label:
-            return label, [firstRow[col]]
+            return label.strip(), sources
 
         return None, []
diff --git a/src/orca/liveregions.py b/src/orca/liveregions.py
index 04e27b4..c0dfa52 100644
--- a/src/orca/liveregions.py
+++ b/src/orca/liveregions.py
@@ -278,8 +278,8 @@ class LiveRegionManager:
         """Move the caret to the last announced live region and speak the 
         contents of that object"""
         if self.lastliveobj:
-            self._script.setCaretPosition(self.lastliveobj, 0)
-            self._script.speakContents(self._script.getObjectContentsAtOffset(\
+            self._script.utilities.setCaretPosition(self.lastliveobj, 0)
+            self._script.speakContents(self._script.utilities.getObjectContentsAtOffset(
                                        self.lastliveobj, 0))
 
     def reviewLiveAnnouncement(self, msgnum):
diff --git a/src/orca/script_utilities.py b/src/orca/script_utilities.py
index c08f249..4e054a8 100644
--- a/src/orca/script_utilities.py
+++ b/src/orca/script_utilities.py
@@ -160,6 +160,15 @@ class Utilities:
         -obj: the table cell whose index we need.
         """
 
+        try:
+            attrs = dict([attr.split(':', 1) for attr in obj.getAttributes()])
+        except:
+            attrs = {}
+
+        index = attrs.get('table-cell-index')
+        if index:
+            return int(index)
+
         return obj.getIndexInParent()
 
     def childNodes(self, obj):
@@ -1654,8 +1663,7 @@ class Utilities:
 
         return False
 
-    @staticmethod
-    def queryNonEmptyText(obj):
+    def queryNonEmptyText(self, obj):
         """Get the text interface associated with an object, if it is
         non-empty.
 
@@ -1769,19 +1777,6 @@ class Utilities:
 
         return rv, start, end
 
-    def unicodeText(self, obj):
-        """Returns the unicode text for an object or None if the object
-        doesn't implement the accessible text specialization.
-        """
-
-        # TODO: eliminate calls to this now-redundant method
-
-        text = self.queryNonEmptyText(obj)
-        if text:
-            return text.getText(0, -1)
-
-        return None
-
     def willEchoCharacter(self, event):
         """Given a keyboard event containing an alphanumeric key,
         determine if the script is likely to echo it as a character.
@@ -2362,23 +2357,10 @@ class Utilities:
             debug.printException(debug.LEVEL_WARNING)
             return ""
 
-    def getLineContentsAtOffset(self, obj, offset, layoutMode=True):
+    def getLineContentsAtOffset(self, obj, offset, layoutMode=True, useCache=True):
         return []
 
-    def getObjectsFromEOCs(self, obj, offset=None, boundary=None):
-        """Breaks the string containing a mixture of text and embedded object
-        characters into a list of (obj, startOffset, endOffset, string) tuples.
-
-        Arguments
-        - obj: the object whose EOCs we need to expand into tuples
-        - offset: the character offset. If None, use the current offset.
-        - boundary: the pyatspi text boundary type. If None, get all text.
-
-        Returns a list of (obj, startOffset, endOffset, string) tuples.
-        """
-
-        # For now, each script should implement this functionality itself.
-
+    def getObjectContentsAtOffset(self, obj, offset=0, useCache=True):
         return []
 
     @staticmethod
@@ -2452,21 +2434,14 @@ class Utilities:
         return False
 
     def headingLevel(self, obj):
-        level = 0
-
-        if obj is None:
-            return level
-
-        if obj.getRole() == pyatspi.ROLE_HEADING:
-            attributes = obj.getAttributes()
-            if attributes is None:
-                return level
-            for attribute in attributes:
-                if attribute.startswith("level:"):
-                    level = int(attribute.split(":")[1])
-                    break
+        if not (obj and obj.getRole() == pyatspi.ROLE_HEADING):
+            return 0
 
-        return level
+        try:
+            attrs = dict([attr.split(':', 1) for attr in obj.getAttributes()])
+        except:
+            return 0
+        return int(attrs.get('level', '0'))
 
     def hasMeaningfulToggleAction(self, obj):
         try:
diff --git a/src/orca/scripts/apps/Instantbird/script.py b/src/orca/scripts/apps/Instantbird/script.py
index a80265d..e113b3b 100644
--- a/src/orca/scripts/apps/Instantbird/script.py
+++ b/src/orca/scripts/apps/Instantbird/script.py
@@ -140,7 +140,7 @@ class Script(Gecko.Script):
         accessible text specialization, the characterOffset value
         is meaningless (and typically -1)."""
 
-        if self.inDocumentContent(event.source):
+        if self.utilities.inDocumentContent(event.source):
             orca.setLocusOfFocus(event, event.source)
             Gecko.Script.onCaretMoved(self, event)
         else:
@@ -193,7 +193,7 @@ class Script(Gecko.Script):
                 orca.setLocusOfFocus(event, event.source)
                 return
 
-        if self.inDocumentContent(event.source):
+        if self.utilities.inDocumentContent(event.source):
             Gecko.Script.onFocusedChanged(self, event)
         else:
             default.Script.onFocusedChanged(self, event)
diff --git a/src/orca/scripts/apps/Thunderbird/Makefile.am b/src/orca/scripts/apps/Thunderbird/Makefile.am
index 2e38f1a..059501c 100644
--- a/src/orca/scripts/apps/Thunderbird/Makefile.am
+++ b/src/orca/scripts/apps/Thunderbird/Makefile.am
@@ -1,7 +1,6 @@
 orca_python_PYTHON = \
        __init__.py \
        script.py \
-       script_utilities.py \
        speech_generator.py \
        spellcheck.py
 
diff --git a/src/orca/scripts/apps/Thunderbird/script.py b/src/orca/scripts/apps/Thunderbird/script.py
index baed062..1d11bcd 100644
--- a/src/orca/scripts/apps/Thunderbird/script.py
+++ b/src/orca/scripts/apps/Thunderbird/script.py
@@ -40,7 +40,6 @@ from orca.orca_i18n import _
 
 from .speech_generator import SpeechGenerator
 from .spellcheck import SpellCheck
-from .script_utilities import Utilities
 
 _settingsManager = settings_manager.getManager()
 
@@ -88,11 +87,6 @@ class Script(Gecko.Script):
 
         return SpellCheck(self)
 
-    def getUtilities(self):
-        """Returns the utilites for this script."""
-
-        return Utilities(self)
-
     def getAppPreferencesGUI(self):
         """Return a GtkGrid containing the application unique configuration
         GUI items for the current application."""
@@ -167,7 +161,7 @@ class Script(Gecko.Script):
             self.spellcheck.presentSuggestionListItem()
             return
 
-        if not self.inDocumentContent(obj):
+        if not self.utilities.inDocumentContent(obj):
             default.Script.onFocusedChanged(self, event)
             return
 
@@ -175,23 +169,22 @@ class Script(Gecko.Script):
             default.Script.onFocusedChanged(self, event)
             return
 
-        role = obj.getRole()
-        if role != pyatspi.ROLE_DOCUMENT_FRAME:
-            Gecko.Script.onFocusedChanged(self, event)
-            return
-
-        contextObj, contextOffset = self.getCaretContext()
-        if contextObj:
-            return
-
-        orca.setLocusOfFocus(event, obj, notifyScript=False)
+        Gecko.Script.onFocusedChanged(self, event)
 
     def onBusyChanged(self, event):
         """Callback for object:state-changed:busy accessibility events."""
 
         obj = event.source
         if obj.getRole() == pyatspi.ROLE_DOCUMENT_FRAME and not event.detail1:
-            if self.inDocumentContent():
+            try:
+                role = orca_state.locusOfFocus.getRole()
+            except:
+                pass
+            else:
+                if role in [pyatspi.ROLE_FRAME, pyatspi.ROLE_PAGE_TAB]:
+                    orca.setLocusOfFocus(event, event.source, False)
+
+            if self.utilities.inDocumentContent():
                 self.speakMessage(obj.name)
                 self._presentMessage(obj)
 
@@ -353,19 +346,20 @@ class Script(Gecko.Script):
             lastKey, mods = self.utilities.lastKeyAndModifiers()
             if lastKey == "Delete":
                 speech.speak(obj.name)
-                [obj, offset] = self.findFirstCaretContext(obj, 0)
-                self.setCaretPosition(obj, offset)
+                [obj, offset] = self.utilities.findFirstCaretContext(obj, 0)
+                self.utilities.setCaretPosition(obj, offset)
                 return
 
     def _presentMessage(self, documentFrame):
         """Presents the first line of the message, or the entire message,
         depending on the user's sayAllOnLoad setting."""
 
-        [obj, offset] = self.findFirstCaretContext(documentFrame, 0)
-        self.setCaretPosition(obj, offset)
+        [obj, offset] = self.utilities.findFirstCaretContext(documentFrame, 0)
+        self.utilities.setCaretPosition(obj, offset)
         self.updateBraille(obj)
         if not _settingsManager.getSetting('sayAllOnLoad'):
-            self.presentLine(obj, offset)
+            contents = self.utilities.getLineContentsAtOffset(obj, offset)
+            self.speakContents(contents)
         elif _settingsManager.getSetting('enableSpeech'):
             self.sayAll(None)
 
@@ -380,22 +374,6 @@ class Script(Gecko.Script):
 
         Gecko.Script.sayCharacter(self, obj)
 
-    def getBottomOfFile(self):
-        """Returns the object and last caret offset at the bottom of the
-        document frame. Overridden here to handle editable messages.
-        """
-
-        # Pylint thinks that obj is an instance of a list. It most
-        # certainly is not. Silly pylint.
-        #
-        # pylint: disable-msg=E1103
-        #
-        [obj, offset] = Gecko.Script.getBottomOfFile(self)
-        if obj and obj.getState().contains(pyatspi.STATE_EDITABLE):
-            offset += 1
-
-        return [obj, offset]
-
     def toggleFlatReviewMode(self, inputEvent=None):
         """Toggles between flat review mode and focus tracking mode."""
 
diff --git a/src/orca/scripts/default.py b/src/orca/scripts/default.py
index db8c736..c141281 100644
--- a/src/orca/scripts/default.py
+++ b/src/orca/scripts/default.py
@@ -2243,8 +2243,7 @@ class Script(script.Script):
         obj = event.source
         role = obj.getRole()
         if not self.utilities.isSameObject(obj, orca_state.locusOfFocus) \
-           and role != pyatspi.ROLE_TABLE_ROW \
-           and not (role == pyatspi.ROLE_COMBO_BOX and event.detail1):
+           and not role in [pyatspi.ROLE_TABLE_ROW, pyatspi.ROLE_COMBO_BOX]:
             return
 
         oldObj, oldState = self.pointOfReference.get('expandedChange', (None, 0))
diff --git a/src/orca/scripts/toolkits/Gecko/Makefile.am b/src/orca/scripts/toolkits/Gecko/Makefile.am
index e46d6f1..9086687 100644
--- a/src/orca/scripts/toolkits/Gecko/Makefile.am
+++ b/src/orca/scripts/toolkits/Gecko/Makefile.am
@@ -2,7 +2,6 @@ orca_python_PYTHON = \
        __init__.py \
        bookmarks.py \
        braille_generator.py \
-       formatting.py \
        keymaps.py \
        script.py \
        script_utilities.py \
diff --git a/src/orca/scripts/toolkits/Gecko/bookmarks.py b/src/orca/scripts/toolkits/Gecko/bookmarks.py
index ff49b76..93d9c5c 100644
--- a/src/orca/scripts/toolkits/Gecko/bookmarks.py
+++ b/src/orca/scripts/toolkits/Gecko/bookmarks.py
@@ -52,7 +52,7 @@ class GeckoBookmarks(bookmarks.Bookmarks):
         # form bookmark dictionary key
         index = (inputEvent.hw_code, self.getURIKey())
         # convert the current object to a path and bookmark it
-        obj, characterOffset = self._script.getCaretContext()
+        obj, characterOffset = self._script.utilities.getCaretContext()
         path = self._objToPath()
         self._bookmarks[index] = path, characterOffset
         self._script.presentMessage(messages.BOOKMARK_ENTERED)
@@ -71,10 +71,10 @@ class GeckoBookmarks(bookmarks.Bookmarks):
        
         if obj:
             # restore the location
-            self._script.setCaretPosition(obj, characterOffset)
+            self._script.utilities.setCaretPosition(obj, characterOffset)
             self._script.updateBraille(obj)
             self._script.speakContents( \
-                self._script.getObjectContentsAtOffset(obj, characterOffset))
+                self._script.utilities.getObjectContentsAtOffset(obj, characterOffset))
             # update the currentbookmark
             self._currentbookmarkindex[index[1]] = index[0]
         else:
@@ -91,7 +91,7 @@ class GeckoBookmarks(bookmarks.Bookmarks):
             self._script.systemBeep()
             return
             
-        [cur_obj, cur_characterOffset] = self._script.getCaretContext()
+        [cur_obj, cur_characterOffset] = self._script.utilities.getCaretContext()
         
         # Are they the same object?
         if self._script.utilities.isSameObject(cur_obj, obj):
@@ -220,7 +220,7 @@ class GeckoBookmarks(bookmarks.Bookmarks):
         """Given an object, return it's path from the root accessible.  If obj 
         is not provided, the current caret context is used. """
         if not start_obj:
-            [start_obj, characterOffset] = self._script.getCaretContext()    
+            [start_obj, characterOffset] = self._script.utilities.getCaretContext()    
             
         if start_obj is None \
                      or start_obj.getRole() == pyatspi.ROLE_DOCUMENT_FRAME:
diff --git a/src/orca/scripts/toolkits/Gecko/braille_generator.py 
b/src/orca/scripts/toolkits/Gecko/braille_generator.py
index ccdb53b..f69793f 100644
--- a/src/orca/scripts/toolkits/Gecko/braille_generator.py
+++ b/src/orca/scripts/toolkits/Gecko/braille_generator.py
@@ -1,6 +1,8 @@
 # Orca
 #
 # Copyright 2005-2009 Sun Microsystems Inc.
+# Copyright 2010-2011 Orca Team
+# Copyright 2011-2015 Igalia, S.L.
 #
 # This library is free software; you can redistribute it and/or
 # modify it under the terms of the GNU Lesser General Public
@@ -17,59 +19,26 @@
 # Free Software Foundation, Inc., Franklin Street, Fifth Floor,
 # Boston MA  02110-1301 USA.
 
-"""Custom script for Gecko toolkit.
-Please refer to the following URL for more information on the AT-SPI
-implementation in Gecko:
-http://developer.mozilla.org/en/docs/Accessibility/ATSPI_Support
-"""
-
 __id__        = "$Id$"
 __version__   = "$Revision$"
 __date__      = "$Date$"
-__copyright__ = "Copyright (c) 2005-2009 Sun Microsystems Inc."
+__copyright__ = "Copyright (c) 2005-2009 Sun Microsystems Inc." \
+                "Copyright (c) 2010-2011 Orca Team" \
+                "Copyright (c) 2011-2015 Igalia, S.L."
 __license__   = "LGPL"
 
 import pyatspi
 
-import orca.braille_generator as braille_generator
-import orca.object_properties as object_properties
-
-from orca.orca_i18n import _ # for gettext support
-
-########################################################################
-#                                                                      #
-# Custom BrailleGenerator                                              #
-#                                                                      #
-########################################################################
+from orca import braille
+from orca import braille_generator
+from orca import messages
+from orca import object_properties
+from orca import orca_state
 
 class BrailleGenerator(braille_generator.BrailleGenerator):
-    """Provides a braille generator specific to Gecko.
-    """
 
     def __init__(self, script):
-        braille_generator.BrailleGenerator.__init__(self, script)
-
-    def _generateInDocumentContent(self, obj, **args):
-        """Returns True if this object is in HTML document content.
-        """
-        return self._script.inDocumentContent(obj)
-
-    def _generateImageLink(self, obj, **args):
-        """Returns the link (if any) for this image.
-        """
-        imageLink = None
-        role = args.get('role', obj.getRole())
-        if role == pyatspi.ROLE_IMAGE:
-            imageLink = self._script.utilities.ancestorWithRole(
-                obj, [pyatspi.ROLE_LINK], [pyatspi.ROLE_DOCUMENT_FRAME])
-        return imageLink
-
-    def __generateHeadingRole(self, obj):
-        result = []
-        level = self._script.utilities.headingLevel(obj)
-        result.append(object_properties.ROLE_HEADING_LEVEL_BRAILLE % level)
-
-        return result
+        super().__init__(script)
 
     def _generateRoleName(self, obj, **args):
         """Prevents some roles from being displayed."""
@@ -79,7 +48,8 @@ class BrailleGenerator(braille_generator.BrailleGenerator):
                         pyatspi.ROLE_PARAGRAPH,
                         pyatspi.ROLE_UNKNOWN]
 
-        if not obj.getState().contains(pyatspi.STATE_FOCUSABLE):
+        state = obj.getState()
+        if not state.contains(pyatspi.STATE_FOCUSABLE):
             doNotDisplay.extend([pyatspi.ROLE_LIST,
                                  pyatspi.ROLE_LIST_ITEM,
                                  pyatspi.ROLE_COLUMN_HEADER,
@@ -90,15 +60,28 @@ class BrailleGenerator(braille_generator.BrailleGenerator):
         if args.get('startOffset') != None and args.get('endOffset') != None:
             doNotDisplay.append(pyatspi.ROLE_ALERT)
 
+        result = []
         role = args.get('role', obj.getRole())
-        if role in doNotDisplay:
-            return []
 
         if role == pyatspi.ROLE_HEADING:
-            return self.__generateHeadingRole(obj)
+            level = self._script.utilities.headingLevel(obj)
+            result.append(object_properties.ROLE_HEADING_LEVEL_BRAILLE % level)
 
-        result = braille_generator.BrailleGenerator._generateRoleName(
-            self, obj, **args)
+        elif role == pyatspi.ROLE_LINK and obj == orca_state.locusOfFocus:
+            if obj.parent.getRole() == pyatspi.ROLE_IMAGE:
+                result.append(messages.IMAGE_MAP_LINK)
+
+        elif role not in doNotDisplay:
+            result = super()._generateRoleName(obj, **args)
+
+        index = args.get('index', 0)
+        total = args.get('total', 1)
+        if index == total - 1 and role != pyatspi.ROLE_HEADING \
+           and (role == pyatspi.ROLE_IMAGE or self._script.utilities.queryNonEmptyText(obj)):
+            isHeading = lambda x: x and x.getRole() == pyatspi.ROLE_HEADING
+            heading = pyatspi.findAncestor(obj, isHeading)
+            if heading:
+                result.extend(self._generateRoleName(heading))
 
         return result
 
@@ -106,57 +89,14 @@ class BrailleGenerator(braille_generator.BrailleGenerator):
         if self._script.utilities.isTextBlockElement(obj):
             return []
 
-        return braille_generator.BrailleGenerator._generateLabelOrName(
-            self, obj, **args)
+        return super()._generateLabelOrName(obj, **args)
 
-    def _generateName(self, obj, **args):
-        result = []
-        role = args.get('role', obj.getRole())
-        if role == pyatspi.ROLE_DOCUMENT_FRAME \
-           and obj.getState().contains(pyatspi.STATE_EDITABLE):
-            return []
+    def _generateLabel(self, obj, **args):
+        label, objects = self._script.utilities.inferLabelFor(obj)
+        if label:
+            return [label]
 
-        result.extend(braille_generator.BrailleGenerator._generateName(
-                              self, obj, **args))
-        if not result and role == pyatspi.ROLE_LIST_ITEM:
-            result.append(self._script.utilities.expandEOCs(obj))
-
-        link = None
-        if role == pyatspi.ROLE_LINK:
-            link = obj
-        elif role == pyatspi.ROLE_IMAGE and not result:
-            link = self._generateImageLink(obj, **args)
-        if link and (not result or len(result[0].strip()) == 0):
-            # If there's no text for the link, expose part of the
-            # URI to the user.
-            #
-            basename = self._script.utilities.linkBasename(link)
-            if basename:
-                result.append(basename)
-
-        return result
-
-    def _generateDescription(self, obj, **args):
-        """Returns an array of strings (and possibly voice and audio
-        specifications) that represent the description of the object,
-        if that description is different from that of the name and
-        label.
-        """
-        if args.get('role', obj.getRole()) == pyatspi.ROLE_LINK \
-           and obj.parent.getRole() == pyatspi.ROLE_IMAGE:
-            result = self._generateName(obj, **args)
-            # Translators: The following string is spoken to let the user
-            # know that he/she is on a link within an image map. An image
-            # map is an image/graphic which has been divided into regions.
-            # Each region can be clicked on and has an associated link.
-            # Please see http://en.wikipedia.org/wiki/Imagemap for more
-            # information and examples.
-            #
-            result.append(_("image map link"))
-        else:
-            result = braille_generator.BrailleGenerator.\
-                           _generateDescription(self, obj, **args)
-        return result
+        return super()._generateLabel(obj, **args)
 
     def _generateExpandedEOCs(self, obj, **args):
         """Returns the expanded embedded object characters for an object."""
@@ -171,7 +111,8 @@ class BrailleGenerator(braille_generator.BrailleGenerator):
 
     def generateBraille(self, obj, **args):
         result = []
-        args['includeContext'] = not self._script.inDocumentContent(obj)
+
+        args['includeContext'] = not self._script.utilities.inDocumentContent(obj)
         oldRole = None
         if self._script.utilities.isClickableElement(obj) \
            or self._script.utilities.isLink(obj):
@@ -187,26 +128,55 @@ class BrailleGenerator(braille_generator.BrailleGenerator):
             if comboBox \
                and not comboBox.getState().contains(pyatspi.STATE_EXPANDED):
                 obj = comboBox
-        result.extend(braille_generator.BrailleGenerator.\
-                          generateBraille(self, obj, **args))
+        result.extend(super().generateBraille(obj, **args))
         del args['includeContext']
         if oldRole:
             self._restoreRole(oldRole, args)
         return result
 
     def _generateEol(self, obj, **args):
-        end = args.get('endOffset')
-        if end == None or obj.getState().contains(pyatspi.STATE_EDITABLE) \
-           or not self._script.inDocumentContent(obj):
-            return braille_generator.BrailleGenerator._generateEol(self, obj, **args)
+        if obj.getState().contains(pyatspi.STATE_EDITABLE) \
+           or not self._script.utilities.inDocumentContent(obj):
+            return super()._generateEol(obj, **args)
 
         return []
 
-    def _generateNestingLevel(self, obj, **args):
-        start = args.get('startOffset')
-        end = args.get('endOffset')
-        if start != None and end != None:
+    def generateContents(self, contents, **args):
+        if not len(contents):
             return []
 
-        return braille_generator.BrailleGenerator._generateNestingLevel(
-            self, obj, **args)
+        result = []
+        contents = self._script.utilities.filterContentsForPresentation(contents, False)
+
+        obj, offset = self._script.utilities.getCaretContext(documentFrame=None)
+        index = self._script.utilities.findObjectInContents(obj, offset, contents)
+
+        lastRegion = None
+        focusedRegion = None
+        for i, content in enumerate(contents):
+            acc, start, end, string = content
+            regions, fRegion = self.generateBraille(
+                acc, startOffset=start, endOffset=end, string=string,
+                index=i, total=len(contents))
+            if not regions:
+                continue
+
+            if i == index:
+                focusedRegion = fRegion
+
+            if lastRegion and regions:
+                if lastRegion.string:
+                    lastChar = lastRegion.string[-1]
+                else:
+                    lastChar = ""
+                if regions[0].string:
+                    nextChar = regions[0].string[0]
+                else:
+                    nextChar = ""
+                if self._script.utilities.needsSeparator(lastChar, nextChar):
+                    regions.insert(0, braille.Region(" "))
+
+            lastRegion = regions[-1]
+            result.append(regions)
+
+        return result, focusedRegion
diff --git a/src/orca/scripts/toolkits/Gecko/script.py b/src/orca/scripts/toolkits/Gecko/script.py
index b589391..f802667 100644
--- a/src/orca/scripts/toolkits/Gecko/script.py
+++ b/src/orca/scripts/toolkits/Gecko/script.py
@@ -41,7 +41,6 @@ __license__   = "LGPL"
 from gi.repository import Gtk
 import pyatspi
 import time
-import urllib.parse
 
 import orca.braille as braille
 import orca.cmdnames as cmdnames
@@ -53,7 +52,6 @@ import orca.input_event as input_event
 import orca.keybindings as keybindings
 import orca.liveregions as liveregions
 import orca.messages as messages
-import orca.object_properties as object_properties
 import orca.orca as orca
 import orca.orca_state as orca_state
 import orca.settings as settings
@@ -64,14 +62,11 @@ import orca.speechserver as speechserver
 from . import keymaps
 from .braille_generator import BrailleGenerator
 from .speech_generator import SpeechGenerator
-from .formatting import Formatting
 from .bookmarks import GeckoBookmarks
 from .structural_navigation import GeckoStructuralNavigation
 from .script_utilities import Utilities
 from .tutorial_generator import TutorialGenerator
 
-from orca.orca_i18n import _
-from orca.speech_generator import Pause
 from orca.acss import ACSS
 
 _settingsManager = settings_manager.getManager()
@@ -158,17 +153,11 @@ class Script(default.Script):
         # reached.  Therefore, we need to make an initial announcement, which
         # means we need to know if that has already taken place.
         #
-        self.madeFindAnnouncement = False
+        self._madeFindAnnouncement = False
 
         # Create the live region manager and start the message manager
         self.liveMngr = liveregions.LiveRegionManager(self)
 
-        # We want to keep track of the line contents we just got so that
-        # we can speak and braille this information without having to call
-        # getLineContentsAtOffset() twice.
-        #
-        self.currentLineContents = []
-
         # For really large objects, a call to getAttributes can take up to
         # two seconds! This is a Firefox bug. We'll try to improve things
         # by storing attributes.
@@ -233,12 +222,18 @@ class Script(default.Script):
     def deactivate(self):
         """Called when this script is deactivated."""
 
+        self._sayAllContents = []
         self._inSayAll = False
         self._sayAllIsInterrupted = False
         self._loadingDocumentContent = False
+        self._madeFindAnnouncement = False
         self._lastCommandWasCaretNav = False
         self._lastCommandWasStructNav = False
         self._lastCommandWasMouseButton = False
+        self._lastMouseOverObject = None
+        self._preMouseOverContext = None, -1
+        self._inMouseOverObject = False
+        self.utilities.clearCachedObjects()
 
     def getBookmarks(self):
         """Returns the "bookmarks" class for this script.
@@ -263,10 +258,6 @@ class Script(default.Script):
         """Returns the tutorial generator for this script."""
         return TutorialGenerator(self)
 
-    def getFormatting(self):
-        """Returns the formatting strings for this script."""
-        return Formatting(self)
-
     def getUtilities(self):
         """Returns the utilites for this script."""
 
@@ -704,28 +695,20 @@ class Script(default.Script):
                 self._lastCommandWasMouseButton = False
         return consumes
 
+    # TODO - JD: This needs to be moved out of the scripts.
     def textLines(self, obj, offset=None):
-        """Creates a generator that can be used to iterate over each line
-        of a text object, starting at the caret offset.
-
-        Arguments:
-        - obj: an Accessible that has a text specialization
+        """Creates a generator that can be used to iterate document content."""
 
-        Returns an iterator that produces elements of the form:
-        [SayAllContext, acss], where SayAllContext has the text to be
-        spoken and acss is an ACSS instance for speaking the text.
-        """
+        if not self.utilities.inDocumentContent():
+            super().textLines(obj, offset)
+            return
 
         self._sayAllIsInterrupted = False
 
         sayAllStyle = _settingsManager.getSetting('sayAllStyle')
         sayAllBySentence = sayAllStyle == settings.SAYALL_STYLE_SENTENCE
         if offset == None:
-            contextObj, contextOffset = self.getCaretContext()
-            if contextObj:
-                [obj, characterOffset] = contextObj, contextOffset
-            else:
-                characterOffset = 0
+            obj, characterOffset = self.utilities.getCaretContext()
         else:
             characterOffset = offset
 
@@ -735,15 +718,11 @@ class Script(default.Script):
             if sayAllBySentence:
                 contents = self.utilities.getSentenceContentsAtOffset(obj, characterOffset)
             else:
-                contents = self.getLineContentsAtOffset(obj, characterOffset)
+                contents = self.utilities.getLineContentsAtOffset(obj, characterOffset)
             self._sayAllContents = contents
             for content in contents:
                 obj, startOffset, endOffset, text = content
-                if self.utilities.isLabellingContents(content, contents) \
-                   or self.utilities.isInferredLabelForContents(content, contents):
-                    continue
-
-                utterances = self.getUtterancesFromContents([content], True)
+                utterances = self.speechGenerator.generateContents([content], eliminatePauses=True)
 
                 # TODO - JD: This is sad, but it's better than the old, broken
                 # clumpUtterances(). We really need to fix the speechservers'
@@ -760,9 +739,11 @@ class Script(default.Script):
                     self._sayAllContexts.append(context)
                     yield [context, voices[i]]
 
-            obj = contents[-1][0]
-            characterOffset = contents[-1][2]
-            [obj, characterOffset] = self.findNextCaretInOrder(obj, characterOffset)
+            lastObj, lastOffset = contents[-1][0], contents[-1][2]
+            obj, characterOffset = self.utilities.findNextCaretInOrder(lastObj, lastOffset - 1)
+            if (obj, characterOffset) == (lastObj, lastOffset):
+                obj, characterOffset = self.utilities.findNextCaretInOrder(lastObj, lastOffset)
+
             done = (obj == None)
 
         self._inSayAll = False
@@ -770,57 +751,33 @@ class Script(default.Script):
         self._sayAllContexts = []
 
     def presentFindResults(self, obj, offset):
-        """Updates the caret context to the match indicated by obj and
-        offset.  Then presents the results according to the user's
-        preferences.
-
-        Arguments:
-        -obj: The accessible object within the document
-        -offset: The offset with obj where the caret should be positioned
-        """
+        """Updates the context and presents the find results if appropriate."""
 
-        # At some point in Firefox 3.2 we started getting detail1 values of
-        # -1 for the caret-moved events for unfocused content during a find.
-        # We don't want to base the new caret offset -- or the current line
-        # on this value. We should be able to count on the selection range
-        # instead -- across FF 3.0, 3.1, and 3.2.
-        #
-        enoughSelected = False
         text = self.utilities.queryNonEmptyText(obj)
-        if text and text.getNSelections():
-            [start, end] = text.getSelection(0)
-            offset = max(offset, start)
-            if end - start >= _settingsManager.getSetting('findResultsMinimumLength'):
-                enoughSelected = True
-
-        # Haing done that, update the caretContext. If the user wants
-        # matches spoken, we also need to if we are on the same line
-        # as before.
-        #
-        origObj, origOffset = self.getCaretContext()
-        self.setCaretContext(obj, offset)
+        if not (text and text.getNSelections()):
+            return
+
+        context = self.utilities.getCaretContext(documentFrame=None)
+
+        start, end = text.getSelection(0)
+        offset = max(offset, start)
+        self.utilities.setCaretContext(obj, offset, documentFrame=None)
+        if end - start < _settingsManager.getSetting('findResultsMinimumLength'):
+            return
+
         verbosity = _settingsManager.getSetting('findResultsVerbosity')
-        if enoughSelected and verbosity != settings.FIND_SPEAK_NONE:
-            origExtents = self.utilities.getExtents(origObj, origOffset - 1, origOffset)
-            newExtents = self.utilities.getExtents(obj, offset - 1, offset)
-            lineChanged = not self.utilities.extentsAreOnSameLine(origExtents, newExtents)
-
-            # If the user starts backspacing over the text in the
-            # toolbar entry, he/she is indicating they want to perform
-            # a different search. Because madeFindAnnounement may
-            # be set to True, we should reset it -- but only if we
-            # detect the line has also changed.  We're not getting
-            # events from the Find entry, so we have to compare
-            # offsets.
-            #
-            if self.utilities.isSameObject(origObj, obj) \
-               and (origOffset > offset) and lineChanged:
-                self.madeFindAnnouncement = False
+        if verbosity == settings.FIND_SPEAK_NONE:
+            return
+
+        if self._madeFindAnnouncement \
+           and verbosity == settings.FIND_SPEAK_IF_LINE_CHANGED \
+           and not self.utilities.contextsAreOnSameLine(context, (obj, offset)):
+            return
 
-            if lineChanged or not self.madeFindAnnouncement or \
-               verbosity != settings.FIND_SPEAK_IF_LINE_CHANGED:
-                self.presentLine(obj, offset)
-                self.madeFindAnnouncement = True
+        contents = self.utilities.getLineContentsAtOffset(obj, offset)
+        self.speakContents(contents)
+        self.updateBraille(obj)
+        self._madeFindAnnouncement = True
 
     def sayAll(self, inputEvent, obj=None, offset=None):
         """Speaks the contents of the document beginning with the present
@@ -828,7 +785,7 @@ class Script(default.Script):
         been started on an object without text (such as an image).
         """
 
-        if not self.inDocumentContent():
+        if not self.utilities.inDocumentContent():
             return default.Script.sayAll(self, inputEvent, obj, offset)
 
         else:
@@ -839,7 +796,7 @@ class Script(default.Script):
         return True
 
     def _rewindSayAll(self, context, minCharCount=10):
-        if not self.inDocumentContent():
+        if not self.utilities.inDocumentContent():
             return default.Script._rewindSayAll(self, context, minCharCount)
 
         if not _settingsManager.getSetting('rewindAndFastForwardInSayAll'):
@@ -847,14 +804,14 @@ class Script(default.Script):
 
         obj, start, end, string = self._sayAllContents[0]
         orca.setLocusOfFocus(None, obj, notifyScript=False)
-        self.setCaretContext(obj, start)
+        self.utilities.setCaretContext(obj, start)
 
-        prevObj, prevOffset = self.findPreviousCaretInOrder(obj, start)
+        prevObj, prevOffset = self.utilities.findPreviousCaretInOrder(obj, start)
         self.sayAll(None, prevObj, prevOffset)
         return True
 
     def _fastForwardSayAll(self, context):
-        if not self.inDocumentContent():
+        if not self.utilities.inDocumentContent():
             return default.Script._fastForwardSayAll(self, context)
 
         if not _settingsManager.getSetting('rewindAndFastForwardInSayAll'):
@@ -862,14 +819,14 @@ class Script(default.Script):
 
         obj, start, end, string = self._sayAllContents[-1]
         orca.setLocusOfFocus(None, obj, notifyScript=False)
-        self.setCaretContext(obj, end)
+        self.utilities.setCaretContext(obj, end)
 
-        nextObj, nextOffset = self.findNextCaretInOrder(obj, end)
+        nextObj, nextOffset = self.utilities.findNextCaretInOrder(obj, end)
         self.sayAll(None, nextObj, nextOffset)
         return True
 
     def __sayAllProgressCallback(self, context, progressType):
-        if not self.inDocumentContent() or self._inFocusMode:
+        if not self.utilities.inDocumentContent() or self._inFocusMode:
             default.Script.__sayAllProgressCallback(self, context, progressType)
             return
 
@@ -882,7 +839,7 @@ class Script(default.Script):
                 elif lastKey == "Up" and self._rewindSayAll(context):
                     return
                 elif not self._lastCommandWasStructNav:
-                    self.setCaretPosition(context.obj, context.currentOffset)
+                    self.utilities.setCaretPosition(context.obj, context.currentOffset)
                     self.updateBraille(context.obj)
 
             self._inSayAll = False
@@ -891,7 +848,7 @@ class Script(default.Script):
             return
 
         orca.setLocusOfFocus(None, context.obj, notifyScript=False)
-        self.setCaretContext(context.obj, context.currentOffset)
+        self.utilities.setCaretContext(context.obj, context.currentOffset)
 
     def _getCtrlShiftSelectionsStrings(self):
         return [messages.LINE_SELECTED_DOWN,
@@ -917,22 +874,22 @@ class Script(default.Script):
     def onBusyChanged(self, event):
         """Callback for object:state-changed:busy accessibility events."""
 
-        if not self.inDocumentContent(event.source):
+        if not self.utilities.inDocumentContent(event.source):
             msg = "INFO: Event source is not in document content"
             debug.println(debug.LEVEL_INFO, msg)
             super().onBusyChanged(event)
             return False
 
-        if not self.inDocumentContent(orca_state.locusOfFocus):
+        if not self.utilities.inDocumentContent(orca_state.locusOfFocus):
             msg = "INFO: Ignoring: Locus of focus is not in document content"
             debug.println(debug.LEVEL_INFO, msg)
             return True
 
         self._loadingDocumentContent = event.detail1
 
-        obj, offset = self.getCaretContext()
+        obj, offset = self.utilities.getCaretContext()
         if not obj or self.utilities.isZombie(obj):
-            self.clearCaretContext()
+            self.utilities.clearCaretContext()
 
         if not _settingsManager.getSetting('onlySpeakDisplayedText'):
             if event.detail1:
@@ -949,7 +906,7 @@ class Script(default.Script):
         if self.useFocusMode(orca_state.locusOfFocus) != self._inFocusMode:
             self.togglePresentationMode(None)
 
-        obj, offset = self.getCaretContext()
+        obj, offset = self.utilities.getCaretContext()
         if not obj:
             msg = "INFO: Could not get caret context"
             debug.println(debug.LEVEL_INFO, msg)
@@ -1001,7 +958,7 @@ class Script(default.Script):
             debug.println(debug.LEVEL_INFO, msg)
             return True
 
-        if not self.inDocumentContent(event.source):
+        if not self.utilities.inDocumentContent(event.source):
             msg = "INFO: Event source is not in document content"
             debug.println(debug.LEVEL_INFO, msg)
             super().onCaretMoved(event)
@@ -1021,10 +978,10 @@ class Script(default.Script):
             msg = "INFO: Event handled: Last command was mouse button"
             debug.println(debug.LEVEL_INFO, msg)
             orca.setLocusOfFocus(event, event.source)
-            self.setCaretContext(event.source, event.detail1)
+            self.utilities.setCaretContext(event.source, event.detail1)
             return True
 
-        if self.utilities.inFindToolbar() and not self.madeFindAnnouncement:
+        if self.utilities.inFindToolbar() and not self._madeFindAnnouncement:
             msg = "INFO: Event handled: Presenting find results"
             debug.println(debug.LEVEL_INFO, msg)
             self.presentFindResults(event.source, event.detail1)
@@ -1046,13 +1003,13 @@ class Script(default.Script):
             self._saveLastCursorPosition(event.source, event.detail1)
             return True
 
-        obj, offset = self.findFirstCaretContext(event.source, event.detail1)
+        obj, offset = self.utilities.findFirstCaretContext(event.source, event.detail1)
 
         if self.utilities.caretMovedToSamePageFragment(event):
             msg = "INFO: Event handled: Caret moved to fragment"
             debug.println(debug.LEVEL_INFO, msg)
             orca.setLocusOfFocus(event, obj)
-            self.setCaretContext(obj, offset)
+            self.utilities.setCaretContext(obj, offset)
             return True
 
         text = self.utilities.queryNonEmptyText(event.source)
@@ -1061,7 +1018,7 @@ class Script(default.Script):
                 msg = "INFO: Event handled: Was for non-text link"
                 debug.println(debug.LEVEL_INFO, msg)
                 orca.setLocusOfFocus(event, event.source)
-                self.setCaretContext(event.source, event.detail1)
+                self.utilities.setCaretContext(event.source, event.detail1)
             else:
                 msg = "INFO: Event ignored: Was for non-text non-link"
                 debug.println(debug.LEVEL_INFO, msg)
@@ -1083,20 +1040,20 @@ class Script(default.Script):
             msg = "INFO: Setting locusOfFocus, context to: %s, %i" % (obj, offset)
             debug.println(debug.LEVEL_INFO, msg)
             orca.setLocusOfFocus(event, obj)
-            self.setCaretContext(obj, offset)
+            self.utilities.setCaretContext(obj, offset)
             return True
 
         if not _settingsManager.getSetting('caretNavigationEnabled') \
            or self._inFocusMode or isEditable:
             orca.setLocusOfFocus(event, event.source, False)
-            self.setCaretContext(event.source, event.detail1)
+            self.utilities.setCaretContext(event.source, event.detail1)
             msg = "INFO: Setting locusOfFocus, context to: %s, %i" % \
                   (event.source, event.detail1)
             debug.println(debug.LEVEL_INFO, msg)
             super().onCaretMoved(event)
             return False
 
-        self.setCaretContext(obj, offset)
+        self.utilities.setCaretContext(obj, offset)
         msg = "INFO: Setting context to: %s, %i" % (obj, offset)
         debug.println(debug.LEVEL_INFO, msg)
         super().onCaretMoved(event)
@@ -1105,13 +1062,13 @@ class Script(default.Script):
     def onCheckedChanged(self, event):
         """Callback for object:state-changed:checked accessibility events."""
 
-        if not self.inDocumentContent(event.source):
+        if not self.utilities.inDocumentContent(event.source):
             msg = "INFO: Event source is not in document content"
             debug.println(debug.LEVEL_INFO, msg)
             super().onCheckedChanged(event)
             return False
 
-        obj, offset = self.getCaretContext()
+        obj, offset = self.utilities.getCaretContext()
         if obj != event.source:
             msg = "INFO: Event source is not context object"
             debug.println(debug.LEVEL_INFO, msg)
@@ -1138,7 +1095,7 @@ class Script(default.Script):
     def onChildrenChanged(self, event):
         """Callback for object:children-changed accessibility events."""
 
-        if self.handleAsLiveRegion(event):
+        if self.utilities.handleAsLiveRegion(event):
             msg = "INFO: Event to be handled as live region"
             debug.println(debug.LEVEL_INFO, msg)
             self.liveMngr.handleEvent(event)
@@ -1154,13 +1111,13 @@ class Script(default.Script):
             debug.println(debug.LEVEL_INFO, msg)
             return True
 
-        if not self.inDocumentContent(event.source):
+        if not self.utilities.inDocumentContent(event.source):
             msg = "INFO: Event source is not in document content"
             debug.println(debug.LEVEL_INFO, msg)
             super().onChildrenChanged(event)
             return False
 
-        obj, offset = self.getCaretContext()
+        obj, offset = self.utilities.getCaretContext()
         if obj and self.utilities.isZombie(obj):
             replicant = self.utilities.findReplicant(event.source, obj)
             if replicant:
@@ -1170,7 +1127,7 @@ class Script(default.Script):
                 msg = "INFO: Event handled by updating locusOfFocus and context"
                 debug.println(debug.LEVEL_INFO, msg)
                 orca.setLocusOfFocus(event, replicant, False)
-                self.setCaretContext(replicant, offset)
+                self.utilities.setCaretContext(replicant, offset)
                 return True
 
         child = event.any_data
@@ -1186,7 +1143,7 @@ class Script(default.Script):
             utterances.extend(self.speechGenerator.generateSpeech(child, force=True))
             speech.speak(utterances)
             self.lastMouseOverObject = child
-            self.preMouseOverContext = self.getCaretContext()
+            self.preMouseOverContext = self.utilities.getCaretContext()
             return True
 
         super().onChildrenChanged(event)
@@ -1221,7 +1178,7 @@ class Script(default.Script):
         """Callback for focus: accessibility events."""
 
         # We should get proper state-changed events for these.
-        if self.inDocumentContent(event.source):
+        if self.utilities.inDocumentContent(event.source):
             return
 
         # NOTE: This event type is deprecated and Orca should no longer use it.
@@ -1264,7 +1221,7 @@ class Script(default.Script):
             debug.println(debug.LEVEL_INFO, msg)
             return True
 
-        if not self.inDocumentContent(event.source):
+        if not self.utilities.inDocumentContent(event.source):
             msg = "INFO: Event source is not in document content"
             debug.println(debug.LEVEL_INFO, msg)
             super().onFocusedChanged(event)
@@ -1295,12 +1252,12 @@ class Script(default.Script):
             return True
 
         if role in [pyatspi.ROLE_DOCUMENT_FRAME, pyatspi.ROLE_DOCUMENT_WEB]:
-            obj, offset = self.getCaretContext(event.source)
+            obj, offset = self.utilities.getCaretContext(event.source)
             if obj and self.utilities.isZombie(obj):
                 msg = "INFO: Clearing context - obj is zombie"
                 debug.println(debug.LEVEL_INFO, msg)
-                self.clearCaretContext()
-                obj, offset = self.getCaretContext(event.source)
+                self.utilities.clearCaretContext()
+                obj, offset = self.utilities.getCaretContext(event.source)
 
             if obj:
                 wasFocused = obj.getState().contains(pyatspi.STATE_FOCUSED)
@@ -1343,7 +1300,7 @@ class Script(default.Script):
     def onShowingChanged(self, event):
         """Callback for object:state-changed:showing accessibility events."""
 
-        if not self.inDocumentContent(event.source):
+        if not self.utilities.inDocumentContent(event.source):
             msg = "INFO: Event source is not in document content"
             debug.println(debug.LEVEL_INFO, msg)
             super().onShowingChanged(event)
@@ -1354,7 +1311,7 @@ class Script(default.Script):
     def onTextDeleted(self, event):
         """Callback for object:text-changed:delete accessibility events."""
 
-        if not self.inDocumentContent(event.source):
+        if not self.utilities.inDocumentContent(event.source):
             msg = "INFO: Event source is not in document content"
             debug.println(debug.LEVEL_INFO, msg)
             super().onTextDeleted(event)
@@ -1372,8 +1329,7 @@ class Script(default.Script):
 
         msg = "INFO: Clearing content cache due to text deletion"
         debug.println(debug.LEVEL_INFO, msg)
-        # self.utilities.clearContentCache()
-        self._destroyLineCache()
+        self.utilities.clearContentCache()
 
         state = event.source.getState()
         if not state.contains(pyatspi.STATE_EDITABLE):
@@ -1393,7 +1349,7 @@ class Script(default.Script):
     def onTextInserted(self, event):
         """Callback for object:text-changed:insert accessibility events."""
 
-        if not self.inDocumentContent(event.source):
+        if not self.utilities.inDocumentContent(event.source):
             msg = "INFO: Event source is not in document content"
             debug.println(debug.LEVEL_INFO, msg)
             super().onTextInserted(event)
@@ -1406,10 +1362,9 @@ class Script(default.Script):
 
         msg = "INFO: Clearing content cache due to text insertion"
         debug.println(debug.LEVEL_INFO, msg)
-        # self.utilities.clearContentCache()
-        self._destroyLineCache()
+        self.utilities.clearContentCache()
 
-        if self.handleAsLiveRegion(event):
+        if self.utilities.handleAsLiveRegion(event):
             msg = "INFO: Event to be handled as live region"
             debug.println(debug.LEVEL_INFO, msg)
             self.liveMngr.handleEvent(event)
@@ -1444,7 +1399,7 @@ class Script(default.Script):
             debug.println(debug.LEVEL_INFO, msg)
             return True
 
-        if not self.inDocumentContent(event.source):
+        if not self.utilities.inDocumentContent(event.source):
             msg = "INFO: Event source is not in document content"
             debug.println(debug.LEVEL_INFO, msg)
             super().onTextSelectionChanged(event)
@@ -1457,7 +1412,7 @@ class Script(default.Script):
             self._saveFocusedObjectInfo(orca_state.locusOfFocus)
             return True
 
-        if not self.inDocumentContent(orca_state.locusOfFocus):
+        if not self.utilities.inDocumentContent(orca_state.locusOfFocus):
             msg = "INFO: Ignoring: Event in document content; focus is not"
             debug.println(debug.LEVEL_INFO, msg)
             return True
@@ -1484,7 +1439,7 @@ class Script(default.Script):
             debug.println(debug.LEVEL_INFO, msg)
             return True
 
-        obj, offset = self.getCaretContext()
+        obj, offset = self.utilities.getCaretContext()
         if obj and obj.parent and event.source in [obj.parent, obj.parent.parent]:
             msg = "INFO: Ignoring: Source is context ancestor"
             debug.println(debug.LEVEL_INFO, msg)
@@ -1511,15 +1466,27 @@ class Script(default.Script):
         if not self.utilities.hasMatchingHierarchy(event.source, rolesList):
             default.Script.handleProgressBarUpdate(self, event, obj)
 
+    def inFocusMode(self):
+        """ Returns True if we're in focus mode."""
+
+        return self._inFocusMode
+
+    def focusModeIsSticky(self):
+        """Returns True if we're in 'sticky' focus mode."""
+
+        return self._focusModeIsSticky
+
     def useFocusMode(self, obj):
+        """Returns True if we should use focus mode in obj."""
+
         if self._focusModeIsSticky:
             return True
 
-        if not orca.settings.structNavTriggersFocusMode \
+        if not _settingsManager.getSetting('structNavTriggersFocusMode') \
            and self._lastCommandWasStructNav:
             return False
 
-        if not orca.settings.caretNavTriggersFocusMode \
+        if not _settingsManager.getSetting('caretNavTriggersFocusMode') \
            and self._lastCommandWasCaretNav:
             return False
 
@@ -1533,7 +1500,7 @@ class Script(default.Script):
             debug.println(debug.LEVEL_INFO, msg)
             return True
 
-        if not self.inDocumentContent(newFocus):
+        if not self.utilities.inDocumentContent(newFocus):
             msg = "INFO: Locus of focus changed to non-document obj"
             self._madeFindAnnouncement = False
             self._inFocusMode = False
@@ -1546,13 +1513,13 @@ class Script(default.Script):
 
         caretOffset = 0
         if self.utilities.inFindToolbar(oldFocus):
-            newFocus, caretOffset = self.getCaretContext()
+            newFocus, caretOffset = self.utilities.getCaretContext()
 
         text = self.utilities.queryNonEmptyText(newFocus)
         if text and (0 <= text.caretOffset < text.characterCount):
             caretOffset = text.caretOffset
 
-        self.setCaretContext(newFocus, caretOffset)
+        self.utilities.setCaretContext(newFocus, caretOffset)
         self.updateBraille(newFocus)
         speech.speak(self.speechGenerator.generateSpeech(newFocus, priorObj=oldFocus))
         self._saveFocusedObjectInfo(newFocus)
@@ -1563,12 +1530,6 @@ class Script(default.Script):
 
         return True
 
-    def _destroyLineCache(self):
-        """Removes all of the stored lines."""
-
-        self.currentLineContents = []
-        self.currentAttrs = {}
-
     def presentLine(self, obj, offset):
         """Presents the current line in speech and in braille.
 
@@ -1577,138 +1538,133 @@ class Script(default.Script):
         - offset: the offset within obj
         """
 
-        contents = self.getLineContentsAtOffset(obj, offset)
+        contents = self.utilities.getLineContentsAtOffset(obj, offset)
         if not isinstance(orca_state.lastInputEvent, input_event.BrailleEvent):
-            self.speakContents(self.currentLineContents)
+            self.speakContents(self.utilities.getLineContentsAtOffset(obj, offset))
         self.updateBraille(obj)
 
     def updateBraille(self, obj, extraRegion=None):
-        """Updates the braille display to show the given object.
-
-        Arguments:
-        - obj: the Accessible
-        - extra: extra Region to add to the end
-        """
+        """Updates the braille display to show the given object."""
 
         if not _settingsManager.getSetting('enableBraille') \
            and not _settingsManager.getSetting('enableBrailleMonitor'):
-            debug.println(debug.LEVEL_INFO, "BRAILLE: update disabled")
+            debug.println(debug.LEVEL_INFO, "BRAILLE: disabled")
             return
 
-        if not self.inDocumentContent() or self._inFocusMode:
-            default.Script.updateBraille(self, obj, extraRegion)
+        if not (self._lastCommandWasCaretNav or self._lastCommandWasStructNav) \
+           or self._inFocusMode or not self.utilities.inDocumentContent():
+            super().updateBraille(obj, extraRegion)
             return
 
-        if not obj:
+        # TODO - JD: This should be removed once struct nav uses the new
+        # method to display contents.
+        if self._lastCommandWasStructNav \
+           and not (self.utilities.isLink(obj) or self.utilities.isTextBlockElement(obj)):
+            super().updateBraille(obj, extraRegion)
             return
 
-        line = self.getNewBrailleLine(clearBraille=True, addLine=True)
+        obj, offset = self.utilities.getCaretContext(documentFrame=None)
+        contents = self.utilities.getLineContentsAtOffset(obj, offset)
+        self.displayContents(contents)
+
+    def displayContents(self, contents):
+        """Displays contents in braille."""
 
-        [focusedObj, focusedOffset] = self.getCaretContext()
-        contents = self.getLineContentsAtOffset(focusedObj, focusedOffset)
-        contents = self.utilities.filterContentsForPresentation(contents)
-        index = self.utilities.findObjectInContents(focusedObj, focusedOffset, contents)
-        if not len(contents) or \
-           (index == -1 and not self.utilities.isTextBlockElement(focusedObj)):
-            default.Script.updateBraille(self, obj, extraRegion)
+        if not _settingsManager.getSetting('enableBraille') \
+           and not _settingsManager.getSetting('enableBrailleMonitor'):
+            debug.println(debug.LEVEL_INFO, "BRAILLE: disabled")
             return
 
-        focusedRegion = None
-        lastObj = None
-        for i, content in enumerate(contents):
-            [obj, startOffset, endOffset, string] = content
-            [regions, fRegion] = self.brailleGenerator.generateBraille(
-                obj, startOffset=startOffset, endOffset=endOffset, string=string)
-            if i == index:
-                focusedRegion = fRegion
-
-            if line.regions and regions:
-                if line.regions[-1].string:
-                    lastChar = line.regions[-1].string[-1]
-                else:
-                    lastChar = ""
-                if regions[0].string:
-                    nextChar = regions[0].string[0]
-                else:
-                    nextChar = ""
-                if self.utilities.needsSeparator(lastChar, nextChar):
-                    self.addToLineAsBrailleRegion(" ", line)
-
-            self.addBrailleRegionsToLine(regions, line)
-            lastObj = obj
+        line = self.getNewBrailleLine(clearBraille=True, addLine=True)
+        regions, focusedRegion = self.brailleGenerator.generateContents(contents)
+        for region in regions:
+            self.addBrailleRegionsToLine(region, line)
 
         if line.regions:
             line.regions[-1].string = line.regions[-1].string.rstrip(" ")
 
-        # TODO - JD: This belongs in the generator.
-        if lastObj and lastObj.getRole() != pyatspi.ROLE_HEADING:
-            heading = self.utilities.ancestorWithRole(
-                lastObj, [pyatspi.ROLE_HEADING], [pyatspi.ROLE_DOCUMENT_FRAME])
-            if heading:
-                level = self.utilities.headingLevel(heading)
-                string = " %s" % object_properties.ROLE_HEADING_LEVEL_BRAILLE % level
-                self.addToLineAsBrailleRegion(string, line)
-
-        if extraRegion:
-            self.addBrailleRegionToLine(extraRegion, line)
-
         self.setBrailleFocus(focusedRegion, getLinkMask=False)
         self.refreshBraille(panToCursor=True, getLinkMask=False)
 
+    def speakContents(self, contents):
+        """Speaks the specified contents."""
+
+        utterances = self.speechGenerator.generateContents(contents)
+        speech.speak(utterances)
+
+    def speakCharacterAtOffset(self, obj, characterOffset):
+        """Speaks the character at the given characterOffset in the
+        given object."""
+        character = self.utilities.getCharacterAtOffset(obj, characterOffset)
+        self.speakMisspelledIndicator(obj, characterOffset)
+        if obj:
+            if character and character != self.EMBEDDED_OBJECT_CHARACTER:
+                self.speakCharacter(character)
+            elif not obj.getState().contains(pyatspi.STATE_EDITABLE):
+                # We won't have a character if we move to the end of an
+                # entry (in which case we're not on a character and therefore
+                # have nothing to say), or when we hit a component with no
+                # text (e.g. checkboxes) or reset the caret to the parent's
+                # characterOffset (lists).  In these latter cases, we'll just
+                # speak the entire component.
+                #
+                utterances = self.speechGenerator.generateSpeech(obj)
+                speech.speak(utterances)
+
     def sayCharacter(self, obj):
         """Speaks the character at the current caret position."""
 
-        # We need to handle HTML content differently because of the
-        # EMBEDDED_OBJECT_CHARACTER model of Gecko.  For all other
-        # things, however, we can defer to the default scripts.
-        #
+        if not self._lastCommandWasCaretNav:
+            super().sayCharacter(obj)
+            return
 
-        if not self.inDocumentContent() or obj.getState().contains(pyatspi.STATE_EDITABLE):
-            default.Script.sayCharacter(self, obj)
+        obj, offset = self.utilities.getCaretContext(documentFrame=None)
+        if not obj:
             return
 
-        [obj, characterOffset] = self.getCaretContext()
-        if characterOffset >= 0:
-            self.speakCharacterAtOffset(obj, characterOffset)
+        contents = self.utilities.getCharacterContentsAtOffset(obj, offset)
+        if not contents:
+            return
+
+        obj, start, end, string = contents[0]
+        if start > 0:
+            string = string or "\n"
+
+        if string:
+            self.speakMisspelledIndicator(obj, start)
+            self.speakCharacter(string)
+        else:
+            self.speakContents(contents)
 
     def sayWord(self, obj):
         """Speaks the word at the current caret position."""
 
-        # We need to handle HTML content differently because of the
-        # EMBEDDED_OBJECT_CHARACTER model of Gecko.  For all other
-        # things, however, we can defer to the default scripts.
-        #
-        if not self.inDocumentContent() or obj.getState().contains(pyatspi.STATE_EDITABLE):
-            default.Script.sayWord(self, obj)
+        if not self._lastCommandWasCaretNav:
+            super().sayWord(obj)
             return
 
-        [obj, characterOffset] = self.getCaretContext()
-        wordContents = self.utilities.getWordContentsAtOffset(obj, characterOffset)
-
-        [textObj, startOffset, endOffset, word] = wordContents[0]
+        obj, offset = self.utilities.getCaretContext(documentFrame=None)
+        wordContents = self.utilities.getWordContentsAtOffset(obj, offset)
+        textObj, startOffset, endOffset, word = wordContents[0]
         self.speakMisspelledIndicator(textObj, startOffset)
         self.speakContents(wordContents)
 
     def sayLine(self, obj):
         """Speaks the line at the current caret position."""
 
-        # We need to handle HTML content differently because of the
-        # EMBEDDED_OBJECT_CHARACTER model of Gecko.  For all other
-        # things, however, we can defer to the default scripts.
-        #
-        if not self.inDocumentContent() or obj.getState().contains(pyatspi.STATE_EDITABLE):
-            default.Script.sayLine(self, obj)
+        if not self._lastCommandWasCaretNav:
+            super().sayLine(obj)
             return
 
-        [obj, characterOffset] = self.getCaretContext()
-        self.speakContents(self.getLineContentsAtOffset(obj, characterOffset))
+        obj, offset = self.utilities.getCaretContext(documentFrame=None)
+        self.speakContents(self.utilities.getLineContentsAtOffset(obj, offset))
 
     def panBrailleLeft(self, inputEvent=None, panAmount=0):
         """In document content, we want to use the panning keys to browse the
         entire document.
         """
         if self.flatReviewContext \
-           or not self.inDocumentContent() \
+           or not self.utilities.inDocumentContent() \
            or not self.isBrailleBeginningShowing():
             default.Script.panBrailleLeft(self, inputEvent, panAmount)
         else:
@@ -1723,7 +1679,7 @@ class Script(default.Script):
         entire document.
         """
         if self.flatReviewContext \
-           or not self.inDocumentContent() \
+           or not self.utilities.inDocumentContent() \
            or not self.isBrailleEndShowing():
             default.Script.panBrailleRight(self, inputEvent, panAmount)
         elif self.goNextLine(inputEvent):
@@ -1732,45 +1688,6 @@ class Script(default.Script):
             self.refreshBraille(False)
         return True
 
-    ####################################################################
-    #                                                                  #
-    # Utility Methods                                                  #
-    #                                                                  #
-    ####################################################################
-
-    def inDocumentContent(self, obj=None):
-        """Returns True if the given object (defaults to the current
-        locus of focus is in the document content).
-        """
-
-        if not obj:
-            obj = orca_state.locusOfFocus
-        try:
-            return self.generatorCache['inDocumentContent'][obj]
-        except:
-            pass
-
-        result = False
-        while obj:
-            try:
-                role = obj.getRole()
-            except:
-                return False
-            if role == pyatspi.ROLE_DOCUMENT_FRAME \
-                    or role == pyatspi.ROLE_EMBEDDED:
-                result = True
-                break
-            else:
-                obj = obj.parent
-
-        if 'inDocumentContent' not in self.generatorCache:
-            self.generatorCache['inDocumentContent'] = {}
-
-        if obj:
-            self.generatorCache['inDocumentContent'][obj] = result
-            
-        return result
-
     def useCaretNavigationModel(self, keyboardEvent):
         """Returns True if we should do our own caret navigation.
         """
@@ -1779,7 +1696,7 @@ class Script(default.Script):
            or self._inFocusMode:
             return False
 
-        if not self.inDocumentContent():
+        if not self.utilities.inDocumentContent():
             return False
 
         if keyboardEvent.event_string in ["Page_Up", "Page_Down"]:
@@ -1802,555 +1719,21 @@ class Script(default.Script):
         if not self.structuralNavigation.enabled or self._inFocusMode:
             return False
 
-        if not self.inDocumentContent():
+        if not self.utilities.inDocumentContent():
             return False
 
         return True
-
-    def _getAttrDictionary(self, obj):
-        if not obj:
-            return {}
-
-        try:
-            return dict([attr.split(':', 1) for attr in obj.getAttributes()])
-        except:
-            return {}
-
-    def handleAsLiveRegion(self, event):
-        """Returns True if the given event (object:children-changed, object:
-        text-insert only) should be considered a live region event"""
-
-        if self._loadingDocumentContent \
-           or not _settingsManager.getSetting('inferLiveRegions'):
-            return False
-
-        attrs = self._getAttrDictionary(event.source)
-        if 'container-live' in attrs:
-            return True
-
-        return False
-
-    def getChildIndex(self, obj, characterOffset):
-        """Given an object that implements accessible text, determine
-        the index of the child that is represented by an
-        EMBEDDED_OBJECT_CHARACTER at characterOffset in the object's
-        accessible text."""
-
-        try:
-            hypertext = obj.queryHypertext()
-        except NotImplementedError:
-            index = -1
-        else:
-            index = hypertext.getLinkIndex(characterOffset)
-
-        return index
  
-    def getTopOfFile(self):
-        """Returns the object and first caret offset at the top of the
-         document frame."""
-
-        documentFrame = self.utilities.documentFrame()
-        [obj, offset] = self.findFirstCaretContext(documentFrame, 0)
-
-        return [obj, offset]
-
-    def getBottomOfFile(self):
-        """Returns the object and last caret offset at the bottom of the
-         document frame."""
-
-        documentFrame = self.utilities.documentFrame()
-        text = self.utilities.queryNonEmptyText(documentFrame)
-        if text:
-            char = text.getText(text.characterCount - 1, text.characterCount)
-            if char != self.EMBEDDED_OBJECT_CHARACTER:
-                return [documentFrame, text.characterCount - 1]
-
-        obj = self.getLastObject(documentFrame)
-        offset = 0
-
-        # If the last object is a link, it may be more efficient to check
-        # for text that follows.
-        #
-        if obj and obj.getRole() == pyatspi.ROLE_LINK:
-            text = self.utilities.queryNonEmptyText(obj.parent)
-            if text:
-                char = text.getText(text.characterCount - 1,
-                                    text.characterCount)
-                if char != self.EMBEDDED_OBJECT_CHARACTER:
-                    return [obj.parent, text.characterCount - 1]
-
-        # obj should now be the very last item in the entire document frame
-        # and not have children of its own.  Therefore, it should have text.
-        # If it doesn't, we don't want to be here.
-        #
-        text = self.utilities.queryNonEmptyText(obj)
-        if text:
-            offset = text.characterCount - 1
-        else:
-            obj = self.findPreviousObject(obj, documentFrame)
-
-        while obj:
-            [lastObj, lastOffset] = self.findNextCaretInOrder(obj, offset)
-            if not lastObj \
-               or self.utilities.isSameObject(lastObj, obj) \
-               and (lastOffset == offset):
-                break
-
-            [obj, offset] = [lastObj, lastOffset]
-
-        return [obj, offset]
-
-    def getLastObject(self, documentFrame):
-        """Returns the last object in the document frame"""
-
-        try:
-            lastChild = documentFrame[documentFrame.childCount - 1]
-        except:
-            lastChild = documentFrame
-        while lastChild:
-            lastObj = self.findNextObject(lastChild, documentFrame)
-            if lastObj and lastObj != lastChild:
-                lastChild = lastObj
-            else:
-                break
-
-        return lastChild
-
-    def getPageSummary(self, obj):
-        """Returns the quantity of headings, forms, tables, visited links,
-        and unvisited links on the page containing obj.
-        """
-
-        docframe = self.utilities.documentFrame()
-        col = docframe.queryCollection()
-        headings = 0
-        forms = 0
-        tables = 0
-        vlinks = 0
-        uvlinks = 0
-        percentRead = None
-
-        stateset = pyatspi.StateSet()
-        roles = [pyatspi.ROLE_HEADING, pyatspi.ROLE_LINK, pyatspi.ROLE_TABLE,
-                 pyatspi.ROLE_FORM]
-        rule = col.createMatchRule(stateset.raw(), col.MATCH_NONE,
-                                   "", col.MATCH_NONE,
-                                   roles, col.MATCH_ANY,
-                                   "", col.MATCH_NONE,
-                                   False)
-
-        matches = col.getMatches(rule, col.SORT_ORDER_CANONICAL, 0, True)
-        col.freeMatchRule(rule)
-        for obj in matches:
-            role = obj.getRole()
-            if role == pyatspi.ROLE_HEADING:
-                headings += 1
-            elif role == pyatspi.ROLE_FORM:
-                forms += 1
-            elif role == pyatspi.ROLE_TABLE \
-                      and not self.utilities.isLayoutOnly(obj):
-                tables += 1
-            elif role == pyatspi.ROLE_LINK:
-                if obj.getState().contains(pyatspi.STATE_VISITED):
-                    vlinks += 1
-                else:
-                    uvlinks += 1
-
-        return [headings, forms, tables, vlinks, uvlinks, percentRead]
-
-    ####################################################################
-    #                                                                  #
-    # Methods to find previous and next objects.                       #
-    #                                                                  #
-    ####################################################################
-
-    def findFirstCaretContext(self, obj, characterOffset):
-        """Given an object and a character offset, find the first
-        [obj, characterOffset] that is actually presenting something
-        on the display.  The reason we do this is that the
-        [obj, characterOffset] passed in may actually be pointing
-        to an embedded object character.  In those cases, we dig
-        into the hierarchy to find the 'real' thing.
-
-        Arguments:
-        -obj: an accessible object
-        -characterOffset: the offset of the character where to start
-        looking for real text
-
-        Returns [obj, characterOffset] that points to real content.
-        """
-
-        try:
-            role = obj.getRole()
-        except:
-            return [None, -1]
-
-        if role == pyatspi.ROLE_TABLE and obj.childCount:
-            child = obj[0]
-            if child.getRole() in [pyatspi.ROLE_CAPTION, pyatspi.ROLE_LIST]:
-                obj = child
-            else:
-                obj = obj.queryTable().getAccessibleAt(0, 0)
-            return self.findFirstCaretContext(obj, 0)
-
-        text = self.utilities.queryNonEmptyText(obj)
-        if not text:
-            return [obj, -1]
-
-        character = text.getText(characterOffset, characterOffset + 1)
-        if len(character) == 1 and character != self.EMBEDDED_OBJECT_CHARACTER:
-            return [obj, characterOffset]
-
-        try:
-            childIndex = self.getChildIndex(obj, characterOffset)
-            child = obj[childIndex]
-
-            # Handle bogus empty paragraphs. Bug 677615.
-            # Make that bogus empty text objects.
-            textRoles = [pyatspi.ROLE_HEADING,
-                         pyatspi.ROLE_PARAGRAPH,
-                         pyatspi.ROLE_SECTION]
-            if child.getRole() in textRoles \
-               and not self.utilities.queryNonEmptyText(child):
-                return self.findFirstCaretContext(obj, characterOffset + 1)
-
-            return self.findFirstCaretContext(child, 0)
-
-        except:
-            return [obj, -1]
-
-        return [obj, characterOffset]
-
-    def findNextCaretInOrder(self, obj=None,
-                             startOffset=-1,
-                             includeNonText=True):
-        """Given an object at a character offset, return the next
-        caret context following an in-order traversal rule.
-
-        Arguments:
-        - root: the Accessible to start at.  If None, starts at the
-        document frame.
-        - startOffset: character position in the object text field
-        (if it exists) to start at.  Defaults to -1, which means
-        start at the beginning - that is, the next character is the
-        first character in the object.
-        - includeNonText: If False, only land on objects that support the
-        accessible text interface; otherwise, include logical leaf
-        nodes like check boxes, combo boxes, etc.
-
-        Returns [obj, characterOffset] or [None, -1]
-        """
-
-        if not obj:
-            obj = self.utilities.documentFrame()
-
-        if not obj or not self.inDocumentContent(obj):
-            return [None, -1]
-
-        if obj.getRole() == pyatspi.ROLE_INVALID:
-            debug.println(debug.LEVEL_SEVERE, \
-                          "findNextCaretInOrder: object is invalid")
-            return [None, -1]
-
-        # We do not want to descend objects of certain role types.
-        #
-        doNotDescend = obj.getState().contains(pyatspi.STATE_FOCUSABLE) \
-                       and obj.getRole() in [pyatspi.ROLE_COMBO_BOX,
-                                             pyatspi.ROLE_LIST_BOX,
-                                             pyatspi.ROLE_LIST,
-                                             pyatspi.ROLE_PUSH_BUTTON,
-                                             pyatspi.ROLE_TABLE_CELL,
-                                             pyatspi.ROLE_TOGGLE_BUTTON,
-                                             pyatspi.ROLE_TOOL_BAR]
-
-        isHidden = self.utilities.isHidden(obj)
-        isOffScreenLabel = self.utilities.isOffScreenLabel(obj, startOffset)
-        skip = isHidden or isOffScreenLabel
-
-        text = self.utilities.queryNonEmptyText(obj)
-        if text and not skip:
-            unicodeText = self.utilities.unicodeText(obj)
-
-            # Delete the final space character if we find it.  Otherwise,
-            # we'll arrow to it.  (We can't just strip the string otherwise
-            # we skip over blank lines that one could otherwise arrow to.)
-            #
-            if len(unicodeText) > 1 and unicodeText[-1] == " ":
-                unicodeText = unicodeText[0:len(unicodeText) - 1]
-
-            nextOffset = startOffset + 1
-            while 0 <= nextOffset < len(unicodeText):
-                if unicodeText[nextOffset] != self.EMBEDDED_OBJECT_CHARACTER:
-                    return [obj, nextOffset]
-                elif obj.childCount:
-                    try:
-                        child = obj[self.getChildIndex(obj, nextOffset)]
-                    except:
-                        break
-                    if child:
-                        return self.findNextCaretInOrder(child,
-                                                         -1,
-                                                       includeNonText)
-                    else:
-                        nextOffset += 1
-                else:
-                    nextOffset += 1
-
-        # If this is a list or combo box in an HTML form, we don't want
-        # to place the caret inside the list, but rather treat the list
-        # as a single object.  Otherwise, if it has children, look there.
-        #
-        elif obj.childCount and obj[0] and not doNotDescend and not skip:
-            try:
-                return self.findNextCaretInOrder(obj[0],
-                                                 -1,
-                                                 includeNonText)
-            except:
-                pass
-
-        elif includeNonText and startOffset < 0 and not skip:
-            extents = obj.queryComponent().getExtents(0)
-            if (extents.width != 0) and (extents.height != 0):
-                return [obj, 0]
-
-        # If we're here, we need to start looking up the tree,
-        # going no higher than the document frame, of course.
-        #
-        documentFrame = self.utilities.documentFrame()
-        if self.utilities.isSameObject(obj, documentFrame):
-            return [None, -1]
-
-        while obj.parent and obj != obj.parent:
-            characterOffsetInParent = \
-                self.utilities.characterOffsetInParent(obj)
-            if characterOffsetInParent >= 0:
-                return self.findNextCaretInOrder(obj.parent,
-                                                 characterOffsetInParent,
-                                                 includeNonText)
-            else:
-                index = obj.getIndexInParent() + 1
-                if index < obj.parent.childCount:
-                    try:
-                        return self.findNextCaretInOrder(
-                            obj.parent[index],
-                            -1,
-                            includeNonText)
-                    except:
-                        pass
-            obj = obj.parent
-
-        return [None, -1]
-
-    def findPreviousCaretInOrder(self,
-                                 obj=None,
-                                 startOffset=-1,
-                                 includeNonText=True):
-        """Given an object an a character offset, return the previous
-        caret context following an in order traversal rule.
-
-        Arguments:
-        - root: the Accessible to start at.  If None, starts at the
-        document frame.
-        - startOffset: character position in the object text field
-        (if it exists) to start at.  Defaults to -1, which means
-        start at the end - that is, the previous character is the
-        last character of the object.
-
-        Returns [obj, characterOffset] or [None, -1]
-        """
-
-        if not obj:
-            obj = self.utilities.documentFrame()
-
-        if not obj or not self.inDocumentContent(obj):
-            return [None, -1]
-
-        if obj.getRole() == pyatspi.ROLE_INVALID:
-            debug.println(debug.LEVEL_SEVERE, \
-                          "findPreviousCaretInOrder: object is invalid")
-            return [None, -1]
-
-        # We do not want to descend objects of certain role types.
-        #
-        doNotDescend = obj.getState().contains(pyatspi.STATE_FOCUSABLE) \
-                       and obj.getRole() in [pyatspi.ROLE_COMBO_BOX,
-                                             pyatspi.ROLE_LIST_BOX,
-                                             pyatspi.ROLE_LIST,
-                                             pyatspi.ROLE_PUSH_BUTTON,
-                                             pyatspi.ROLE_TABLE_CELL,
-                                             pyatspi.ROLE_TOGGLE_BUTTON,
-                                             pyatspi.ROLE_TOOL_BAR]
-
-        isHidden = self.utilities.isHidden(obj)
-        isOffScreenLabel = self.utilities.isOffScreenLabel(obj, startOffset)
-        skip = isHidden or isOffScreenLabel
-
-        text = self.utilities.queryNonEmptyText(obj)
-        if text and not skip:
-            unicodeText = self.utilities.unicodeText(obj)
-
-            # Delete the final space character if we find it.  Otherwise,
-            # we'll arrow to it.  (We can't just strip the string otherwise
-            # we skip over blank lines that one could otherwise arrow to.)
-            #
-            if len(unicodeText) > 1 and unicodeText[-1] == " ":
-                unicodeText = unicodeText[0:len(unicodeText) - 1]
-
-            if (startOffset == -1) or (startOffset > len(unicodeText)):
-                startOffset = len(unicodeText)
-            previousOffset = startOffset - 1
-            while previousOffset >= 0:
-                if unicodeText[previousOffset] \
-                    != self.EMBEDDED_OBJECT_CHARACTER:
-                    return [obj, previousOffset]
-                elif obj.childCount:
-                    child = obj[self.getChildIndex(obj, previousOffset)]
-                    if child:
-                        return self.findPreviousCaretInOrder(child,
-                                                             -1,
-                                                             includeNonText)
-                    else:
-                        previousOffset -= 1
-                else:
-                    previousOffset -= 1
-
-        # If this is a list or combo box in an HTML form, we don't want
-        # to place the caret inside the list, but rather treat the list
-        # as a single object.  Otherwise, if it has children, look there.
-        #
-        elif obj.childCount and obj[obj.childCount - 1] and not doNotDescend \
-             and not skip:
-            try:
-                return self.findPreviousCaretInOrder(
-                    obj[obj.childCount - 1],
-                    -1,
-                    includeNonText)
-            except:
-                pass
-
-        elif includeNonText and startOffset < 0 and not skip:
-            extents = obj.queryComponent().getExtents(0)
-            if (extents.width != 0) and (extents.height != 0):
-                return [obj, 0]
-
-        # If we're here, we need to start looking up the tree,
-        # going no higher than the document frame, of course.
-        #
-        documentFrame = self.utilities.documentFrame()
-        if self.utilities.isSameObject(obj, documentFrame):
-            return [None, -1]
-
-        while obj.parent and obj != obj.parent:
-            characterOffsetInParent = \
-                self.utilities.characterOffsetInParent(obj)
-            if characterOffsetInParent >= 0:
-                return self.findPreviousCaretInOrder(obj.parent,
-                                                     characterOffsetInParent,
-                                                     includeNonText)
-            else:
-                index = obj.getIndexInParent() - 1
-                if index >= 0:
-                    try:
-                        return self.findPreviousCaretInOrder(
-                            obj.parent[index],
-                            -1,
-                            includeNonText)
-                    except:
-                        pass
-            obj = obj.parent
-
-        return [None, -1]
-
-    def findPreviousObject(self, obj, documentFrame):
-        if not obj:
-            return None
-
-        for relation in obj.getRelationSet():
-            if relation.getRelationType() == pyatspi.RELATION_FLOWS_FROM:
-                return relation.getTarget(0)
-
-        if obj == documentFrame:
-            obj, offset = self.getCaretContext()
-            for child in documentFrame:
-                if self.utilities.characterOffsetInParent(child) < offset:
-                    return child
-
-        index = obj.getIndexInParent() - 1
-        if not 0 <= index < obj.parent.childCount:
-            obj = obj.parent
-            index = obj.getIndexInParent() - 1
-
-        previousObj = obj.parent[index]
-        while previousObj and previousObj.childCount:
-            previousObj = previousObj[previousObj.childCount - 1]
-
-        return previousObj
-
-    def findNextObject(self, obj, documentFrame):
-        if not obj:
-            return None
-
-        for relation in obj.getRelationSet():
-            if relation.getRelationType() == pyatspi.RELATION_FLOWS_TO:
-                return relation.getTarget(0)
-
-        if obj == documentFrame:
-            obj, offset = self.getCaretContext()
-            for child in documentFrame:
-                if self.utilities.characterOffsetInParent(child) > offset:
-                    return child
-
-        if obj and obj.childCount:
-            return obj[0]
-
-        nextObj = None
-        while obj and not nextObj:
-            index = obj.getIndexInParent() + 1
-            if 0 < index < obj.parent.childCount:
-                nextObj = obj.parent[index]
-            elif obj.parent != documentFrame:
-                obj = obj.parent
-            else:
-                break
-
-        return nextObj
-
     ####################################################################
     #                                                                  #
     # Methods to get information about current object.                 #
     #                                                                  #
     ####################################################################
 
-    def clearCaretContext(self):
-        """Deletes all knowledge of a character context for the current
-        document frame."""
-
-        documentFrame = self.utilities.documentFrame()
-        self._destroyLineCache()
-        try:
-            del self._documentFrameCaretContext[hash(documentFrame)]
-        except:
-            pass
-
-    def setCaretContext(self, obj=None, characterOffset=-1):
-        """Sets the caret context for the current document frame."""
-
-        # We keep a context for each page tab shown.
-        # [[[TODO: WDW - probably should figure out how to destroy
-        # these contexts when a tab is killed.]]]
-        #
-        documentFrame = self.utilities.documentFrame()
-
-        if not documentFrame:
-            return
-
-        self._documentFrameCaretContext[hash(documentFrame)] = \
-            [obj, characterOffset]
-
     def getTextLineAtCaret(self, obj, offset=None, startOffset=None, endOffset=None):
         """To-be-removed. Returns the string, caretOffset, startOffset."""
 
-        if self._inFocusMode or not self.inDocumentContent(obj) \
+        if self._inFocusMode or not self.utilities.inDocumentContent(obj) \
            or obj.getState().contains(pyatspi.STATE_EDITABLE):
             return super().getTextLineAtCaret(obj, offset, startOffset, endOffset)
 
@@ -2364,13 +1747,13 @@ class Script(default.Script):
         if text and startOffset is not None and endOffset is not None:
             return text.getText(startOffset, endOffset), offset, startOffset
 
-        contextObj, contextOffset = self.getCaretContext()
+        contextObj, contextOffset = self.utilities.getCaretContext(documentFrame=None)
         if contextObj == obj:
             caretOffset = contextOffset
         else:
             caretOffset = offset
 
-        contents = self.getLineContentsAtOffset(obj, offset)
+        contents = self.utilities.getLineContentsAtOffset(obj, offset)
         contents = list(filter(lambda x: x[0] == obj, contents))
         if len(contents) == 1:
             index = 0
@@ -2382,177 +1765,7 @@ class Script(default.Script):
             if not self.EMBEDDED_OBJECT_CHARACTER in string:
                 return string, caretOffset, startOffset
 
-        return '', 0, 0
-
-    def searchForCaretLocation(self, acc):
-        """Attempts to locate the caret on the page independent of our
-        caret context. This functionality is needed when a page loads
-        and the URL is for a fragment (anchor, id, named object) within
-        that page.
-
-        Arguments:
-        - acc: The top-level accessible in which we suspect to find the
-          caret (most likely the document frame).
-
-        Returns the [obj, caretOffset] containing the caret if it can
-        be determined. Otherwise [None, -1] is returned.
-        """
-
-        context = [None, -1]
-        while acc:
-            try:
-                offset = acc.queryText().caretOffset
-            except:
-                acc = None
-            else:
-                context = [acc, offset]
-                childIndex = self.getChildIndex(acc, offset)
-                if childIndex >= 0 and acc.childCount:
-                    acc = acc[childIndex]
-                else:
-                    break
-
-        return context
-
-    def getCaretContext(self, includeNonText=True):
-        """Returns the current [obj, caretOffset] if defined.  If not,
-        it returns the first [obj, caretOffset] found by an in order
-        traversal from the beginning of the document."""
-
-        # We keep a context for each page tab shown.
-        # [[[TODO: WDW - probably should figure out how to destroy
-        # these contexts when a tab is killed.]]]
-        #
-        documentFrame = self.utilities.documentFrame()
-
-        if not documentFrame:
-            return [None, -1]
-
-        try:
-            return self._documentFrameCaretContext[hash(documentFrame)]
-        except:
-            # If we don't have a context, we should attempt to see if we
-            # can find the caret first. Failing that, we'll start at the
-            # top.
-            #
-            [obj, caretOffset] = self.searchForCaretLocation(documentFrame)
-            self._documentFrameCaretContext[hash(documentFrame)] = \
-                self.findNextCaretInOrder(obj,
-                                          max(-1, caretOffset - 1),
-                                          includeNonText)
-
-        [obj, caretOffset] = \
-            self._documentFrameCaretContext[hash(documentFrame)]
-
-        return [obj, caretOffset]
-
-    def getCharacterAtOffset(self, obj, characterOffset):
-        """Returns the character at the given characterOffset in the
-        given object or None if the object does not implement the
-        accessible text specialization.
-        """
-
-        try:
-            unicodeText = self.utilities.unicodeText(obj)
-            return unicodeText[characterOffset]
-        except:
-            return ""
-
-    def getLineContentsAtOffset(self, obj, offset):
-        if not obj:
-            return []
-
-        if self.utilities.findObjectInContents(obj, offset, self.currentLineContents) == -1:
-            self.currentLineContents = self.utilities.getLineContentsAtOffset(
-                obj, offset, _settingsManager.getSetting('layoutMode'))
-
-        return self.currentLineContents
-
-    def getObjectContentsAtOffset(self, obj, characterOffset):
-        """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 and stopping at the given object.
-        """
-
-        return self.utilities.getObjectsFromEOCs(obj, characterOffset)
-
-    ####################################################################
-    #                                                                  #
-    # Methods to speak current objects.                                #
-    #                                                                  #
-    ####################################################################
-
-    def getUtterancesFromContents(self, contents, eliminatePauses=False):
-        """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, string] tuples
-        """
-
-        if not len(contents):
-            return []
-
-        utterances = []
-        contents = self.utilities.filterContentsForPresentation(contents, True)
-        lastObj = None
-        for content in contents:
-            [obj, startOffset, endOffset, string] = content
-            if not self.utilities.justEnteredObject(obj, startOffset, endOffset) \
-               and not self.utilities.isTextBlockElement(obj):
-                formatType = 'focused'
-            else:
-                formatType = 'unfocused'
-            utterance = self.speechGenerator.generateSpeech(
-                obj, startOffset=startOffset, endOffset=endOffset, string=string,
-                formatType=formatType)
-            if eliminatePauses:
-                utterance = list(filter(lambda x: not isinstance(x, Pause), utterance))
-            if utterance and utterance[0]:
-                utterances.append(utterance)
-            lastObj = obj
-
-        # TODO - JD: This belongs in the generator.
-        if lastObj and lastObj.getRole() != pyatspi.ROLE_HEADING:
-            heading = self.utilities.ancestorWithRole(
-                lastObj, [pyatspi.ROLE_HEADING], [pyatspi.ROLE_DOCUMENT_FRAME])
-            if heading:
-                utterance = self.speechGenerator.getRoleName(heading)
-                utterances.append(utterance)
-
-        if not utterances:
-            if eliminatePauses:
-                string = ""
-            else:
-                string = messages.BLANK
-            utterances = [string, self.voices[settings.DEFAULT_VOICE]]
-
-        return utterances
-
-    def speakContents(self, contents):
-        """Speaks each string in contents using the associated voice/acss"""
-
-        speech.speak(self.getUtterancesFromContents(contents))
-
-    def speakCharacterAtOffset(self, obj, characterOffset):
-        """Speaks the character at the given characterOffset in the
-        given object."""
-        character = self.getCharacterAtOffset(obj, characterOffset)
-        self.speakMisspelledIndicator(obj, characterOffset)
-        if obj:
-            if character and character != self.EMBEDDED_OBJECT_CHARACTER:
-                self.speakCharacter(character)
-            elif not obj.getState().contains(pyatspi.STATE_EDITABLE):
-                # We won't have a character if we move to the end of an
-                # entry (in which case we're not on a character and therefore
-                # have nothing to say), or when we hit a component with no
-                # text (e.g. checkboxes) or reset the caret to the parent's
-                # characterOffset (lists).  In these latter cases, we'll just
-                # speak the entire component.
-                #
-                utterances = self.speechGenerator.generateSpeech(obj)
-                speech.speak(utterances)
+        return "", 0, 0
 
     ####################################################################
     #                                                                  #
@@ -2560,37 +1773,6 @@ class Script(default.Script):
     #                                                                  #
     ####################################################################
 
-    def setCaretPosition(self, obj, characterOffset):
-        """Sets the caret position to the given character offset in the
-        given object.
-        """
-
-        if self.flatReviewContext:
-            self.toggleFlatReviewMode()
-
-        self.setCaretContext(obj, characterOffset)
-        if self._focusModeIsSticky:
-            return
-
-        try:
-            state = obj.getState()
-        except:
-            return
-
-        orca.setLocusOfFocus(None, obj, notifyScript=False)
-        if state.contains(pyatspi.STATE_FOCUSABLE):
-            obj.queryComponent().grabFocus()
-
-        text = self.utilities.queryNonEmptyText(obj)
-        if text:
-            text.setCaretOffset(characterOffset)
-
-        if self.useFocusMode(obj) != self._inFocusMode:
-            self.togglePresentationMode(None)
-
-        obj.clearCache()
-        self._saveFocusedObjectInfo(obj)
-
     def moveToMouseOver(self, inputEvent):
         """Positions the caret offset to the next character or object
         in the mouse over which has just appeared.
@@ -2604,19 +1786,19 @@ class Script(default.Script):
             obj = self.lastMouseOverObject
             offset = 0
             if obj and not obj.getState().contains(pyatspi.STATE_FOCUSABLE):
-                [obj, offset] = self.findFirstCaretContext(obj, offset)
+                [obj, offset] = self.utilities.findFirstCaretContext(obj, offset)
 
             if obj and obj.getState().contains(pyatspi.STATE_FOCUSABLE):
                 obj.queryComponent().grabFocus()
             elif obj:
-                contents = self.getObjectContentsAtOffset(obj, offset)
+                contents = self.utilities.getObjectContentsAtOffset(obj, offset)
                 # If we don't have anything to say, let's try one more
                 # time.
                 #
                 if len(contents) == 1 and not contents[0][3].strip():
-                    [obj, offset] = self.findNextCaretInOrder(obj, offset)
-                    contents = self.getObjectContentsAtOffset(obj, offset)
-                self.setCaretPosition(obj, offset)
+                    [obj, offset] = self.utilities.findNextCaretInOrder(obj, offset)
+                    contents = self.utilities.getObjectContentsAtOffset(obj, offset)
+                self.utilities.setCaretPosition(obj, offset)
                 self.speakContents(contents)
                 self.updateBraille(obj)
             self.inMouseOverObject = True
@@ -2634,13 +1816,13 @@ class Script(default.Script):
 
         obj, offset = self.preMouseOverContext
         if obj and not obj.getState().contains(pyatspi.STATE_FOCUSABLE):
-            [obj, offset] = self.findFirstCaretContext(obj, offset)
+            [obj, offset] = self.utilities.findFirstCaretContext(obj, offset)
 
         if obj and obj.getState().contains(pyatspi.STATE_FOCUSABLE):
             obj.queryComponent().grabFocus()
         elif obj:
-            self.setCaretPosition(obj, offset)
-            self.speakContents(self.getObjectContentsAtOffset(obj, offset))
+            self.utilities.setCaretPosition(obj, offset)
+            self.speakContents(self.utilities.getObjectContentsAtOffset(obj, offset))
             self.updateBraille(obj)
         self.inMouseOverObject = False
         self.lastMouseOverObject = None
@@ -2649,17 +1831,17 @@ class Script(default.Script):
         """Positions the caret offset to the next character or object
         in the document window.
         """
-        [obj, characterOffset] = self.getCaretContext()
+        [obj, characterOffset] = self.utilities.getCaretContext()
         while obj:
-            [obj, characterOffset] = self.findNextCaretInOrder(obj,
+            [obj, characterOffset] = self.utilities.findNextCaretInOrder(obj,
                                                                characterOffset)
             if obj and obj.getState().contains(pyatspi.STATE_VISIBLE):
                 break
 
         if not obj:
-            [obj, characterOffset] = self.getBottomOfFile()
+            [obj, characterOffset] = self.utilities.getBottomOfFile()
 
-        self.setCaretPosition(obj, characterOffset)
+        self.utilities.setCaretPosition(obj, characterOffset)
         self.speakCharacterAtOffset(obj, characterOffset)
         self.updateBraille(obj)
 
@@ -2667,17 +1849,17 @@ class Script(default.Script):
         """Positions the caret offset to the previous character or object
         in the document window.
         """
-        [obj, characterOffset] = self.getCaretContext()
+        [obj, characterOffset] = self.utilities.getCaretContext()
         while obj:
-            [obj, characterOffset] = self.findPreviousCaretInOrder(
+            [obj, characterOffset] = self.utilities.findPreviousCaretInOrder(
                 obj, characterOffset)
             if obj and obj.getState().contains(pyatspi.STATE_VISIBLE):
                 break
 
         if not obj:
-            [obj, characterOffset] = self.getTopOfFile()
+            [obj, characterOffset] = self.utilities.getTopOfFile()
 
-        self.setCaretPosition(obj, characterOffset)
+        self.utilities.setCaretPosition(obj, characterOffset)
         self.speakCharacterAtOffset(obj, characterOffset)
         self.updateBraille(obj)
 
@@ -2686,12 +1868,12 @@ class Script(default.Script):
         word or object in the document window.
         """
 
-        [obj, characterOffset] = self.getCaretContext()
+        [obj, characterOffset] = self.utilities.getCaretContext()
 
         # Make sure we have a word.
         #
         [obj, characterOffset] = \
-            self.findPreviousCaretInOrder(obj, characterOffset)
+            self.utilities.findPreviousCaretInOrder(obj, characterOffset)
 
         contents = self.utilities.getWordContentsAtOffset(obj, characterOffset)
         if not len(contents):
@@ -2700,18 +1882,18 @@ class Script(default.Script):
         [obj, startOffset, endOffset, string] = contents[0]
         if len(contents) == 1 \
            and endOffset - startOffset == 1 \
-           and self.getCharacterAtOffset(obj, startOffset) == " ":
+           and self.utilities.getCharacterAtOffset(obj, startOffset) == " ":
             # Our "word" is just a space. This can happen if the previous
             # word was a mark of punctuation surrounded by whitespace (e.g.
             # " | ").
             #
             [obj, characterOffset] = \
-                self.findPreviousCaretInOrder(obj, startOffset)
+                self.utilities.findPreviousCaretInOrder(obj, startOffset)
             contents = self.utilities.getWordContentsAtOffset(obj, characterOffset)
             if len(contents):
                 [obj, startOffset, endOffset, string] = contents[0]
 
-        self.setCaretPosition(obj, startOffset)
+        self.utilities.setCaretPosition(obj, startOffset)
         self.updateBraille(obj)
         self.speakMisspelledIndicator(obj, startOffset)
         self.speakContents(contents)
@@ -2721,13 +1903,13 @@ class Script(default.Script):
         in the document window.
         """
 
-        [obj, characterOffset] = self.getCaretContext()
+        [obj, characterOffset] = self.utilities.getCaretContext()
 
         # Make sure we have a word.
         #
         characterOffset = max(0, characterOffset)
         [obj, characterOffset] = \
-            self.findNextCaretInOrder(obj, characterOffset)
+            self.utilities.findNextCaretInOrder(obj, characterOffset)
 
         contents = self.utilities.getWordContentsAtOffset(obj, characterOffset)
         if not (len(contents) and contents[-1][2]):
@@ -2736,7 +1918,7 @@ class Script(default.Script):
         [obj, startOffset, endOffset, string] = contents[-1]
         if string and string[-1].isspace():
             endOffset -= 1
-        self.setCaretPosition(obj, endOffset)
+        self.utilities.setCaretPosition(obj, endOffset)
         self.updateBraille(obj)
         self.speakMisspelledIndicator(obj, startOffset)
         self.speakContents(contents)
@@ -2752,26 +1934,20 @@ class Script(default.Script):
            and _settingsManager.getSetting('rewindAndFastForwardInSayAll'):
             return True
 
-        [obj, characterOffset] = self.getCaretContext()
-        thisLine = self.getLineContentsAtOffset(obj, characterOffset)
-        if not (thisLine and thisLine[0]):
+        obj, offset = self.utilities.getCaretContext()
+        line = self.utilities.getLineContentsAtOffset(obj, offset)
+        if not (line and line[0]):
             return False
 
-        startObj, startOffset = thisLine[0][0], thisLine[0][1]
-        prevObj, prevOffset = self.findPreviousCaretInOrder(startObj, startOffset)
-        if prevObj == startObj:
-            prevObj, prevOffset = self.findPreviousCaretInOrder(prevObj, prevOffset)
-
-        if not prevObj:
+        obj, offset = self.utilities.previousContext(line[0][0], line[0][1], True)
+        contents = self.utilities.getLineContentsAtOffset(obj, offset)
+        if not contents:
             return False
 
-        prevLine = self.getLineContentsAtOffset(prevObj, prevOffset)
-        if prevLine:
-            prevObj, prevOffset = prevLine[0][0], prevLine[0][1]
-
-        [obj, caretOffset] = self.findFirstCaretContext(prevObj, prevOffset)
-        self.setCaretPosition(obj, caretOffset)
-        self.presentLine(prevObj, prevOffset)
+        obj, start = contents[0][0], contents[0][1]
+        self.utilities.setCaretPosition(obj, start)
+        self.displayContents(contents)
+        self.speakContents(contents)
 
         return True
 
@@ -2786,36 +1962,29 @@ class Script(default.Script):
            and _settingsManager.getSetting('rewindAndFastForwardInSayAll'):
             return True
 
-        [obj, characterOffset] = self.getCaretContext()
-        thisLine = self.getLineContentsAtOffset(obj, characterOffset)
-        if not (thisLine and thisLine[0]):
+        obj, offset = self.utilities.getCaretContext()
+        line = self.utilities.getLineContentsAtOffset(obj, offset)
+        if not (line and line[0]):
             return False
 
-        lastObj, lastOffset = thisLine[-1][0], thisLine[-1][2]
-        nextObj, nextOffset = self.findNextCaretInOrder(lastObj, lastOffset - 1)
-        if nextObj and self.getCharacterAtOffset(nextObj, nextOffset).isspace():
-            nextObj, nextOffset = self.findNextCaretInOrder(nextObj, nextOffset)
-
-        if not nextObj:
+        obj, offset = self.utilities.nextContext(line[-1][0], line[-1][2] - 1, True)
+        contents = self.utilities.getLineContentsAtOffset(obj, offset)
+        if not contents:
             return False
 
-        nextLine = self.getLineContentsAtOffset(nextObj, nextOffset)
-        if nextLine:
-            nextObj, nextOffset = nextLine[0][0], nextLine[0][1]
-
-        [obj, caretOffset] = self.findFirstCaretContext(nextObj, nextOffset)
-        self.setCaretPosition(obj, caretOffset)
-        self.presentLine(nextObj, nextOffset)
-
+        obj, start = contents[0][0], contents[0][1]
+        self.utilities.setCaretPosition(obj, start)
+        self.speakContents(contents)
+        self.displayContents(contents)
         return True
 
     def goBeginningOfLine(self, inputEvent):
         """Positions the caret offset at the beginning of the line."""
 
-        [obj, characterOffset] = self.getCaretContext()
-        line = self.getLineContentsAtOffset(obj, characterOffset)
-        obj, characterOffset = self.findFirstCaretContext(line[0][0], line[0][1])
-        self.setCaretPosition(obj, characterOffset)
+        [obj, characterOffset] = self.utilities.getCaretContext()
+        line = self.utilities.getLineContentsAtOffset(obj, characterOffset)
+        obj, characterOffset = self.utilities.findFirstCaretContext(line[0][0], line[0][1])
+        self.utilities.setCaretPosition(obj, characterOffset)
         if not isinstance(orca_state.lastInputEvent, input_event.BrailleEvent):
             self.speakCharacterAtOffset(obj, characterOffset)
         self.updateBraille(obj)
@@ -2823,10 +1992,10 @@ class Script(default.Script):
     def goEndOfLine(self, inputEvent):
         """Positions the caret offset at the end of the line."""
 
-        [obj, characterOffset] = self.getCaretContext()
-        line = self.getLineContentsAtOffset(obj, characterOffset)
+        [obj, characterOffset] = self.utilities.getCaretContext()
+        line = self.utilities.getLineContentsAtOffset(obj, characterOffset)
         obj, characterOffset = line[-1][0], line[-1][2] - 1
-        self.setCaretPosition(obj, characterOffset)
+        self.utilities.setCaretPosition(obj, characterOffset)
         if not isinstance(orca_state.lastInputEvent, input_event.BrailleEvent):
             self.speakCharacterAtOffset(obj, characterOffset)
         self.updateBraille(obj)
@@ -2834,15 +2003,15 @@ class Script(default.Script):
     def goTopOfFile(self, inputEvent):
         """Positions the caret offset at the beginning of the document."""
 
-        [obj, characterOffset] = self.getTopOfFile()
-        self.setCaretPosition(obj, characterOffset)
+        [obj, characterOffset] = self.utilities.getTopOfFile()
+        self.utilities.setCaretPosition(obj, characterOffset)
         self.presentLine(obj, characterOffset)
 
     def goBottomOfFile(self, inputEvent):
         """Positions the caret offset at the end of the document."""
 
-        [obj, characterOffset] = self.getBottomOfFile()
-        self.setCaretPosition(obj, characterOffset)
+        [obj, characterOffset] = self.utilities.getBottomOfFile()
+        self.utilities.setCaretPosition(obj, characterOffset)
         self.presentLine(obj, characterOffset)
 
     def advanceLivePoliteness(self, inputEvent):
@@ -2881,15 +2050,15 @@ class Script(default.Script):
 
     def togglePresentationMode(self, inputEvent):
         if self._inFocusMode:
-            [obj, characterOffset] = self.getCaretContext()
+            [obj, characterOffset] = self.utilities.getCaretContext()
             try:
                 parentRole = obj.parent.getRole()
             except:
                 parentRole = None
             if parentRole == pyatspi.ROLE_LIST_BOX:
-                self.setCaretContext(obj.parent, -1)
+                self.utilities.setCaretContext(obj.parent, -1)
             elif parentRole == pyatspi.ROLE_MENU:
-                self.setCaretContext(obj.parent.parent, -1)
+                self.utilities.setCaretContext(obj.parent.parent, -1)
 
             self.presentMessage(messages.MODE_BROWSE)
         else:
@@ -2923,7 +2092,7 @@ class Script(default.Script):
 
         Returns True if this accessible should provide the single word.
         """
-        if self.inDocumentContent(acc):
+        if self.utilities.inDocumentContent(acc):
             try:
                 ai = acc.queryAction()
             except NotImplementedError:
diff --git a/src/orca/scripts/toolkits/Gecko/script_utilities.py 
b/src/orca/scripts/toolkits/Gecko/script_utilities.py
index dd19501..c402c95 100644
--- a/src/orca/scripts/toolkits/Gecko/script_utilities.py
+++ b/src/orca/scripts/toolkits/Gecko/script_utilities.py
@@ -32,129 +32,261 @@ __license__   = "LGPL"
 
 import pyatspi
 import re
+import urllib
 
-import orca.debug as debug
-import orca.input_event as input_event
-import orca.orca_state as orca_state
-import orca.script_utilities as script_utilities
+from orca import debug
+from orca import input_event
+from orca import orca
+from orca import orca_state
+from orca import script_utilities
+from orca import settings
+from orca import settings_manager
+
+_settingsManager = settings_manager.getManager()
 
-#############################################################################
-#                                                                           #
-# Utilities                                                                 #
-#                                                                           #
-#############################################################################
 
 class Utilities(script_utilities.Utilities):
 
     def __init__(self, script):
-        """Creates an instance of the Utilities class.
+        super().__init__(script)
+
+        self._currentAttrs = {}
+        self._caretContexts = {}
+        self._inDocumentContent = {}
+        self._isTextBlockElement = {}
+        self._isGridDescendant = {}
+        self._isOffScreenLabel = {}
+        self._hasNoSize = {}
+        self._hasLongDesc = {}
+        self._isClickableElement = {}
+        self._isAnchor = {}
+        self._isLandmark = {}
+        self._isLiveRegion = {}
+        self._isLink = {}
+        self._isNonEntryTextWidget = {}
+        self._inferredLabels = {}
+        self._text = {}
+        self._currentObjectContents = None
+        self._currentSentenceContents = None
+        self._currentLineContents = None
+        self._currentWordContents = None
+        self._currentCharacterContents = None
+
+    def _cleanupContexts(self):
+        toRemove = []
+        for key, [obj, offset] in self._caretContexts.items():
+            if self.isZombie(obj):
+                toRemove.append(key)
+
+        for key in toRemove:
+            self._caretContexts.pop(key, None)
+
+    def clearCachedObjects(self):
+        debug.println(debug.LEVEL_INFO, "INFO: cleaning up cached objects")
+        self._inDocumentContent = {}
+        self._isTextBlockElement = {}
+        self._isGridDescendant = {}
+        self._isOffScreenLabel = {}
+        self._hasNoSize = {}
+        self._hasLongDesc = {}
+        self._isClickableElement = {}
+        self._isAnchor = {}
+        self._isLandmark = {}
+        self._isLiveRegion = {}
+        self._isLink = {}
+        self._isNonEntryTextWidget = {}
+        self._inferredLabels = {}
+        self._cleanupContexts()
+
+    def clearContentCache(self):
+        self._currentObjectContents = None
+        self._currentSentenceContents = None
+        self._currentLineContents = None
+        self._currentWordContents = None
+        self._currentCharacterContents = None
+        self._currentAttrs = {}
+        self._text = {}
+
+    def inDocumentContent(self, obj=None):
+        if not obj:
+            obj = orca_state.locusOfFocus
 
-        Arguments:
-        - script: the script with which this instance is associated.
-        """
+        rv = self._inDocumentContent.get(hash(obj))
+        if rv is not None:
+            return rv
+
+        document = self.getDocumentForObject(obj)
+        rv = document is not None
+        self._inDocumentContent[hash(obj)] = rv
+        return rv
+
+    def getDocumentForObject(self, obj):
+        if not obj:
+            return None
+
+        roles = [pyatspi.ROLE_DOCUMENT_FRAME, pyatspi.ROLE_DOCUMENT_WEB]
+        isDocument = lambda x: x and x.getRole() in roles
+        if isDocument(obj):
+            return obj
+
+        return pyatspi.findAncestor(obj, isDocument)
+
+    def _getDocumentsEmbeddedBy(self, frame):
+        isEmbeds = lambda r: r.getRelationType() == pyatspi.RELATION_EMBEDS
+        relations = list(filter(isEmbeds, frame.getRelationSet()))
+        if not relations:
+            return []
+
+        relation = relations[0]
+        targets = [relation.getTarget(i) for i in range(relation.getNTargets())]
+        if not targets:
+            return []
+
+        roles = [pyatspi.ROLE_DOCUMENT_FRAME, pyatspi.ROLE_DOCUMENT_WEB]
+        isDocument = lambda x: x and x.getRole() in roles
+        return list(filter(isDocument, targets))
+
+    def documentFrame(self, obj=None):
+        isShowing = lambda x: x and x.getState().contains(pyatspi.STATE_SHOWING)
+
+        windows = [child for child in self._script.app]
+        if orca_state.activeWindow in windows:
+            windows = [orca_state.activeWindow]
+
+        for window in windows:
+            documents = self._getDocumentsEmbeddedBy(window)
+            documents = list(filter(isShowing, documents))
+            if len(documents) == 1:
+                return documents[0]
+
+        return self.getDocumentForObject(obj or orca_state.locusOfFocus)
+
+    def documentFrameURI(self):
+        documentFrame = self.documentFrame()
+        if documentFrame and not self.isZombie(documentFrame):
+            document = documentFrame.queryDocument()
+            return document.getAttributeValue('DocURL')
+
+        return None
+
+    def setCaretPosition(self, obj, offset):
+        if self._script.flatReviewContext:
+            self._script.toggleFlatReviewMode()
+
+        obj, offset = self.findFirstCaretContext(obj, offset)
+        self.setCaretContext(obj, offset, documentFrame=None)
+        if self._script.focusModeIsSticky():
+            return
 
-        script_utilities.Utilities.__init__(self, script)
-
-    #########################################################################
-    #                                                                       #
-    # Utilities for finding, identifying, and comparing accessibles         #
-    #                                                                       #
-    #########################################################################
-
-    def cellIndex(self, obj):
-        """Returns the index of the cell which should be used with the
-        table interface.  This is necessary because we cannot count on
-        the index we need being the same as the index in the parent.
-        See, for example, tables with captions and tables with rows
-        that have attributes."""
-
-        index = -1
-        parent = self.ancestorWithRole(obj,
-                                       [pyatspi.ROLE_TABLE, 
-                                        pyatspi.ROLE_TREE_TABLE,
-                                        pyatspi.ROLE_TREE],
-                                       [pyatspi.ROLE_DOCUMENT_FRAME])
         try:
-            table = parent.queryTable()
+            state = obj.getState()
         except:
-            pass
-        else:
-            attrs = dict([attr.split(':', 1) for attr in obj.getAttributes()])
-            index = attrs.get('table-cell-index')
-            if index:
-                index = int(index)
+            return
+
+        orca.setLocusOfFocus(None, obj, notifyScript=False)
+        if state.contains(pyatspi.STATE_FOCUSABLE):
+            try:
+                obj.queryComponent().grabFocus()
+            except:
+                return
+
+        text = self.queryNonEmptyText(obj)
+        if text:
+            text.setCaretOffset(offset)
+
+        if self._script.useFocusMode(obj) != self._script.inFocusMode():
+            self._script.togglePresentationMode(None)
+
+        obj.clearCache()
+
+        # TODO - JD: This is private.
+        self._script._saveFocusedObjectInfo(obj)
+
+    def getNextObjectInDocument(self, obj, documentFrame):
+        if not obj:
+            return None
+
+        for relation in obj.getRelationSet():
+            if relation.getRelationType() == pyatspi.RELATION_FLOWS_TO:
+                return relation.getTarget(0)
+
+        if obj == documentFrame:
+            obj, offset = self.getCaretContext(documentFrame)
+            for child in documentFrame:
+                if self.characterOffsetInParent(child) > offset:
+                    return child
+
+        if obj and obj.childCount:
+            return obj[0]
+
+        nextObj = None
+        while obj and not nextObj:
+            index = obj.getIndexInParent() + 1
+            if 0 < index < obj.parent.childCount:
+                nextObj = obj.parent[index]
+            elif obj.parent != documentFrame:
+                obj = obj.parent
             else:
-                index = obj.getIndexInParent()
+                break
 
-        return index
+        return nextObj
 
-    def documentFrame(self):
-        """Returns the document frame that holds the content being shown."""
+    def getPreviousObjectInDocument(self, obj, documentFrame):
+        if not obj:
+            return None
 
-        # [[[TODO: WDW - this is based upon the 12-Oct-2006 implementation
-        # that uses the EMBEDS relation on the top level frame as a means
-        # to find the document frame.  Future implementations will break
-        # this.]]]
-        #
-        documentFrame = None
-        for child in self._script.app:
-            if child.getRole() == pyatspi.ROLE_FRAME:
-                relationSet = child.getRelationSet()
-                for relation in relationSet:
-                    if relation.getRelationType()  \
-                        == pyatspi.RELATION_EMBEDS:
-                        documentFrame = relation.getTarget(0)
-                        if documentFrame.getState().contains(
-                            pyatspi.STATE_SHOWING):
-                            break
-                        else:
-                            documentFrame = None
-
-        # Certain add-ons can interfere with the above approach. But we
-        # should have a locusOfFocus. If so look up and try to find the
-        # document frame. See bug 537303.
-        #
-        if not documentFrame:
-            documentFrame = self.ancestorWithRole(
-                orca_state.locusOfFocus,
-                [pyatspi.ROLE_DOCUMENT_FRAME],
-                [pyatspi.ROLE_FRAME])
+        for relation in obj.getRelationSet():
+            if relation.getRelationType() == pyatspi.RELATION_FLOWS_FROM:
+                return relation.getTarget(0)
 
-        return documentFrame
+        if obj == documentFrame:
+            obj, offset = self.getCaretContext(documentFrame)
+            for child in documentFrame:
+                if self.characterOffsetInParent(child) < offset:
+                    return child
 
-    def documentFrameURI(self):
-        """Returns the URI of the document frame that is active."""
+        index = obj.getIndexInParent() - 1
+        if not 0 <= index < obj.parent.childCount:
+            obj = obj.parent
+            index = obj.getIndexInParent() - 1
 
-        documentFrame = self.documentFrame()
-        if documentFrame:
-            # If the document frame belongs to a Thunderbird message which
-            # has just been deleted, getAttributes() will crash Thunderbird.
-            #
-            if not documentFrame.getState().contains(pyatspi.STATE_DEFUNCT):
-                attrs = documentFrame.queryDocument().getAttributes()
-                for attr in attrs:
-                    if attr.startswith('DocURL'):
-                        return attr[7:]
+        previousObj = obj.parent[index]
+        while previousObj and previousObj.childCount:
+            previousObj = previousObj[previousObj.childCount - 1]
 
-        return None
+        return previousObj
 
-    def grabFocusBeforeRouting(self, obj, offset):
-        """Whether or not we should perform a grabFocus before routing
-        the cursor via the braille cursor routing keys.
+    def getTopOfFile(self):
+        return self.findFirstCaretContext(self.documentFrame(), 0)
 
-        Arguments:
-        - obj: the accessible object where the cursor should be routed
-        - offset: the offset to which it should be routed
+    def getBottomOfFile(self):
+        obj = self.getLastObjectInDocument(self.documentFrame())
+        offset = 0
+        text = self.queryNonEmptyText(obj)
+        if text:
+            offset = text.characterCount - 1
 
-        Returns True if we should do an explicit grabFocus on obj prior
-        to routing the cursor.
-        """
+        while obj:
+            lastobj, lastoffset = self.nextContext(obj, offset)
+            if not lastobj:
+                break
+            obj, offset = lastobj, lastoffset
 
-        if obj and obj.getRole() == pyatspi.ROLE_COMBO_BOX \
-           and not self.isSameObject(obj, orca_state.locusOfFocus):
-            return True
+        return [obj, offset]
 
-        return False
+    def getLastObjectInDocument(self, documentFrame):
+        try:
+            lastChild = documentFrame[documentFrame.childCount - 1]
+        except:
+            lastChild = documentFrame
+        while lastChild:
+            lastObj = self.getNextObjectInDocument(lastChild, documentFrame)
+            if lastObj and lastObj != lastChild:
+                lastChild = lastObj
+            else:
+                break
+
+        return lastChild
 
     def inFindToolbar(self, obj=None):
         if not obj:
@@ -164,44 +296,29 @@ class Utilities(script_utilities.Utilities):
            and obj.parent.getRole() == pyatspi.ROLE_AUTOCOMPLETE:
             return False
 
-        return script_utilities.Utilities.inFindToolbar(obj)
-
-    def isLink(self, obj):
-        """Returns True if we should treat this object as a link."""
+        return super().inFindToolbar(obj)
 
-        if not obj:
+    def isHidden(self, obj):
+        try:
+            attrs = dict([attr.split(':', 1) for attr in obj.getAttributes()])
+        except:
             return False
+        return attrs.get('hidden', False)
 
-        role = obj.getRole()
-        if role == pyatspi.ROLE_LINK:
-            return True
-
-        if role == pyatspi.ROLE_TEXT \
-           and obj.parent.getRole() == pyatspi.ROLE_LINK \
-           and obj.name and obj.name == obj.parent.name:
-            return True
-
-        return False
-
-    def isHidden(self, obj):
-        attrs = dict([attr.split(':', 1) for attr in obj.getAttributes()])
-        isHidden = attrs.get('hidden', False)
+    def isTextArea(self, obj):
+        if self.isLink(obj):
+            return False
 
-        return isHidden
+        return super().isTextArea(obj)
 
     def isReadOnlyTextArea(self, obj):
-        """Returns True if obj is a text entry area that is read only."""
-
-        if not obj.getRole() == pyatspi.ROLE_ENTRY:
+        # NOTE: This method is deliberately more conservative than isTextArea.
+        if obj.getRole() != pyatspi.ROLE_ENTRY:
             return False
 
         state = obj.getState()
         readOnly = state.contains(pyatspi.STATE_FOCUSABLE) \
                    and not state.contains(pyatspi.STATE_EDITABLE)
-        details = debug.getAccessibleDetails(debug.LEVEL_ALL, obj)
-        debug.println(debug.LEVEL_ALL,
-                      "Gecko - isReadOnlyTextArea=%s for %s" \
-                      % (readOnly, details))
 
         return readOnly
 
@@ -263,7 +380,7 @@ class Utilities(script_utilities.Utilities):
         if parent.getRole() != pyatspi.ROLE_TREE_TABLE \
            or parent.getState().contains(pyatspi.STATE_MANAGES_DESCENDANTS) \
            or parent.childCount <= 50:
-            return script_utilities.Utilities.showingDescendants(self, parent)
+            return super().showingDescendants(parent)
 
         try:
             table = parent.queryTable()
@@ -341,34 +458,6 @@ class Utilities(script_utilities.Utilities):
 
         return descendants
 
-    def uri(self, obj):
-        """Return the URI for a given link object.
-
-        Arguments:
-        - obj: the Accessible object.
-        """
-
-        # Getting a link's URI requires a little workaround due to
-        # https://bugzilla.mozilla.org/show_bug.cgi?id=379747.  You
-        # should be able to use getURI() directly on the link but
-        # instead must use ihypertext.getLink(0) on parent then use
-        # getURI on returned ihyperlink.
-        try:
-            ihyperlink = obj.parent.queryHypertext().getLink(0)
-        except:
-            return None
-        else:
-            try:
-                return ihyperlink.getURI(0)
-            except:
-                return None
-
-    #########################################################################
-    #                                                                       #
-    # Utilities for working with the accessible text interface              #
-    #                                                                       #
-    #########################################################################
-
     def isWordMisspelled(self, obj, offset):
         """Identifies if the current word is flagged as misspelled by the
         application.
@@ -387,57 +476,53 @@ class Utilities(script_utilities.Utilities):
         return error == "spelling"
 
     def setCaretOffset(self, obj, characterOffset):
-        self._script.setCaretPosition(obj, characterOffset)
+        self.setCaretPosition(obj, characterOffset)
         self._script.updateBraille(obj)
 
-    def textAttributes(self, acc, offset, get_defaults=False):
-        """Get the text attributes run for a given offset in a given accessible
+    def nextContext(self, obj=None, offset=-1, skipSpace=False):
+        if not obj:
+            obj, offset = self.getCaretContext()
 
-        Arguments:
-        - acc: An accessible.
-        - offset: Offset in the accessible's text for which to retrieve the
-        attributes.
-        - get_defaults: Get the default attributes as well as the unique ones.
-        Default is True
+        nextobj, nextoffset = self.findNextCaretInOrder(obj, offset)
+        if (obj, offset) == (nextobj, nextoffset):
+            nextobj, nextoffset = self.findNextCaretInOrder(nextobj, nextoffset)
 
-        Returns a dictionary of attributes, a start offset where the attributes
-        begin, and an end offset. Returns ({}, 0, 0) if the accessible does not
-        supprt the text attribute.
-        """
+        if skipSpace:
+            text = self.queryNonEmptyText(nextobj)
+            while text and text.getText(nextoffset, nextoffset + 1).isspace():
+                nextobj, nextoffset = self.findNextCaretInOrder(nextobj, nextoffset)
+                text = self.queryNonEmptyText(nextobj)
 
-        # For really large objects, a call to getAttributes can take up to
-        # two seconds! This is a Gecko bug. We'll try to improve things
-        # by storing attributes.
-        #
-        attrsForObj = self._script.currentAttrs.get(hash(acc)) or {}
-        if offset in attrsForObj:
-            return attrsForObj.get(offset)
-
-        attrs = script_utilities.Utilities.textAttributes(
-            self, acc, offset, get_defaults)
-        self._script.currentAttrs[hash(acc)] = {offset:attrs}
+        return nextobj, nextoffset
 
-        return attrs
+    def previousContext(self, obj=None, offset=-1, skipSpace=False):
+        if not obj:
+            obj, offset = self.getCaretContext()
 
-    #########################################################################
-    #                                                                       #
-    # Miscellaneous Utilities                                               #
-    #                                                                       #
-    #########################################################################
+        prevobj, prevoffset = self.findPreviousCaretInOrder(obj, offset)
+        if (obj, offset) == (prevobj, prevoffset):
+            prevobj, prevoffset = self.findPreviousCaretInOrder(prevobj, prevoffset)
 
-    # TODO - JD: Ultimately "utilities" need to be properly organized into
-    # functionality-based modules. But they belong even less in the script.
+        if skipSpace:
+            text = self.queryNonEmptyText(prevobj)
+            while text and text.getText(prevoffset, prevoffset + 1).isspace():
+                prevobj, prevoffset = self.findPreviousCaretInOrder(prevobj, prevoffset)
+                text = self.queryNonEmptyText(prevobj)
 
-    def extentsAreOnSameLine(self, a, b, pixelDelta=5):
-        """Determine if extents a and b are on the same line.
+        return prevobj, prevoffset
 
-        Arguments:
-        -a: [x, y, width, height]
-        -b: [x, y, width, height]
+    def contextsAreOnSameLine(self, a, b):
+        if a == b:
+            return True
 
-        Returns True if a and b are on the same line.
-        """
+        aObj, aOffset = a
+        bObj, bOffset = b
+        aExtents = self.getExtents(aObj, aOffset, aOffset + 1)
+        bExtents = self.getExtents(bObj, bOffset, bOffset + 1)
+        return self.extentsAreOnSameLine(aExtents, bExtents)
 
+    @staticmethod
+    def extentsAreOnSameLine(a, b, pixelDelta=5):
         if a == b:
             return True
 
@@ -461,40 +546,155 @@ class Utilities(script_utilities.Utilities):
 
         return True
 
-    def getExtents(self, obj, startOffset, endOffset):
-        """Returns [x, y, width, height] of the text at the given offsets
-        if the object implements accessible text, or just the extents of
-        the object if it doesn't implement accessible text.
-        """
+    @staticmethod
+    def getExtents(obj, startOffset, endOffset):
         if not obj:
             return [0, 0, 0, 0]
 
-        role = obj.getRole()
-        text = self.queryNonEmptyText(obj)
-        if text and not self._treatTextObjectAsWhole(obj):
-            return list(text.getRangeExtents(startOffset, endOffset, 0))
+        try:
+            text = obj.queryText()
+            if text.characterCount:
+                return list(text.getRangeExtents(startOffset, endOffset, 0))
+        except NotImplementedError:
+            pass
+        except:
+            return [0, 0, 0, 0]
 
+        role = obj.getRole()
         parentRole = obj.parent.getRole()
         if role in [pyatspi.ROLE_MENU, pyatspi.ROLE_LIST_ITEM] \
            and parentRole in [pyatspi.ROLE_COMBO_BOX, pyatspi.ROLE_LIST_BOX]:
-            ext = obj.parent.queryComponent().getExtents(0)
+            try:
+                ext = obj.parent.queryComponent().getExtents(0)
+            except:
+                return [0, 0, 0, 0]
         else:
-            ext = obj.queryComponent().getExtents(0)
+            try:
+                ext = obj.queryComponent().getExtents(0)
+            except:
+                return [0, 0, 0, 0]
 
         return [ext.x, ext.y, ext.width, ext.height]
 
+    def expandEOCs(self, obj, startOffset=0, endOffset=-1):
+        if not self.inDocumentContent(obj):
+            return ""
+
+        text = self.queryNonEmptyText(obj)
+        if not text:
+            return ""
+
+        string = text.getText(startOffset, endOffset)
+
+        if self.EMBEDDED_OBJECT_CHARACTER in string:
+            # If we're not getting the full text of this object, but
+            # rather a substring, we need to figure out the offset of
+            # the first child within this substring.
+            childOffset = 0
+            for child in obj:
+                if self.characterOffsetInParent(child) >= startOffset:
+                    break
+                childOffset += 1
+
+            toBuild = list(string)
+            count = toBuild.count(self.EMBEDDED_OBJECT_CHARACTER)
+            for i in range(count):
+                index = toBuild.index(self.EMBEDDED_OBJECT_CHARACTER)
+                try:
+                    child = obj[i + childOffset]
+                except:
+                    continue
+                childText = self.expandEOCs(child)
+                if not childText:
+                    childText = ""
+                toBuild[index] = "%s " % childText
+
+            string = "".join(toBuild).strip()
+
+        return string
+
+    def substring(self, obj, startOffset, endOffset):
+        if not self.inDocumentContent(obj):
+            return super().substring(obj, startOffset, endOffset)
+
+        text = self.queryNonEmptyText(obj)
+        if text:
+            return text.getText(startOffset, endOffset)
+
+        return ""
+
+    def textAttributes(self, acc, offset, get_defaults=False):
+        attrsForObj = self._currentAttrs.get(hash(acc)) or {}
+        if offset in attrsForObj:
+            return attrsForObj.get(offset)
+
+        attrs = super().textAttributes(acc, offset, get_defaults)
+        self._currentAttrs[hash(acc)] = {offset:attrs}
+
+        return attrs
+
     def findObjectInContents(self, obj, offset, contents):
         if not obj or not contents:
             return -1
 
         offset = max(0, offset)
-        matches = [x for x in contents if self.isSameObject(x[0], obj)]
+        matches = [x for x in contents if x[0] == obj]
         match = [x for x in matches if x[1] <= offset < x[2]]
         if match and match[0] and match[0] in contents:
             return contents.index(match[0])
 
         return -1
 
+    def isNonEntryTextWidget(self, obj):
+        rv = self._isNonEntryTextWidget.get(hash(obj))
+        if rv is not None:
+            return rv
+
+        roles = [pyatspi.ROLE_CHECK_BOX,
+                 pyatspi.ROLE_CHECK_MENU_ITEM,
+                 pyatspi.ROLE_MENU,
+                 pyatspi.ROLE_MENU_ITEM,
+                 pyatspi.ROLE_PAGE_TAB,
+                 pyatspi.ROLE_RADIO_MENU_ITEM,
+                 pyatspi.ROLE_RADIO_BUTTON,
+                 pyatspi.ROLE_PUSH_BUTTON,
+                 pyatspi.ROLE_TOGGLE_BUTTON]
+
+        role = obj.getRole()
+        if role in roles:
+            rv = True
+        elif role in [pyatspi.ROLE_LIST_ITEM, pyatspi.ROLE_TABLE_CELL]:
+            rv = not self.isTextBlockElement(obj)
+
+        self._isNonEntryTextWidget[hash(obj)] = rv
+        return rv
+
+    def queryNonEmptyText(self, obj, excludeNonEntryTextWidgets=True):
+        if hash(obj) in self._text:
+            return self._text.get(hash(obj))
+
+        try:
+            rv = obj.queryText()
+            characterCount = rv.characterCount
+        except:
+            rv = None
+        else:
+            if not characterCount:
+                rv = None
+
+        doNotQuery = [pyatspi.ROLE_LIST,
+                      pyatspi.ROLE_TABLE_ROW,
+                      pyatspi.ROLE_TOOL_BAR]
+        if rv and obj.getRole() in doNotQuery:
+            rv = None
+        if rv and excludeNonEntryTextWidgets and self.isNonEntryTextWidget(obj):
+            rv = None
+        if rv and (self.isHidden(obj) or self.isOffScreenLabel(obj)):
+            rv = None
+
+        self._text[hash(obj)] = rv
+        return rv
+
     def _treatTextObjectAsWhole(self, obj):
         roles = [pyatspi.ROLE_CHECK_BOX,
                  pyatspi.ROLE_CHECK_MENU_ITEM,
@@ -514,49 +714,50 @@ class Utilities(script_utilities.Utilities):
 
         return False
 
-    def __findRange(self, obj, offset, boundary):
+    def __findRange(self, text, offset, start, end, boundary):
         # We should not have to do any of this. Seriously. This is why
         # We can't have nice things.
-        if not obj:
-            return '', 0, 0
-
-        text = self.queryNonEmptyText(obj)
-        if not text:
-            return '', 0, 1
 
         allText = text.getText(0, -1)
         extents = list(text.getRangeExtents(offset, offset + 1, 0))
 
-        def _inThisSentence(span):
-            return span[0] <= offset <= span[1]
-
-        def _inThisWord(span):
+        def _inThisSpan(span):
             return span[0] <= offset <= span[1]
 
         def _onThisLine(span):
             rangeExtents = list(text.getRangeExtents(span[0], span[0] + 1, 0))
             return self.extentsAreOnSameLine(extents, rangeExtents)
 
-        words = [m.span() for m in re.finditer("[^\s\ufffc]+", allText)]
-        sentences = [m.span() for m in re.finditer("\S[^\.\?\!]+((?<!\w)[\.\?\!]+(?!\w)|\S*)", allText)]
-        if boundary == pyatspi.TEXT_BOUNDARY_LINE_START:
-            segments = list(filter(_onThisLine, words))
-        elif boundary == pyatspi.TEXT_BOUNDARY_WORD_START:
-            segments = list(filter(_inThisWord, words))
-        elif boundary == pyatspi.TEXT_BOUNDARY_SENTENCE_START:
-            sentences = sentences or [(0, text.characterCount)]
-            segments = list(filter(_inThisSentence, sentences))
-        else:
-            return '', 0, 0
+        spans = []
+        charCount = text.characterCount
+        if boundary == pyatspi.TEXT_BOUNDARY_SENTENCE_START:
+            spans = [m.span() for m in re.finditer("\S*[^\.\?\!]+((?<!\w)[\.\?\!]+(?!\w)|\S*)", allText)]
+        elif boundary is not None:
+            spans = [m.span() for m in re.finditer("[^\n\r]+", allText)]
+        if not spans:
+            spans = [(0, charCount)]
+
+        rangeStart, rangeEnd = 0, charCount
+        for span in spans:
+            if _inThisSpan(span):
+                rangeStart, rangeEnd = span[0], span[1] + 1
+                break
 
-        if segments and segments[0]:
-            start = segments[0][0]
-            end = segments[-1][1] + 1
-            if start <= offset < end:
-                string = allText[start:end]
-                return string, start, end
+        string = allText[rangeStart:rangeEnd]
+        if string and boundary in [pyatspi.TEXT_BOUNDARY_SENTENCE_START, None]:
+            return string, rangeStart, rangeEnd
 
-        return allText[offset:offset+1], offset, offset + 1
+        words = [m.span() for m in re.finditer("[^\s\ufffc]+", string)]
+        words = list(map(lambda x: (x[0] + rangeStart, x[1] + rangeStart), words))
+        if boundary == pyatspi.TEXT_BOUNDARY_WORD_START:
+            spans = list(filter(_inThisSpan, words))
+        if boundary == pyatspi.TEXT_BOUNDARY_LINE_START:
+            spans = list(filter(_onThisLine, words))
+        if spans:
+            rangeStart, rangeEnd = spans[0][0], spans[-1][1] + 1
+            string = allText[rangeStart:rangeEnd]
+
+        return string, rangeStart, rangeEnd
 
     def _getTextAtOffset(self, obj, offset, boundary):
         if not obj:
@@ -566,23 +767,24 @@ class Utilities(script_utilities.Utilities):
         if not text:
             return '', 0, 1
 
-        treatAsWhole = self._treatTextObjectAsWhole(obj)
-        if not treatAsWhole and boundary == pyatspi.TEXT_BOUNDARY_SENTENCE_START:
-            state = obj.getState()
-            if state.contains(pyatspi.STATE_EDITABLE) \
-               and state.contains(pyatspi.STATE_FOCUSED):
-                treatAsWhole = False
-            elif obj.getRole() in [pyatspi.ROLE_LIST_ITEM, pyatspi.ROLE_HEADING] \
-               or not self.isTextBlockElement(obj):
-                treatAsWhole = True
+        if boundary == pyatspi.TEXT_BOUNDARY_CHAR:
+            return text.getText(offset, offset + 1), offset, offset + 1
 
-        if treatAsWhole:
-            return text.getText(0, -1), 0, text.characterCount
+        if not boundary:
+            return text.getText(offset, -1), offset, text.characterCount
+
+        if boundary == pyatspi.TEXT_BOUNDARY_SENTENCE_START \
+            and not obj.getState().contains(pyatspi.STATE_EDITABLE):
+            allText = text.getText(0, -1)
+            if obj.getRole() in [pyatspi.ROLE_LIST_ITEM, pyatspi.ROLE_HEADING] \
+               or not (re.search("\w", allText) and self.isTextBlockElement(obj)):
+                return allText, 0, text.characterCount
 
         offset = max(0, offset)
         string, start, end = text.getTextAtOffset(offset, boundary)
 
         # The above should be all that we need to do, but....
+
         needSadHack = False
         testString, testStart, testEnd = text.getTextAtOffset(start, boundary)
         if (string, start, end) != (testString, testStart, testEnd):
@@ -592,7 +794,7 @@ class Utilities(script_utilities.Utilities):
                   "      For offset %i - String: '%s', Start: %i, End: %i.\n" \
                   "      For offset %i - String: '%s', Start: %i, End: %i.\n" \
                   "      The bug is the above results should be the same.\n" \
-                  "      This very likely needs to be fixed by Mozilla." \
+                  "      This very likely needs to be fixed by the toolkit." \
                   % (obj, boundary, offset, s1.replace("\n", "\\n"), start, end,
                      start, s2.replace("\n", "\\n"), testStart, testEnd)
             debug.println(debug.LEVEL_INFO, msg)
@@ -604,7 +806,7 @@ class Utilities(script_utilities.Utilities):
                   "      String: '%s', Start: %i, End: %i.\n" \
                   "      The bug is no text reported for a valid offset.\n" \
                   "      Character count: %i, Full text: '%s'.\n" \
-                  "      This very likely needs to be fixed by Mozilla." \
+                  "      This very likely needs to be fixed by the toolkit." \
                   % (offset, obj, boundary, s1.replace("\n", "\\n"), start, end,
                      text.characterCount, s2.replace("\n", "\\n"))
             debug.println(debug.LEVEL_INFO, msg)
@@ -614,13 +816,13 @@ class Utilities(script_utilities.Utilities):
             msg = "FAIL: Bad results for text at offset %i for %s using %s:\n" \
                   "      String: '%s', Start: %i, End: %i.\n" \
                   "      The bug is the range returned is outside of the offset.\n" \
-                  "      This very likely needs to be fixed by Mozilla." \
+                  "      This very likely needs to be fixed by the toolkit." \
                   % (offset, obj, boundary, s1.replace("\n", "\\n"), start, end)
             debug.println(debug.LEVEL_INFO, msg)
             needSadHack = True
 
         if needSadHack:
-            sadString, sadStart, sadEnd = self.__findRange(obj, offset, boundary)
+            sadString, sadStart, sadEnd = self.__findRange(text, offset, start, end, boundary)
             s = sadString.replace(self.EMBEDDED_OBJECT_CHARACTER, "[OBJ]")
             msg = "HACK: Attempting to recover from above failure.\n" \
                   "      Returning: '%s' (%i, %i) " % (s, sadStart, sadEnd)
@@ -644,9 +846,13 @@ class Utilities(script_utilities.Utilities):
             pass
         else:
             if char == self.EMBEDDED_OBJECT_CHARACTER:
-                childIndex = self._script.getChildIndex(obj, offset)
-                child = obj[childIndex]
-                return [[child, 0, 1, ""]]
+                childIndex = self.getChildIndex(obj, offset)
+                try:
+                    child = obj[childIndex]
+                except:
+                    pass
+                else:
+                    return self._getContentsForObj(child, 0, boundary)
 
         ranges = [m.span() for m in re.finditer("[^\ufffc]+", string)]
         strings = list(filter(lambda x: x[0] <= stringOffset <= x[1], ranges))
@@ -658,10 +864,16 @@ class Utilities(script_utilities.Utilities):
 
         return [[obj, start, end, string]]
 
-    def getSentenceContentsAtOffset(self, obj, offset):
+    def getSentenceContentsAtOffset(self, obj, offset, useCache=True):
         if not obj:
             return []
 
+        offset = max(0, offset)
+
+        if useCache:
+            if self.findObjectInContents(obj, offset, self._currentSentenceContents) != -1:
+                return self._currentSentenceContents
+
         boundary = pyatspi.TEXT_BOUNDARY_SENTENCE_START
         objects = self._getContentsForObj(obj, offset, boundary)
         state = obj.getState()
@@ -682,7 +894,7 @@ class Utilities(script_utilities.Utilities):
                 xString = " ".join(xString.split()[1:])
 
             match = re.search("\S[\.\!\?]+(\s|\Z)", xString)
-            return match != None
+            return match is not None
 
         # Check for things in the same sentence before this object.
         firstObj, firstStart, firstEnd, firstString = objects[0]
@@ -690,7 +902,7 @@ class Utilities(script_utilities.Utilities):
             if firstStart == 0 and self.isTextBlockElement(firstObj):
                 break
 
-            prevObj, pOffset = self._script.findPreviousCaretInOrder(firstObj, firstStart)
+            prevObj, pOffset = self.findPreviousCaretInOrder(firstObj, firstStart)
             onLeft = self._getContentsForObj(prevObj, pOffset, boundary)
             onLeft = list(filter(lambda x: x not in objects, onLeft))
             endsOnLeft = list(filter(_treatAsSentenceEnd, onLeft))
@@ -707,7 +919,7 @@ class Utilities(script_utilities.Utilities):
         # Check for things in the same sentence after this object.
         while not _treatAsSentenceEnd(objects[-1]):
             lastObj, lastStart, lastEnd, lastString = objects[-1]
-            nextObj, nOffset = self._script.findNextCaretInOrder(lastObj, lastEnd - 1)
+            nextObj, nOffset = self.findNextCaretInOrder(lastObj, lastEnd - 1)
             onRight = self._getContentsForObj(nextObj, nOffset, boundary)
             onRight = list(filter(lambda x: x not in objects, onRight))
             if not onRight:
@@ -715,12 +927,45 @@ class Utilities(script_utilities.Utilities):
 
             objects.extend(onRight)
 
+        if useCache:
+            self._currentSentenceContents = objects
+
         return objects
 
-    def getWordContentsAtOffset(self, obj, offset):
+    def getCharacterAtOffset(self, obj, offset):
+        text = self.queryNonEmptyText(obj)
+        if text:
+            return text.getText(offset, offset + 1)
+
+        return ""
+
+    def getCharacterContentsAtOffset(self, obj, offset, useCache=True):
         if not obj:
             return []
 
+        offset = max(0, offset)
+
+        if useCache:
+            if self.findObjectInContents(obj, offset, self._currentCharacterContents) != -1:
+                return self._currentCharacterContents
+
+        boundary = pyatspi.TEXT_BOUNDARY_CHAR
+        objects = self._getContentsForObj(obj, offset, boundary)
+        if useCache:
+            self._currentCharacterContents = objects
+
+        return objects
+
+    def getWordContentsAtOffset(self, obj, offset, useCache=True):
+        if not obj:
+            return []
+
+        offset = max(0, offset)
+
+        if useCache:
+            if self.findObjectInContents(obj, offset, self._currentWordContents) != -1:
+                return self._currentWordContents
+
         boundary = pyatspi.TEXT_BOUNDARY_WORD_START
         objects = self._getContentsForObj(obj, offset, boundary)
         extents = self.getExtents(obj, offset, offset + 1)
@@ -738,7 +983,7 @@ class Utilities(script_utilities.Utilities):
 
         # Check for things in the same word to the left of this object.
         firstObj, firstStart, firstEnd, firstString = objects[0]
-        prevObj, pOffset = self._script.findPreviousCaretInOrder(firstObj, firstStart)
+        prevObj, pOffset = self.findPreviousCaretInOrder(firstObj, firstStart)
         while prevObj and firstString:
             text = self.queryNonEmptyText(prevObj)
             if not text or text.getText(pOffset, pOffset + 1).isspace():
@@ -751,12 +996,12 @@ class Utilities(script_utilities.Utilities):
 
             objects[0:0] = onLeft
             firstObj, firstStart, firstEnd, firstString = objects[0]
-            prevObj, pOffset = self._script.findPreviousCaretInOrder(firstObj, firstStart)
+            prevObj, pOffset = self.findPreviousCaretInOrder(firstObj, firstStart)
 
         # Check for things in the same word to the right of this object.
         lastObj, lastStart, lastEnd, lastString = objects[-1]
         while lastObj and lastString and not lastString[-1].isspace():
-            nextObj, nOffset = self._script.findNextCaretInOrder(lastObj, lastEnd - 1)
+            nextObj, nOffset = self.findNextCaretInOrder(lastObj, lastEnd - 1)
             onRight = self._getContentsForObj(nextObj, nOffset, boundary)
             onRight = list(filter(_include, onRight))
             if not onRight:
@@ -770,6 +1015,59 @@ class Utilities(script_utilities.Utilities):
         if firstStart == 0 and firstObj.getRole() == pyatspi.ROLE_LIST_ITEM:
             objects = [objects[0]]
 
+        if useCache:
+            self._currentWordContents = objects
+
+        return objects
+
+    def getObjectContentsAtOffset(self, obj, offset=0, useCache=True):
+        if not obj:
+            return []
+
+        offset = max(0, offset)
+
+        if useCache:
+            if self.findObjectInContents(obj, offset, self._currentObjectContents) != -1:
+                return self._currentObjectContents
+
+        objIsLandmark = self.isLandmark(obj)
+
+        def _isInObject(x):
+            if not x:
+                return False
+            if x == obj:
+                return True
+            return _isInObject(x.parent)
+
+        def _include(x):
+            if x in objects:
+                return False
+
+            xObj, xStart, xEnd, xString = x
+            if xStart == xEnd:
+                return False
+
+            if objIsLandmark and self.isLandmark(xObj) and obj != xObj:
+                return False
+
+            return _isInObject(xObj)
+
+        objects = self._getContentsForObj(obj, offset, None)
+        lastObj, lastStart, lastEnd, lastString = objects[-1]
+        nextObj, nOffset = self.findNextCaretInOrder(lastObj, lastEnd - 1)
+        while nextObj:
+            onRight = self._getContentsForObj(nextObj, nOffset, None)
+            onRight = list(filter(_include, onRight))
+            if not onRight:
+                break
+
+            objects.extend(onRight)
+            lastObj, lastEnd = objects[-1][0], objects[-1][2]
+            nextObj, nOffset = self.findNextCaretInOrder(lastObj, lastEnd - 1)
+
+        if useCache:
+            self._currentObjectContents = objects
+
         return objects
 
     def _contentIsSubsetOf(self, contentA, contentB):
@@ -782,10 +1080,22 @@ class Utilities(script_utilities.Utilities):
 
         return False
 
-    def getLineContentsAtOffset(self, obj, offset, layoutMode=True):
+    def getLineContentsAtOffset(self, obj, offset, layoutMode=None, useCache=True):
         if not obj:
             return []
 
+        text = self.queryNonEmptyText(obj)
+        if text and offset == text.characterCount:
+            offset -= 1
+        offset = max(0, offset)
+
+        if useCache:
+            if self.findObjectInContents(obj, offset, self._currentLineContents) != -1:
+                return self._currentLineContents
+
+        if layoutMode == None:
+            layoutMode = _settingsManager.getSetting('layoutMode')
+
         objects = []
         extents = self.getExtents(obj, offset, offset + 1)
 
@@ -804,9 +1114,12 @@ class Utilities(script_utilities.Utilities):
         objects = self._getContentsForObj(obj, offset, boundary)
 
         firstObj, firstStart, firstEnd, firstString = objects[0]
+        if extents[2] == 0 and extents[3] == 0:
+            extents = self.getExtents(obj, firstStart, firstEnd)
+
         lastObj, lastStart, lastEnd, lastString = objects[-1]
-        prevObj, pOffset = self._script.findPreviousCaretInOrder(firstObj, firstStart)
-        nextObj, nOffset = self._script.findNextCaretInOrder(lastObj, lastEnd - 1)
+        prevObj, pOffset = self.findPreviousCaretInOrder(firstObj, firstStart)
+        nextObj, nOffset = self.findNextCaretInOrder(lastObj, lastEnd - 1)
         if not layoutMode:
             if firstString and not re.search("\w", firstString) \
                and (re.match("[^\w\s]", firstString[0]) or not firstString.strip()):
@@ -814,14 +1127,23 @@ class Utilities(script_utilities.Utilities):
                 onLeft = list(filter(_include, onLeft))
                 objects[0:0] = onLeft
 
-            char = self._script.getCharacterAtOffset(nextObj, nOffset)
-            if re.match("[^\w\s]", char):
-                objects.append([nextObj, nOffset, nOffset + 1, char])
+            text = self.queryNonEmptyText(nextObj)
+            if text:
+                char = text.getText(nOffset, nOffset + 1)
+                if re.match("[^\w\s]", char):
+                    objects.append([nextObj, nOffset, nOffset + 1, char])
+
+            if useCache:
+                self._currentLineContents = objects
 
             return objects
 
         # Check for things on the same line to the left of this object.
         while prevObj:
+            text = self.queryNonEmptyText(prevObj)
+            if text and text.getText(pOffset, pOffset + 1) in [" ", "\xa0"]:
+                prevObj, pOffset = self.findPreviousCaretInOrder(prevObj, pOffset)
+
             onLeft = self._getContentsForObj(prevObj, pOffset, boundary)
             onLeft = list(filter(_include, onLeft))
             if not onLeft:
@@ -832,12 +1154,14 @@ class Utilities(script_utilities.Utilities):
 
             objects[0:0] = onLeft
             firstObj, firstStart = objects[0][0], objects[0][1]
-            prevObj, pOffset = self._script.findPreviousCaretInOrder(firstObj, firstStart)
-            if self._script.getCharacterAtOffset(prevObj, pOffset) in [" ", "\xa0"]:
-                prevObj, pOffset = self._script.findPreviousCaretInOrder(prevObj, pOffset)
+            prevObj, pOffset = self.findPreviousCaretInOrder(firstObj, firstStart)
 
         # Check for things on the same line to the right of this object.
         while nextObj:
+            text = self.queryNonEmptyText(nextObj)
+            if text and text.getText(nOffset, nOffset + 1) in [" ", "\xa0"]:
+                nextObj, nOffset = self.findNextCaretInOrder(nextObj, nOffset)
+
             onRight = self._getContentsForObj(nextObj, nOffset, boundary)
             onRight = list(filter(_include, onRight))
             if not onRight:
@@ -845,9 +1169,10 @@ class Utilities(script_utilities.Utilities):
 
             objects.extend(onRight)
             lastObj, lastEnd = objects[-1][0], objects[-1][2]
-            nextObj, nOffset = self._script.findNextCaretInOrder(lastObj, lastEnd - 1)
-            if self._script.getCharacterAtOffset(nextObj, nOffset) in [" ", "\xa0"]:
-                nextObj, nOffset = self._script.findNextCaretInOrder(nextObj, nOffset)
+            nextObj, nOffset = self.findNextCaretInOrder(lastObj, lastEnd - 1)
+
+        if useCache:
+            self._currentLineContents = objects
 
         return objects
 
@@ -899,17 +1224,32 @@ class Utilities(script_utilities.Utilities):
            and not self.isTextBlockElement(obj):
             return True
 
+        if self.isGridDescendant(obj):
+            return True
+
         return False
 
     def isTextBlockElement(self, obj):
-        if not (obj and self._script.inDocumentContent(obj)):
+        if not obj:
             return False
 
-        textBlockElements = [pyatspi.ROLE_COLUMN_HEADER,
+        rv = self._isTextBlockElement.get(hash(obj))
+        if rv is not None:
+            return rv
+
+        role = obj.getRole()
+        state = obj.getState()
+
+        if not (obj and self.inDocumentContent(obj)):
+            return False
+
+        textBlockElements = [pyatspi.ROLE_CAPTION,
+                             pyatspi.ROLE_COLUMN_HEADER,
                              pyatspi.ROLE_DOCUMENT_FRAME,
+                             pyatspi.ROLE_DOCUMENT_WEB,
                              pyatspi.ROLE_FORM,
                              pyatspi.ROLE_HEADING,
-                             pyatspi.ROLE_LIST,
+                             pyatspi.ROLE_LABEL,
                              pyatspi.ROLE_LIST_ITEM,
                              pyatspi.ROLE_PANEL,
                              pyatspi.ROLE_PARAGRAPH,
@@ -918,22 +1258,21 @@ class Utilities(script_utilities.Utilities):
                              pyatspi.ROLE_TEXT,
                              pyatspi.ROLE_TABLE_CELL]
 
-        role = obj.getRole()
-        if not role in textBlockElements:
-            return False
-
-        state = obj.getState()
-        if state.contains(pyatspi.STATE_EDITABLE):
-            return False
-
-        if role == pyatspi.ROLE_DOCUMENT_FRAME:
-            return True
-
-        if not state.contains(pyatspi.STATE_FOCUSABLE) \
-           and not state.contains(pyatspi.STATE_FOCUSED):
-            return True
+        if not self.inDocumentContent(obj):
+            rv = False
+        elif not role in textBlockElements:
+            rv = False
+        elif state.contains(pyatspi.STATE_EDITABLE):
+            rv = False
+        elif role in [pyatspi.ROLE_DOCUMENT_FRAME, pyatspi.ROLE_DOCUMENT_WEB]:
+            rv = True
+        elif not state.contains(pyatspi.STATE_FOCUSABLE) and not state.contains(pyatspi.STATE_FOCUSED):
+            rv = True
+        else:
+            rv = False
 
-        return False
+        self._isTextBlockElement[hash(obj)] = rv
+        return rv
 
     def filterContentsForPresentation(self, contents, inferLabels=False):
         def _include(x):
@@ -942,11 +1281,15 @@ class Utilities(script_utilities.Utilities):
                 return False
 
             if (self.isTextBlockElement(obj) and not string.strip()) \
-               or self.isLabellingContents(x, contents) \
-               or self.isOffScreenLabel(obj, start):
+               or self.isAnchor(obj) \
+               or self.hasNoSize(obj) \
+               or self.isOffScreenLabel(obj) \
+               or self.isLabellingContents(x, contents):
                 return False
 
-            if inferLabels and self.isInferredLabelForContents(x, contents):
+            widget = self.isInferredLabelForContents(x, contents)
+            alwaysFilter = [pyatspi.ROLE_RADIO_BUTTON, pyatspi.ROLE_CHECK_BOX]
+            if widget and (inferLabels or widget.getRole() in alwaysFilter):
                 return False
 
             return True
@@ -966,136 +1309,50 @@ class Utilities(script_utilities.Utilities):
 
         return lastChar.isalnum()
 
-    def getObjectsFromEOCs(self, obj, offset=None, boundary=None):
-        """Expands the current object replacing EMBEDDED_OBJECT_CHARACTERS
-        with [obj, startOffset, endOffset, string] tuples.
-
-        Arguments
-        - obj: the object whose EOCs we need to expand into tuples
-        - offset: the character offset after which
-        - boundary: the pyatspi text boundary type
-
-        Returns a list of object tuples.
-        """
+    def supportsSelectionAndTable(self, obj):
+        interfaces = pyatspi.listInterfaces(obj)
+        return 'Table' in interfaces and 'Selection' in interfaces
 
-        if not obj:
-            return []
-
-        elif boundary and obj.getRole() == pyatspi.ROLE_TABLE:
-            if obj[0] and obj[0].getRole() in [pyatspi.ROLE_CAPTION,
-                                               pyatspi.ROLE_LIST]:
-                obj = obj[0]
-            else:
-                obj = obj.queryTable().getAccessibleAt(0, 0)
-
-            if not obj:
-                debug.printStack(debug.LEVEL_WARNING)
-                return []
-
-        objects = []
-        text = self.queryNonEmptyText(obj)
-        if text:
-            if offset == None:
-                offset = max(0, text.caretOffset)
-
-            if boundary:
-                [string, start, end] = self._getTextAtOffset(obj, offset, boundary)
-                if end == -1:
-                    end = text.characterCount
-            else:
-                start = offset
-                end = text.characterCount
-                string = text.getText(start, end)
-        else:
-            string = ""
-            start = 0
-            end = 1
-
-        unicodeText = string
-        objects.append([obj, start, end, unicodeText])
-
-        pattern = re.compile(self._script.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
-            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._script.getChildIndex(obj, childOffset)
-            child = obj[childIndex]
-            objects.extend(self.getObjectsFromEOCs(child, 0, boundary))
-
-            # Tack on the remainder of the original object, if any.
-            #
-            if end > childOffset + 1:
-                restOfText = unicodeText[offset:len(unicodeText)]
-                objects.append([obj, childOffset + 1, end, restOfText])
- 
-        if obj.getRole() in [pyatspi.ROLE_IMAGE, pyatspi.ROLE_TABLE, pyatspi.ROLE_TABLE_ROW]:
-            # 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. The same is true for tables.
-            #
-            toAdd = []
-            for child in obj:
-                toAdd.extend(self.getObjectsFromEOCs(child, 0, boundary))
-            if len(toAdd):
-                if self.isSameObject(objects[-1][0], obj):
-                    objects.pop()
-                objects.extend(toAdd)
-
-        return objects
-
-    def isOffScreenLabel(self, obj, offset=0):
+    def isGridDescendant(self, obj):
         if not obj:
             return False
 
-        isLabelFor = lambda x: x.getRelationType() == pyatspi.RELATION_LABEL_FOR
-        relations = list(filter(isLabelFor, obj.getRelationSet()))
-        if relations:
-            offset = max(offset, 0)
-            x, y, width, height = self.getExtents(obj, offset, offset + 1)
-            if x < 0 or y < 0:
-                return True
+        rv = self._isGridDescendant.get(hash(obj))
+        if rv is not None:
+            return rv
 
-        return False
+        rv = pyatspi.findAncestor(obj, self.supportsSelectionAndTable) is not None
+        self._isGridDescendant[hash(obj)] = rv
+        return rv
 
-    def shouldInferLabelFor(self, obj):
-        if self.displayedLabel(obj) or obj.name:
+    def isOffScreenLabel(self, obj):
+        if not (obj and self.inDocumentContent(obj)):
             return False
 
-        roles =  [pyatspi.ROLE_CHECK_BOX,
-                  pyatspi.ROLE_COMBO_BOX,
-                  pyatspi.ROLE_ENTRY,
-                  pyatspi.ROLE_LIST_BOX,
-                  pyatspi.ROLE_PASSWORD_TEXT,
-                  pyatspi.ROLE_RADIO_BUTTON]
-        if not obj.getRole() in roles:
-            return False
+        rv = self._isOffScreenLabel.get(hash(obj))
+        if rv is not None:
+            return rv
 
-        if not self._script.inDocumentContent():
-            return False
+        rv = False
+        isLabelFor = lambda x: x.getRelationType() == pyatspi.RELATION_LABEL_FOR
+        try:
+            relationSet = obj.getRelationSet()
+        except:
+            pass
+        else:
+            relations = list(filter(isLabelFor, relationSet))
+            if relations:
+                try:
+                    text = obj.queryText()
+                    end = text.characterCount
+                except:
+                    end = 1
+                x, y, width, height = self.getExtents(obj, 0, end)
+                if x < 0 or y < 0:
+                    rv = True
 
-        return True
+        self._isOffScreenLabel[hash(obj)] = rv
+        return rv
 
     def isInferredLabelForContents(self, content, contents):
         obj, start, end, string = content
@@ -1104,7 +1361,7 @@ class Utilities(script_utilities.Utilities):
             return None
 
         for o in objs:
-            label, sources = self._script.labelInference.infer(o, False)
+            label, sources = self.inferLabelFor(o)
             if obj in sources and label.strip() == string.strip():
                 return o
 
@@ -1130,55 +1387,172 @@ class Utilities(script_utilities.Utilities):
 
         return None
 
+    def isAnchor(self, obj):
+        if not (obj and self.inDocumentContent(obj)):
+            return False
+
+        rv = self._isAnchor.get(hash(obj))
+        if rv is not None:
+            return rv
+
+        rv = False
+        if obj.getRole() == pyatspi.ROLE_LINK \
+           and not obj.getState().contains(pyatspi.STATE_FOCUSABLE) \
+           and not 'Action' in pyatspi.listInterfaces(obj) \
+           and not self.queryNonEmptyText(obj):
+            rv = True
+
+        self._isAnchor[hash(obj)] = rv
+        return rv
+
     def isClickableElement(self, obj):
-        if not self._script.inDocumentContent(obj):
+        if not (obj and self.inDocumentContent(obj)):
             return False
 
-        # For Gecko, we want to identify things which are ONLY clickable.
-        # Things which are focusable, while technically "clickable", are
-        # easily discoverable (e.g. via role) and activatable (e.g. via
-        # pressing Space or Enter.
-        state = obj.getState()
-        if state.contains(pyatspi.STATE_FOCUSABLE):
+        rv = self._isClickableElement.get(hash(obj))
+        if rv is not None:
+            return rv
+
+        rv = False
+        if not obj.getState().contains(pyatspi.STATE_FOCUSABLE) \
+           and not self.isFocusModeWidget(obj):
+            try:
+                action = obj.queryAction()
+                names = [action.getName(i) for i in range(action.nActions)]
+            except NotImplementedError:
+                rv = False
+            else:
+                rv = "click" in names
+
+        self._isClickableElement[hash(obj)] = rv
+        return rv
+
+    def isLandmark(self, obj):
+        if not (obj and self.inDocumentContent(obj)):
             return False
 
-        try:
-            action = obj.queryAction()
-        except NotImplementedError:
+        rv = self._isLandmark.get(hash(obj))
+        if rv is not None:
+            return rv
+
+        if obj.getRole() == pyatspi.ROLE_LANDMARK:
+            rv = True
+        else:
+            try:
+                attrs = dict([attr.split(':', 1) for attr in obj.getAttributes()])
+            except:
+                attrs = {}
+            rv = attrs.get('xml-roles') in settings.ariaLandmarks
+
+        self._isLandmark[hash(obj)] = rv
+        return rv
+
+    def isLiveRegion(self, obj):
+        if not (obj and self.inDocumentContent(obj)):
             return False
 
-        for i in range(action.nActions):
-            if action.getName(i) in ["click"]:
-                return True
+        rv = self._isLiveRegion.get(hash(obj))
+        if rv is not None:
+            return rv
 
-        return False
+        try:
+            attrs = dict([attr.split(':', 1) for attr in obj.getAttributes()])
+        except:
+            attrs = {}
+
+        rv = 'container-live' in attrs
+        self._isLiveRegion[hash(obj)] = rv
+        return rv
+
+    def isLink(self, obj):
+        rv = self._isLink.get(hash(obj))
+        if rv is not None:
+            return rv
+
+        role = obj.getRole()
+        if role == pyatspi.ROLE_LINK and not self.isAnchor(obj):
+            rv = True
+        elif role == pyatspi.ROLE_TEXT \
+           and obj.parent.getRole() == pyatspi.ROLE_LINK \
+           and obj.name and obj.name == obj.parent.name:
+            rv = True
+
+        self._isLink[hash(obj)] = rv
+        return rv
 
     def hasLongDesc(self, obj):
-        if not self._script.inDocumentContent(obj):
+        if not (obj and self.inDocumentContent(obj)):
             return False
 
+        rv = self._hasLongDesc.get(hash(obj))
+        if rv is not None:
+            return rv
+
         try:
             action = obj.queryAction()
         except NotImplementedError:
+            rv = False
+        else:
+            names = [action.getName(i) for i in range(action.nActions)]
+            rv = "showlongdesc" in names
+
+        self._hasLongDesc[hash(obj)] = rv
+        return rv
+
+    def inferLabelFor(self, obj):
+        if not self.shouldInferLabelFor(obj):
+            return None, []
+
+        rv = self._inferredLabels.get(hash(obj))
+        if rv is not None:
+            return rv
+
+        rv = self._script.labelInference.infer(obj, False)
+        self._inferredLabels[hash(obj)] = rv
+        return rv
+
+    def shouldInferLabelFor(self, obj):
+        if obj.name:
             return False
 
-        for i in range(action.nActions):
-            if action.getName(i) in ["showlongdesc"]:
-                return True
+        if self._script.inSayAll():
+            return False
 
-        return False
+        if not self.inDocumentContent():
+            return False
+
+        role = obj.getRole()
+
+        # TODO - JD: This is private.
+        if self._script._lastCommandWasCaretNav \
+           and role not in [pyatspi.ROLE_RADIO_BUTTON, pyatspi.ROLE_CHECK_BOX]:
+            return False
+
+        roles =  [pyatspi.ROLE_CHECK_BOX,
+                  pyatspi.ROLE_COMBO_BOX,
+                  pyatspi.ROLE_ENTRY,
+                  pyatspi.ROLE_LIST_BOX,
+                  pyatspi.ROLE_PASSWORD_TEXT,
+                  pyatspi.ROLE_RADIO_BUTTON]
+        if role not in roles:
+            return False
+
+        if self.displayedLabel(obj):
+            return False
+
+        return True
 
     def eventIsAutocompleteNoise(self, event):
-        if not self._script.inDocumentContent(event.source):
+        if not self.inDocumentContent(event.source):
             return False
 
-        isListBoxItem = lambda x: x and x.parent.getRole() == pyatspi.ROLE_LIST_BOX
-        isMenuItem = lambda x: x and x.parent.getRole() == pyatspi.ROLE_MENU
-        isComboBoxItem = lambda x: x and x.parent.getRole() == pyatspi.ROLE_COMBO_BOX
+        isListBoxItem = lambda x: x and x.parent and x.parent.getRole() == pyatspi.ROLE_LIST_BOX
+        isMenuItem = lambda x: x and x.parent and x.parent.getRole() == pyatspi.ROLE_MENU
+        isComboBoxItem = lambda x: x and x.parent and x.parent.getRole() == pyatspi.ROLE_COMBO_BOX
 
         if event.source.getState().contains(pyatspi.STATE_EDITABLE) \
            and event.type.startswith("object:text-"):
-            obj, offset = self._script.getCaretContext()
+            obj, offset = self.getCaretContext()
             if isListBoxItem(obj) or isMenuItem(obj):
                 return True
 
@@ -1193,7 +1567,7 @@ class Utilities(script_utilities.Utilities):
         if not event.type.startswith("object:text-"):
             return False
 
-        if not self._script.inDocumentContent(event.source) \
+        if not self.inDocumentContent(event.source) \
            or not event.source.getState().contains(pyatspi.STATE_EDITABLE) \
            or not event.source == orca_state.locusOfFocus:
             return False
@@ -1211,7 +1585,7 @@ class Utilities(script_utilities.Utilities):
         return self._treatTextObjectAsWhole(event.source)
 
     def eventIsEOCAdded(self, event):
-        if not self._script.inDocumentContent(event.source):
+        if not self.inDocumentContent(event.source):
             return False
 
         if event.type.startswith("object:text-changed:insert"):
@@ -1229,3 +1603,302 @@ class Utilities(script_utilities.Utilities):
             return True
 
         return False
+
+    @staticmethod
+    def getHyperlinkRange(obj):
+        try:
+            hyperlink = obj.queryHyperlink()
+            start, end = hyperlink.startIndex, hyperlink.endIndex
+        except:
+            return -1, -1
+
+        return start, end
+
+    def characterOffsetInParent(self, obj):
+        start, end, length = self._rangeInParentWithLength(obj)
+        return start
+
+    def _rangeInParentWithLength(self, obj):
+        if not obj:
+            return -1, -1, 0
+
+        text = self.queryNonEmptyText(obj.parent)
+        if not text:
+            return -1, -1, 0
+
+        start, end = self.getHyperlinkRange(obj)
+        return start, end, text.characterCount
+
+    @staticmethod
+    def getChildIndex(obj, offset):
+        try:
+            hypertext = obj.queryHypertext()
+        except:
+            return -1
+
+        return hypertext.getLinkIndex(offset)
+
+    def getChildAtOffset(self, obj, offset):
+        index = self.getChildIndex(obj, offset)
+        if index == -1:
+            return None
+
+        try:
+            child = obj[index]
+        except:
+            return None
+
+        return child
+
+    def hasNoSize(self, obj):
+        if not (obj and self.inDocumentContent(obj)):
+            return False
+
+        rv = self._hasNoSize.get(hash(obj))
+        if rv is not None:
+            return rv
+
+        try:
+            extents = obj.queryComponent().getExtents(0)
+        except:
+            rv = True
+        else:
+            rv = not (extents.width and extents.height)
+
+        self._hasNoSize[hash(obj)] = rv
+        return rv
+
+    def doNotDescendForCaret(self, obj):
+        if not obj or self.isZombie(obj):
+            return True
+
+        if self.isHidden(obj) or self.isOffScreenLabel(obj):
+            return True
+
+        if self.isTextBlockElement(obj):
+            return False
+
+        doNotDescend = [pyatspi.ROLE_COMBO_BOX,
+                        pyatspi.ROLE_LIST_BOX,
+                        pyatspi.ROLE_MENU_BAR,
+                        pyatspi.ROLE_MENU,
+                        pyatspi.ROLE_MENU_ITEM,
+                        pyatspi.ROLE_PUSH_BUTTON,
+                        pyatspi.ROLE_TOGGLE_BUTTON,
+                        pyatspi.ROLE_TOOL_BAR,
+                        pyatspi.ROLE_TREE,
+                        pyatspi.ROLE_TREE_TABLE]
+        return obj.getRole() in doNotDescend
+
+    def _searchForCaretContext(self, obj):
+        context = [None, -1]
+        while obj:
+            try:
+                offset = obj.queryText().caretOffset
+            except:
+                obj = None
+            else:
+                context = [obj, offset]
+                childIndex = self.getChildIndex(obj, offset)
+                if childIndex >= 0 and obj.childCount:
+                    obj = obj[childIndex]
+                else:
+                    break
+
+        return context
+
+    def _getCaretContextViaLocusOfFocus(self):
+        obj = orca_state.locusOfFocus
+        try:
+            offset = obj.queryText().caretOffset
+        except NotImplementedError:
+            offset = 0
+        except:
+            offset = -1
+
+        return obj, offset
+
+    def getCaretContext(self, documentFrame=None):
+        documentFrame = documentFrame or self.documentFrame()
+        if not documentFrame:
+            return self._getCaretContextViaLocusOfFocus()
+
+        context = self._caretContexts.get(hash(documentFrame.parent))
+        if context:
+            return context
+
+        obj, offset = self._searchForCaretContext(documentFrame)
+        obj, offset = self.findNextCaretInOrder(obj, max(-1, offset - 1))
+        self.setCaretContext(obj, offset, documentFrame)
+
+        return obj, offset
+
+    def clearCaretContext(self, documentFrame=None):
+        self.clearContentCache()
+        documentFrame = documentFrame or self.documentFrame()
+        if not documentFrame:
+            return
+
+        parent = documentFrame.parent
+        self._caretContexts.pop(hash(parent), None)
+
+    def setCaretContext(self, obj=None, offset=-1, documentFrame=None):
+        documentFrame = documentFrame or self.documentFrame()
+        if not documentFrame:
+            return
+
+        parent = documentFrame.parent
+        self._caretContexts[hash(parent)] = obj, offset
+
+    def findFirstCaretContext(self, obj, offset):
+        try:
+            role = obj.getRole()
+        except:
+            return None, -1
+
+        lookInChild = [pyatspi.ROLE_LIST,
+                       pyatspi.ROLE_TABLE,
+                       pyatspi.ROLE_TABLE_ROW]
+        if role in lookInChild and obj.childCount:
+            return self.findFirstCaretContext(obj[0], 0)
+
+        text = self.queryNonEmptyText(obj)
+        if not text:
+            return obj, 0
+
+        if offset >= text.characterCount:
+            return obj, text.characterCount
+
+        allText = text.getText(0, -1)
+        offset = max (0, offset)
+        if allText[offset] != self.EMBEDDED_OBJECT_CHARACTER:
+            return obj, offset
+
+        child = self.getChildAtOffset(obj, offset)
+        if not child:
+            return None, -1
+
+        return self.findFirstCaretContext(child, 0)
+
+    def findNextCaretInOrder(self, obj=None, offset=-1):
+        if not obj:
+            obj, offset = self.getCaretContext()
+
+        if not obj or not self.inDocumentContent(obj):
+            return None, -1
+
+        if not (self.isHidden(obj) or self.isOffScreenLabel(obj)):
+            text = self.queryNonEmptyText(obj)
+            if text:
+                allText = text.getText(0, -1)
+                for i in range(offset + 1, len(allText)):
+                    child = self.getChildAtOffset(obj, i)
+                    if child:
+                        return self.findNextCaretInOrder(child, -1)
+                    if allText[i] != self.EMBEDDED_OBJECT_CHARACTER:
+                        return obj, i
+            elif obj.childCount and not self.doNotDescendForCaret(obj):
+                return self.findNextCaretInOrder(obj[0], -1)
+            elif offset < 0 and not self.isTextBlockElement(obj) and not self.hasNoSize(obj):
+                return obj, 0
+
+        # If we're here, start looking up the the tree, up to the document.
+        documentFrame = self.documentFrame()
+        if self.isSameObject(obj, documentFrame):
+            return None, -1
+
+        while obj.parent and obj != obj.parent:
+            start, end, length = self._rangeInParentWithLength(obj)
+            if start + 1 == end and 0 <= start < end <= length:
+                return self.findNextCaretInOrder(obj.parent, start)
+
+            index = obj.getIndexInParent() + 1
+            if 0 <= index < obj.parent.childCount:
+                return self.findNextCaretInOrder(obj.parent[index], -1)
+            obj = obj.parent
+
+        return None, -1
+
+    def findPreviousCaretInOrder(self, obj=None, offset=-1):
+        if not obj:
+            obj, offset = self.getCaretContext()
+
+        if not obj or not self.inDocumentContent(obj):
+            return None, -1
+
+        if not (self.isHidden(obj) or self.isOffScreenLabel(obj)):
+            text = self.queryNonEmptyText(obj)
+            if text:
+                allText = text.getText(0, -1)
+                if offset == -1 or offset > len(allText):
+                    offset = len(allText)
+                for i in range(offset - 1, -1, -1):
+                    child = self.getChildAtOffset(obj, i)
+                    if child:
+                        return self.findPreviousCaretInOrder(child, -1)
+                    if allText[i] != self.EMBEDDED_OBJECT_CHARACTER:
+                        return obj, i
+            elif obj.childCount and not self.doNotDescendForCaret(obj):
+                return self.findPreviousCaretInOrder(obj[obj.childCount - 1], -1)
+            elif offset < 0 and not self.isTextBlockElement(obj) and not self.hasNoSize(obj):
+                return obj, 0
+
+        # If we're here, start looking up the the tree, up to the document.
+        documentFrame = self.documentFrame()
+        if self.isSameObject(obj, documentFrame):
+            return None, -1
+
+        while obj.parent and obj != obj.parent:
+            start, end, length = self._rangeInParentWithLength(obj)
+            if start + 1 == end and 0 <= start < end <= length:
+                return self.findPreviousCaretInOrder(obj.parent, start)
+
+            index = obj.getIndexInParent() - 1
+            if 0 <= index < obj.parent.childCount:
+                return self.findPreviousCaretInOrder(obj.parent[index], -1)
+            obj = obj.parent
+
+        return None, -1
+
+    def handleAsLiveRegion(self, event):
+        if not _settingsManager.getSetting('inferLiveRegions'):
+            return False
+
+        return self.isLiveRegion(event.source)
+
+    def getPageSummary(self, obj):
+        docframe = self.documentFrame(obj)
+        col = docframe.queryCollection()
+        headings = 0
+        forms = 0
+        tables = 0
+        vlinks = 0
+        uvlinks = 0
+        percentRead = None
+
+        stateset = pyatspi.StateSet()
+        roles = [pyatspi.ROLE_HEADING, pyatspi.ROLE_LINK, pyatspi.ROLE_TABLE,
+                 pyatspi.ROLE_FORM]
+        rule = col.createMatchRule(stateset.raw(), col.MATCH_NONE,
+                                   "", col.MATCH_NONE,
+                                   roles, col.MATCH_ANY,
+                                   "", col.MATCH_NONE,
+                                   False)
+
+        matches = col.getMatches(rule, col.SORT_ORDER_CANONICAL, 0, True)
+        col.freeMatchRule(rule)
+        for obj in matches:
+            role = obj.getRole()
+            if role == pyatspi.ROLE_HEADING:
+                headings += 1
+            elif role == pyatspi.ROLE_FORM:
+                forms += 1
+            elif role == pyatspi.ROLE_TABLE and not self.isLayoutOnly(obj):
+                tables += 1
+            elif role == pyatspi.ROLE_LINK:
+                if obj.getState().contains(pyatspi.STATE_VISITED):
+                    vlinks += 1
+                else:
+                    uvlinks += 1
+
+        return [headings, forms, tables, vlinks, uvlinks, percentRead]
diff --git a/src/orca/scripts/toolkits/Gecko/speech_generator.py 
b/src/orca/scripts/toolkits/Gecko/speech_generator.py
index 67bafb1..7bebe5c 100644
--- a/src/orca/scripts/toolkits/Gecko/speech_generator.py
+++ b/src/orca/scripts/toolkits/Gecko/speech_generator.py
@@ -1,7 +1,8 @@
 # Orca
 #
 # Copyright 2005-2009 Sun Microsystems Inc.
-# Copyright 2010 Orca Team.
+# Copyright 2010-2011 Orca Team
+# Copyright 2011-2015 Igalia, S.L.
 #
 # This library is free software; you can redistribute it and/or
 # modify it under the terms of the GNU Lesser General Public
@@ -18,169 +19,174 @@
 # Free Software Foundation, Inc., Franklin Street, Fifth Floor,
 # Boston MA  02110-1301 USA.
 
-"""Custom script for Gecko toolkit.
-Please refer to the following URL for more information on the AT-SPI
-implementation in Gecko:
-http://developer.mozilla.org/en/docs/Accessibility/ATSPI_Support
-"""
-
 __id__        = "$Id$"
 __version__   = "$Revision$"
 __date__      = "$Date$"
-__copyright__ = "Copyright (c) 2010 Orca Team."
+__copyright__ = "Copyright (c) 2005-2009 Sun Microsystems Inc." \
+                "Copyright (c) 2010-2011 Orca Team" \
+                "Copyright (c) 2011-2015 Igalia, S.L."
 __license__   = "LGPL"
 
 import pyatspi
+import urllib
 
-import orca.messages as messages
-import orca.object_properties as object_properties
-import orca.orca_state as orca_state
-import orca.settings_manager as settings_manager
-import orca.speech_generator as speech_generator
+from orca import debug
+from orca import messages
+from orca import object_properties
+from orca import orca_state
+from orca import settings_manager
+from orca import speech_generator
 
 _settingsManager = settings_manager.getManager()
 
-########################################################################
-#                                                                      #
-# Custom SpeechGenerator                                               #
-#                                                                      #
-########################################################################
 
 class SpeechGenerator(speech_generator.SpeechGenerator):
-    """Provides a speech generator specific to Gecko.
-    """
-
-    # pylint: disable-msg=W0142
 
     def __init__(self, script):
-        speech_generator.SpeechGenerator.__init__(self, script)
-
-    def _getACSS(self, obj, string):
-        if obj.getRole() == pyatspi.ROLE_LINK:
-            acss = self.voice(speech_generator.HYPERLINK)
-        elif isinstance(string, str) \
-            and string.isupper() \
-            and string.strip().isalpha():
-            acss = self.voice(speech_generator.UPPERCASE)
-        else:
-            acss = self.voice(speech_generator.DEFAULT)
+        super().__init__(script)
 
-        return acss
+    def _generateAncestors(self, obj, **args):
+        if not self._script.utilities.inDocumentContent(obj):
+            return super()._generateAncestors(obj, **args)
 
-    def _generateName(self, obj, **args):
-        result = []
-        acss = self.voice(speech_generator.DEFAULT)
         role = args.get('role', obj.getRole())
-        if role == pyatspi.ROLE_DOCUMENT_FRAME \
-           and obj.getState().contains(pyatspi.STATE_EDITABLE):
+        if role == pyatspi.ROLE_LINK:
             return []
 
-        result.extend(speech_generator.SpeechGenerator._generateName(
-                              self, obj, **args))
-        if not result and role == pyatspi.ROLE_LIST_ITEM:
-            result.append(self._script.utilities.expandEOCs(obj))
-            result.extend(acss)
+        if self._script.utilities.isLandmark(obj):
+            return []
 
-        acss = self.voice(speech_generator.HYPERLINK)
-        link = None
-        if role == pyatspi.ROLE_LINK:
-            link = obj
-        elif role == pyatspi.ROLE_IMAGE and not result:
-            link = self._script.utilities.ancestorWithRole(
-                obj, [pyatspi.ROLE_LINK], [pyatspi.ROLE_DOCUMENT_FRAME])
-        if link and (not result or len(result[0].strip()) == 0):
-            # If there's no text for the link, expose part of the
-            # URI to the user.
-            #
-            basename = self._script.utilities.linkBasename(link)
-            if basename:
-                result.append(basename)
-                result.extend(acss)
+        args['stopAtRoles'] = [pyatspi.ROLE_DOCUMENT_FRAME,
+                               pyatspi.ROLE_DOCUMENT_WEB,
+                               pyatspi.ROLE_EMBEDDED,
+                               pyatspi.ROLE_INTERNAL_FRAME,
+                               pyatspi.ROLE_FORM,
+                               pyatspi.ROLE_MENU_BAR,
+                               pyatspi.ROLE_TOOL_BAR]
+        args['skipRoles'] = [pyatspi.ROLE_PARAGRAPH,
+                             pyatspi.ROLE_LIST_ITEM,
+                             pyatspi.ROLE_TEXT]
 
-        return result
+        return super()._generateAncestors(obj, **args)
+
+    def _generateAllTextSelection(self, obj, **args):
+        if self._script.utilities.isZombie(obj) \
+           or obj != orca_state.locusOfFocus:
+            return []
+
+        # TODO - JD: These (and the default script's) need to
+        # call utility methods rather than generate it.
+        return super()._generateAllTextSelection(obj, **args)
+
+    def _generateAnyTextSelection(self, obj, **args):
+        if self._script.utilities.isZombie(obj) \
+           or obj != orca_state.locusOfFocus:
+            return []
+
+        # TODO - JD: These (and the default script's) need to
+        # call utility methods rather than generate it.
+        return super()._generateAnyTextSelection(obj, **args)
+
+    def _generateClickable(self, obj, **args):
+        if not self._script.utilities.inDocumentContent(obj):
+            return []
+
+        if not args.get('mode', None):
+            args['mode'] = self._mode
+
+        args['stringType'] = 'clickable'
+        if self._script.utilities.isClickableElement(obj):
+            return [self._script.formatting.getString(**args)]
+
+        return []
 
     def _generateDescription(self, obj, **args):
-        """Returns an array of strings (and possibly voice and audio
-        specifications) that represent the description of the object,
-        if that description is different from that of the name and
-        label.
-        """
-        if not obj == orca_state.locusOfFocus:
+        if self._script.utilities.isZombie(obj) \
+           or obj != orca_state.locusOfFocus:
             return []
 
         formatType = args.get('formatType')
+        if formatType == 'basicWhereAmI' and self._script.utilities.isLiveRegion(obj):
+            return self._script.liveMngr.generateLiveRegionDescription(obj, **args)
+
         role = args.get('role', obj.getRole())
         if role == pyatspi.ROLE_TEXT and formatType != 'basicWhereAmI':
             return []
 
-        return speech_generator.SpeechGenerator._generateDescription(
-            self, obj, **args)
+        return super()._generateDescription(obj, **args)
 
-    def _generateLabel(self, obj, **args):
-        start = args.get('startOffset')
-        end = args.get('endOffset')
-        if isinstance(start, int) and isinstance(end, int) \
-           and not self._script.utilities.justEnteredObject(obj, start, end):
+    def _generateHasLongDesc(self, obj, **args):
+        if not self._script.utilities.inDocumentContent(obj):
             return []
 
-        acss = self.voice(speech_generator.DEFAULT)
-        result = speech_generator.SpeechGenerator._generateLabel(self,
-                                                                 obj,
-                                                                 **args)
-
-        if self._script.utilities.shouldInferLabelFor(obj):
-            label, objects = self._script.labelInference.infer(obj, False)
-            if label:
-                result.append(label)
-                result.extend(acss)
+        if not args.get('mode', None):
+            args['mode'] = self._mode
 
-        # XUL combo boxes don't always have a label for/by
-        # relationship.  But, they will make their names be
-        # the string of the thing labelling them.
-        #
-        role = args.get('role', obj.getRole())
-        if not len(result) \
-           and role == pyatspi.ROLE_COMBO_BOX \
-           and not self._script.inDocumentContent():
-            result.append(obj.name)
-            result.extend(acss)
+        args['stringType'] = 'haslongdesc'
+        if self._script.utilities.hasLongDesc(obj):
+            return [self._script.formatting.getString(**args)]
 
-        return result
+        return []
 
     def _generateLabelOrName(self, obj, **args):
         if self._script.utilities.isTextBlockElement(obj):
             return []
 
-        start = args.get('startOffset')
-        end = args.get('endOffset')
-        if isinstance(start, int) and isinstance(end, int) \
-           and not self._script.utilities.justEnteredObject(obj, start, end):
+        return super()._generateLabelOrName(obj, **args)
+
+    def _generateLabel(self, obj, **args):
+        if self._script.utilities.isTextBlockElement(obj):
             return []
 
-        result = speech_generator.SpeechGenerator._generateLabelOrName(
-            self, obj, **args)
+        label, objects = self._script.utilities.inferLabelFor(obj)
+        if label:
+            result = [label]
+            result.extend(self.voice(speech_generator.DEFAULT))
+            return result
 
-        if not result and obj.parent.getRole() == pyatspi.ROLE_AUTOCOMPLETE:
-            result = self._generateLabelOrName(obj.parent, **args)
+        return super()._generateLabel(obj, **args)
 
+    def _generateNewNodeLevel(self, obj, **args):
+        if self._script.utilities.isTextBlockElement(obj) \
+           or self._script.utilities.isLink(obj):
+            return []
+
+        return super()._generateNewNodeLevel(obj, **args)
+
+    def _generateNewRadioButtonGroup(self, obj, **args):
+        # TODO - JD: Looking at the default speech generator's method, this
+        # is all kinds of broken. Until that can be sorted out, try to filter
+        # out some of the noise....
+        return []
+
+    def _generateNumberOfChildren(self, obj, **args):
+        if _settingsManager.getSetting('onlySpeakDisplayedText'):
+            return []
+
+        role = args.get('role', obj.getRole())
+        if role not in [pyatspi.ROLE_LIST, pyatspi.ROLE_LIST_BOX] \
+           or not self._script.utilities.inDocumentContent(obj):
+            return super()._generateNumberOfChildren(obj, **args)
+
+        result = [messages.listItemCount(obj.childCount)]
+        result.extend(self.voice(speech_generator.SYSTEM))
         return result
 
+    # TODO - JD: Yet another dumb generator method we should kill.
+    def _generateTextRole(self, obj, **args):
+        return self._generateRoleName(obj, **args)
+
     def _generateRoleName(self, obj, **args):
-        """Prevents some roles from being spoken."""
+        if not self._script.utilities.inDocumentContent(obj):
+            return super()._generateRoleName(obj, **args)
+
         result = []
         acss = self.voice(speech_generator.SYSTEM)
         role = args.get('role', obj.getRole())
         force = args.get('force', False)
+
         start = args.get('startOffset')
         end = args.get('endOffset')
-        if isinstance(start, int) and isinstance(end, int) \
-           and not self._script.utilities.justEnteredObject(obj, start, end) \
-           and not self._script.utilities.isTextBlockElement(obj) \
-           and not self._script.utilities.isLink(obj):
-            return []
-        if role == pyatspi.ROLE_DOCUMENT_FRAME \
-           and obj.getState().contains(pyatspi.STATE_EDITABLE):
-            return []
 
         if not force:
             doNotSpeak = [pyatspi.ROLE_FORM,
@@ -190,141 +196,73 @@ class SpeechGenerator(speech_generator.SpeechGenerator):
                           pyatspi.ROLE_SECTION,
                           pyatspi.ROLE_UNKNOWN]
         else:
-            # We never ever want to speak 'unknown'
-            #
             doNotSpeak = [pyatspi.ROLE_UNKNOWN]
 
-        if not force and self._script.inDocumentContent(obj):
+        if not force:
             doNotSpeak.append(pyatspi.ROLE_TABLE_CELL)
             doNotSpeak.append(pyatspi.ROLE_TEXT)
             if args.get('formatType', 'unfocused') != 'basicWhereAmI':
                 doNotSpeak.append(pyatspi.ROLE_LIST_ITEM)
                 doNotSpeak.append(pyatspi.ROLE_LIST)
-            if args.get('startOffset') != None and args.get('endOffset') != None:
+            if (start or end):
                 doNotSpeak.append(pyatspi.ROLE_DOCUMENT_FRAME)
                 doNotSpeak.append(pyatspi.ROLE_ALERT)
 
-        if not (role in doNotSpeak):
-            if role == pyatspi.ROLE_IMAGE:
+        if obj.getState().contains(pyatspi.STATE_EDITABLE):
+            lastKey, mods = self._script.utilities.lastKeyAndModifiers()
+            if ((lastKey in ["Down", "Right"] and not mods) or self._script.inSayAll()) and start:
+                return []
+            if lastKey in ["Up", "Left"] and not mods:
+                text = self._script.utilities.queryNonEmptyText(obj)
+                if text and end not in [None, text.characterCount]:
+                    return []
+            if role not in doNotSpeak:
                 result.append(self.getLocalizedRoleName(obj, role))
                 result.extend(acss)
-                link = self._script.utilities.ancestorWithRole(
-                    obj, [pyatspi.ROLE_LINK], [pyatspi.ROLE_DOCUMENT_FRAME])
-                if link:
-                    result.append(self.getLocalizedRoleName(link))
-                    result.extend(acss)
-
-            elif role == pyatspi.ROLE_HEADING:
-                level = self._script.utilities.headingLevel(obj)
-                if level:
-                    result.append(object_properties.ROLE_HEADING_LEVEL_SPEECH % {
-                        'role': self.getLocalizedRoleName(obj, role),
-                        'level': level})
-                    result.extend(acss)
-                else:
-                    result.append(self.getLocalizedRoleName(obj, role))
-                    result.extend(acss)
-
-            elif role == pyatspi.ROLE_LINK:
-                if obj.parent.getRole() == pyatspi.ROLE_IMAGE:
-                    result.append(messages.IMAGE_MAP_LINK)
-                    result.extend(acss)
-                else:
-                    result.append(self.getLocalizedRoleName(obj, role))
-                    result.extend(acss)
-                    if obj.childCount and obj[0].getRole() == pyatspi.ROLE_IMAGE:
-                        result.append(self.getLocalizedRoleName(obj[0]))
-                        result.extend(acss)
+
+        elif role == pyatspi.ROLE_HEADING:
+            level = self._script.utilities.headingLevel(obj)
+            if level:
+                result.append(object_properties.ROLE_HEADING_LEVEL_SPEECH % {
+                    'role': self.getLocalizedRoleName(obj, role),
+                    'level': level})
+                result.extend(acss)
             else:
                 result.append(self.getLocalizedRoleName(obj, role))
                 result.extend(acss)
 
-        return result
-
-    def _generateExpandedEOCs(self, obj, **args):
-        """Returns the expanded embedded object characters for an object."""
-        result = []
-
-        startOffset = args.get('startOffset', 0)
-        endOffset = args.get('endOffset', -1)
-        text = self._script.utilities.expandEOCs(obj, startOffset, endOffset)
-        if text:
-            result.append(text)
-        return result
-
-    def _generateNumberOfChildren(self, obj, **args):
-        if _settingsManager.getSetting('onlySpeakDisplayedText'):
-            return []
+        elif role == pyatspi.ROLE_LINK:
+            if obj.parent.getRole() == pyatspi.ROLE_IMAGE:
+                result.append(messages.IMAGE_MAP_LINK)
+                result.extend(acss)
+            else:
+                result.append(self.getLocalizedRoleName(obj, role))
+                result.extend(acss)
 
-        result = []
-        acss = self.voice(speech_generator.SYSTEM)
-        role = args.get('role', obj.getRole())
-        if role in [pyatspi.ROLE_LIST, pyatspi.ROLE_LIST_BOX]:
-            result.append(messages.listItemCount(obj.childCount))
+        elif role not in doNotSpeak:
+            result.append(self.getLocalizedRoleName(obj, role))
             result.extend(acss)
-        else:
-            result.extend(
-                speech_generator.SpeechGenerator._generateNumberOfChildren(
-                    self, obj, **args))
-        return result
 
-    def _generateNewAncestors(self, obj, **args):
-        # TODO - JD: This is not the right way to do this, but we can fix
-        # that as part of the removal of formatting strings.
-        start = args.get('startOffset')
-        end = args.get('endOffset')
-        if start != None or end != None:
-            return []
-
-        return speech_generator.SpeechGenerator._generateNewAncestors(
-            self, obj, **args)
+        index = args.get('index', 0)
+        total = args.get('total', 1)
+        ancestorRoles = [pyatspi.ROLE_HEADING, pyatspi.ROLE_LINK]
+        if index == total - 1 \
+           and (role == pyatspi.ROLE_IMAGE or self._script.utilities.queryNonEmptyText(obj)):
+            speakRoles = lambda x: x and x.getRole() in ancestorRoles
+            ancestor = pyatspi.findAncestor(obj, speakRoles)
+            if ancestor and ancestor.getRole() != role:
+                result.extend(self._generateRoleName(ancestor))
 
-    def _generateAncestors(self, obj, **args):
-        role = args.get('role', obj.getRole())
-        if role == pyatspi.ROLE_LINK:
-            return []
-
-        args['stopAtRoles'] = [pyatspi.ROLE_DOCUMENT_FRAME,
-                               pyatspi.ROLE_EMBEDDED,
-                               pyatspi.ROLE_INTERNAL_FRAME,
-                               pyatspi.ROLE_FORM,
-                               pyatspi.ROLE_MENU_BAR,
-                               pyatspi.ROLE_TOOL_BAR]
-        args['skipRoles'] = [pyatspi.ROLE_PARAGRAPH,
-                             pyatspi.ROLE_LIST_ITEM,
-                             pyatspi.ROLE_TABLE_ROW,
-                             pyatspi.ROLE_TEXT]
-
-        return speech_generator.SpeechGenerator._generateAncestors(
-            self, obj, **args)
+        return result
 
-    def _generateDefaultButton(self, obj, **args):
-        """Returns an array of strings (and possibly voice and audio
-        specifications) that represent the default button in a dialog.
-        This method should initially be called with a top-level window.
-        """
-        if self._script.inDocumentContent(obj):
+    def _generatePageSummary(self, obj, **args):
+        if not self._script.utilities.inDocumentContent(obj):
             return []
 
-        return speech_generator.SpeechGenerator.\
-                     _generateDefaultButton(self, obj, **args)
-
-    def _generateLiveRegionDescription(self, obj, **args):
-        """Returns an array of strings (and possibly voice and audio
-        specifications) that represent the live region.
-        """
-        return self._script.liveMngr.\
-                    generateLiveRegionDescription(obj, **args)
-
-    def _generatePageSummary(self, obj, **args):
-        """Returns an array of strings (and possibly voice and audio
-        specifications) that summarize the objects found on the page
-        containing obj.
-        """
         result = []
         acss = self.voice(speech_generator.DEFAULT)
         headings, forms, tables, vlinks, uvlinks, percent = \
-            self._script.getPageSummary(obj)
+            self._script.utilities.getPageSummary(obj)
         if headings:
             result.append(messages.headingCount(headings))
         if forms:
@@ -342,57 +280,83 @@ class SpeechGenerator(speech_generator.SpeechGenerator):
             result.extend(acss)
         return result
 
-    def generateSpeech(self, obj, **args):
+    def _generateSiteDescription(self, obj, **args):
+        if not self._script.utilities.inDocumentContent(obj):
+            return []
+
+        link_uri = self._script.utilities.uri(obj)
+        if not link_uri:
+            return []
+
+        link_uri_info = urllib.parse.urlparse(link_uri)
+        doc_uri = self._script.utilities.documentFrameURI()
+        if not doc_uri:
+            return []
+
         result = []
-        # Detailed WhereAmI should always be a page summary if we
-        # are in document content.
-        #
-        if args.get('formatType', 'unfocused') == 'detailedWhereAmI' \
-           and self._script.inDocumentContent(obj):
-            oldRole = self._overrideRole('default', args)
-            result.extend(speech_generator.SpeechGenerator.\
-                                           generateSpeech(self, obj, **args))
-            self._restoreRole(oldRole, args)
-        elif self._script.utilities.isLink(obj):
-            oldRole = self._overrideRole(pyatspi.ROLE_LINK, args)
-            result.extend(speech_generator.SpeechGenerator.\
-                                           generateSpeech(self, obj, **args))
-            self._restoreRole(oldRole, args)
+        doc_uri_info = urllib.parse.urlparse(doc_uri)
+        if link_uri_info[1] == doc_uri_info[1]:
+            if link_uri_info[2] == doc_uri_info[2]:
+                result.append(messages.LINK_SAME_PAGE)
+            else:
+                result.append(messages.LINK_SAME_SITE)
         else:
-            result.extend(speech_generator.SpeechGenerator.\
-                                           generateSpeech(self, obj, **args))
+            linkdomain = link_uri_info[1].split('.')
+            docdomain = doc_uri_info[1].split('.')
+            if len(linkdomain) > 1 and len(docdomain) > 1  \
+               and linkdomain[-1] == docdomain[-1]  \
+               and linkdomain[-2] == docdomain[-2]:
+                result.append(messages.LINK_SAME_SITE)
+            else:
+                result.append(messages.LINK_DIFFERENT_SITE)
+
+        if result:
+            result.extend(self.voice(speech_generator.HYPERLINK))
+
         return result
 
+    def _generateExpandedEOCs(self, obj, **args):
+        if not self._script.utilities.inDocumentContent(obj):
+            return super()._generateExpandedEOCs(obj, **args)
+
+        result = []
+        startOffset = args.get('startOffset', 0)
+        endOffset = args.get('endOffset', -1)
+        text = self._script.utilities.expandEOCs(obj, startOffset, endOffset)
+        if text:
+            result.append(text)
+        return result
+
+    # TODO - JD: more crap to move to default and utilities....
     def getAttribute(self, obj, attributeName):
         attributes = obj.getAttributes()
         for attribute in attributes:
             if attribute.startswith(attributeName):
                 return attribute.split(":")[1]
 
-    def _generateNewNodeLevel(self, obj, **args):
-        if self._script.utilities.isTextBlockElement(obj):
-            return []
-
-        return speech_generator.SpeechGenerator._generateNewNodeLevel(
-            self, obj, **args)
-
     def _generatePositionInList(self, obj, **args):
-        if _settingsManager.getSetting('onlySpeakDisplayedText') \
-           or not (_settingsManager.getSetting('enablePositionSpeaking') \
-                   or args.get('forceList', False)):
+        if _settingsManager.getSetting('onlySpeakDisplayedText'):
             return []
 
-        if self._script.utilities.isTextBlockElement(obj):
+        if not args.get('forceList', False) \
+           and not _settingsManager.getSetting('enablePositionSpeaking'):
             return []
 
+        # TODO - JD: We cannot do this for XUL (or whatever Firefox is
+        # using in its non-webcontent dialogs)
+        #if not self._script.utilities.inDocumentContent(obj):
+        #    return super()._generatePositionInList(obj, **args)
         menuRoles = [pyatspi.ROLE_MENU_ITEM,
+                     pyatspi.ROLE_TEAROFF_MENU_ITEM,
                      pyatspi.ROLE_CHECK_MENU_ITEM,
                      pyatspi.ROLE_RADIO_MENU_ITEM,
-                     pyatspi.ROLE_MENU,
-                     pyatspi.ROLE_COMBO_BOX]
+                     pyatspi.ROLE_MENU]
         if obj.getRole() in menuRoles:
             return super()._generatePositionInList(obj, **args)
 
+        if self._script.utilities.isTextBlockElement(obj):
+            return []
+
         position = self.getAttribute(obj, "posinset")
         total = self.getAttribute(obj, "setsize")
         if position is None or total is None:
@@ -412,67 +376,41 @@ class SpeechGenerator(speech_generator.SpeechGenerator):
         result.extend(self.voice(speech_generator.SYSTEM))
         return result
 
-    def _generateNewRadioButtonGroup(self, obj, **args):
-        # TODO - JD: Looking at the default speech generator's method, this
-        # is all kinds of broken. Until that can be sorted out, try to filter
-        # out some of the noise....
-        return []
-
-    def _generateAnyTextSelection(self, obj, **args):
-        if not obj == orca_state.locusOfFocus:
-            return []
-
-        return speech_generator.SpeechGenerator._generateAnyTextSelection(
-            self, obj, **args)
-
-    def _generateAllTextSelection(self, obj, **args):
-        if not obj == orca_state.locusOfFocus:
-            return []
+    def generateSpeech(self, obj, **args):
+        if not self._script.utilities.inDocumentContent(obj):
+            return super().generateSpeech(obj, **args)
 
-        return speech_generator.SpeechGenerator._generateAllTextSelection(
-            self, obj, **args)
+        result = []
+        if args.get('formatType') == 'detailedWhereAmI':
+            oldRole = self._overrideRole('default', args)
+        elif self._script.utilities.isLink(obj):
+            oldRole = self._overrideRole(pyatspi.ROLE_LINK, args)
+        else:
+            oldRole = self._overrideRole(obj.getRole(), args)
 
-    def _generateSubstring(self, obj, **args):
-        start = args.get('startOffset')
-        end = args.get('endOffset')
-        if start == None or end == None:
-            return []
+        result.extend(super().generateSpeech(obj, **args))
+        self._restoreRole(oldRole, args)
+        return result
 
-        string = self._script.utilities.substring(obj, start, end)
-        string = self._script.utilities.adjustForRepeats(string)
-        if not string:
+    def generateContents(self, contents, **args):
+        if not len(contents):
             return []
 
-        if not obj.getState().contains(pyatspi.STATE_EDITABLE):
-            string = string.strip()
+        result = []
+        contents = self._script.utilities.filterContentsForPresentation(contents, False)
+        for i, content in enumerate(contents):
+            obj, start, end, string = content
+            utterance = self.generateSpeech(
+                obj, startOffset=start, endOffset=end, string=string,
+                index=i, total=len(contents), **args)
+            if utterance and utterance[0]:
+                result.append(utterance)
+
+        if not result:
+            if self._script.inSayAll():
+                string = ""
+            else:
+                string = messages.BLANK
+            result = [string, self.voice(speech_generator.DEFAULT)]
 
-        result = [string]
-        result.extend(self._getACSS(obj, string))
         return result
-
-    # TODO - JD: While working on the Gecko rewrite, I found a metric crapton
-    # of text generation methods (including, but not limited to, these below).
-    # Are these really all needed? Seriously??
-    def _generateCurrentLineText(self, obj, **args):
-        result = self._generateSubstring(obj, **args)
-        if result:
-            return result
-
-        return speech_generator.SpeechGenerator._generateCurrentLineText(
-            self, obj, **args)
-
-    def _generateDisplayedText(self, obj, **args):
-        result = self._generateSubstring(obj, **args)
-        if result:
-            return result
-
-        return speech_generator.SpeechGenerator._generateDisplayedText(
-            self, obj, **args)
-
-    def _generateTextContent(self, obj, **args):
-        result = self._generateSubstring(obj, **args)
-        if result:
-            return result
-
-        return speech_generator.SpeechGenerator._generateTextContent(
-            self, obj, **args)
diff --git a/src/orca/scripts/toolkits/Gecko/structural_navigation.py 
b/src/orca/scripts/toolkits/Gecko/structural_navigation.py
index fc091e0..02c5ef0 100644
--- a/src/orca/scripts/toolkits/Gecko/structural_navigation.py
+++ b/src/orca/scripts/toolkits/Gecko/structural_navigation.py
@@ -57,7 +57,7 @@ class GeckoStructuralNavigation(structural_navigation.StructuralNavigation):
         in the case of Gecko, that doesn't always work.
         """
 
-        [obj, offset] = self._script.getCaretContext()
+        [obj, offset] = self._script.utilities.getCaretContext()
         return obj
 
     def _findPreviousObject(self, obj, stopAncestor):
@@ -70,7 +70,7 @@ class GeckoStructuralNavigation(structural_navigation.StructuralNavigation):
         -stopAncestor: the ancestor at which the search should stop
         """
 
-        return self._script.findPreviousObject(obj, stopAncestor)
+        return self._script.utilities.getPreviousObjectInDocument(obj, stopAncestor)
 
     def _findNextObject(self, obj, stopAncestor):
         """Finds the object after to this one, where the tree we're
@@ -82,7 +82,7 @@ class GeckoStructuralNavigation(structural_navigation.StructuralNavigation):
         -stopAncestor: the ancestor at which the search should stop
         """
 
-        return self._script.findNextObject(obj, stopAncestor)
+        return self._script.utilities.getNextObjectInDocument(obj, stopAncestor)
 
     def _findLastObject(self, ancestor):
         """Returns the last object in ancestor.
@@ -92,7 +92,7 @@ class GeckoStructuralNavigation(structural_navigation.StructuralNavigation):
           is sought.
         """
 
-        return self._script.getLastObject(ancestor)
+        return self._script.utilities.getLastObjectInDocument(ancestor)
 
     def _getDocument(self):
         """Returns the document or other object in which the object of
@@ -104,34 +104,34 @@ class GeckoStructuralNavigation(structural_navigation.StructuralNavigation):
     def _isInDocument(self, obj):
         """Returns True of the object is inside of the document."""
 
-        return self._script.inDocumentContent(obj)
+        return self._script.utilities.inDocumentContent(obj)
 
     def _getCaretPosition(self, obj):
         """Returns the [obj, characterOffset] where the caret should be
         positioned.
         """
 
-        obj, offset = self._script.findFirstCaretContext(obj, 0)
+        obj, offset = self._script.utilities.findFirstCaretContext(obj, 0)
         if not obj:
             return obj, offset
 
         if obj.getRole() == pyatspi.ROLE_SECTION \
            and not self._script.utilities.queryNonEmptyText(obj):
-            obj, offset = self._script.findNextCaretInOrder(obj, offset)
+            obj, offset = self._script.utilities.findNextCaretInOrder(obj, offset)
 
         # If it's an anchor, look for the first object of use.
         # See bug #591592.
         #
         if obj.getRole() == pyatspi.ROLE_LINK \
            and not obj.getState().contains(pyatspi.STATE_FOCUSABLE):
-            obj, offset = self._script.findNextCaretInOrder(obj, offset)
+            obj, offset = self._script.utilities.findNextCaretInOrder(obj, offset)
 
         return obj, offset
 
     def _setCaretPosition(self, obj, characterOffset):
         """Sets the caret at the specified offset within obj."""
 
-        self._script.setCaretPosition(obj, characterOffset)
+        self._script.utilities.setCaretPosition(obj, characterOffset)
 
     #####################################################################
     #                                                                   #
@@ -163,7 +163,7 @@ class GeckoStructuralNavigation(structural_navigation.StructuralNavigation):
                 pass
 
         self._script.updateBraille(obj)
-        contents = self._script.getObjectContentsAtOffset(obj, offset)
+        contents = self._script.utilities.getObjectContentsAtOffset(obj, offset)
         self._script.speakContents(contents)
 
     #########################################################################
diff --git a/src/orca/scripts/toolkits/WebKitGtk/script_utilities.py 
b/src/orca/scripts/toolkits/WebKitGtk/script_utilities.py
index 8e2e192..850b40a 100644
--- a/src/orca/scripts/toolkits/WebKitGtk/script_utilities.py
+++ b/src/orca/scripts/toolkits/WebKitGtk/script_utilities.py
@@ -98,6 +98,9 @@ class Utilities(script_utilities.Utilities):
         return self.getObjectsFromEOCs(
             obj, offset, pyatspi.TEXT_BOUNDARY_LINE_START)
 
+    def getObjectContentsAtOffset(self, obj, offset=0, useCache=True):
+        return self.getObjectsFromEOCs(obj, offset)
+
     def getObjectsFromEOCs(self, obj, offset=None, boundary=None):
         """Breaks the string containing a mixture of text and embedded object
         characters into a list of (obj, startOffset, endOffset, string) tuples.
diff --git a/src/orca/speech_generator.py b/src/orca/speech_generator.py
index 4810722..4e8d614 100644
--- a/src/orca/speech_generator.py
+++ b/src/orca/speech_generator.py
@@ -93,6 +93,18 @@ class SpeechGenerator(generator.Generator):
     def __init__(self, script):
         generator.Generator.__init__(self, script, "speech")
 
+    def _getACSS(self, obj, string):
+        if obj.getRole() == pyatspi.ROLE_LINK:
+            acss = self.voice(HYPERLINK)
+        elif isinstance(string, str) \
+            and string.isupper() \
+            and string.strip().isalpha():
+            acss = self.voice(UPPERCASE)
+        else:
+            acss = self.voice(DEFAULT)
+
+        return acss
+
     def _addGlobals(self, globalsDict):
         """Other things to make available from the formatting string.
         """
@@ -964,6 +976,11 @@ class SpeechGenerator(generator.Generator):
         this is a text object.  [[[WDW - consider returning an empty
         array if this is not a text object.]]]
         """
+
+        result = self._generateSubstring(obj, **args)
+        if result:
+            return result
+
         acss = self.voice(DEFAULT)
         result = generator.Generator._generateCurrentLineText(self, obj, **args)
         if result:
@@ -973,6 +990,10 @@ class SpeechGenerator(generator.Generator):
         return result
 
     def _generateDisplayedText(self, obj, **args):
+        result = self._generateSubstring(obj, **args)
+        if result:
+            return result
+
         acss = self.voice(DEFAULT)
         result = generator.Generator._generateDisplayedText(self, obj, **args)
         if result:
@@ -1065,18 +1086,6 @@ class SpeechGenerator(generator.Generator):
                 textObj.caretOffset,
                 pyatspi.TEXT_BOUNDARY_LINE_START)
             if len(line):
-                # Check for embedded object characters. If we find any,
-                # expand the text. TODO - JD: This expansion doesn't
-                # include the role information; just the text. However,
-                # the handling of roles should probably be dealt with as
-                # a formatting string. We have not yet worked out how to
-                # do this with Gecko (primary user of embedded object
-                # characters). Until we do, this expansion is better than
-                # presenting the actual embedded object character.
-                #
-                if self._script.EMBEDDED_OBJECT_CHARACTER in line:
-                    line = self._script.utilities.expandEOCs(
-                        obj, startOffset, endOffset)
                 line = self._script.utilities.adjustForRepeats(line)
                 textContents = line
             else:
@@ -1096,6 +1105,11 @@ class SpeechGenerator(generator.Generator):
         specifications) containing the text content.  This requires
         _generateTextInformation to have been called prior to this method.
         """
+
+        result = self._generateSubstring(obj, **args)
+        if result:
+            return result
+
         try:
             text = obj.queryText()
         except NotImplementedError:
@@ -1211,6 +1225,17 @@ class SpeechGenerator(generator.Generator):
                     result.extend(acss)
         return result
 
+    def _generateSubstring(self, obj, **args):
+        result = super()._generateSubstring(obj, **args)
+        if not (result and result[0]):
+            return []
+
+        if not obj.getState().contains(pyatspi.STATE_EDITABLE):
+            result[0] = result[0].strip()
+
+        result.extend(self._getACSS(obj, result[0]))
+        return result
+
     def generateTextIndentation(self, obj, **args):
         return self._generateTextIndentation(obj, **args)
 
@@ -1578,6 +1603,14 @@ class SpeechGenerator(generator.Generator):
         'priorObj' is typically set by Orca to be the previous object
         with focus.
         """
+
+        # TODO - JD: This is not the right way to do this, but we can fix
+        # that as part of the removal of formatting strings.
+        start = args.get('startOffset')
+        end = args.get('endOffset')
+        if start is not None or end is not None:
+            return []
+
         result = []
         priorObj = args.get('priorObj')
         if obj.getRole() == pyatspi.ROLE_MENU_ITEM \
@@ -1840,6 +1873,8 @@ class SpeechGenerator(generator.Generator):
     #####################################################################
 
     def _generatePause(self, obj, **args):
+        if args.get('eliminatePauses', False):
+            return []
         return PAUSE
 
     def _generateLineBreak(self, obj, **args):
diff --git a/test/html/inline-block-spans.html b/test/html/inline-block-spans.html
new file mode 100644
index 0000000..a86d033
--- /dev/null
+++ b/test/html/inline-block-spans.html
@@ -0,0 +1,25 @@
+<html>
+<head>
+<style>
+.foo{display:inline-block;height:32px;width:32px;position:relative}
+</style>
+</head>
+<body>
+<div>Line 1</div>
+<div>Line 2
+  <span>
+    <span class="foo"></span>
+  </span>
+  <span>
+    <span class="foo"></span>
+  </span>
+  <span>
+    <span class="foo"></span>
+  </span>
+  <span>
+    <span class="foo"></span>
+  </span>
+</div>
+<div>Line 3</div>
+</body>
+</html>
diff --git a/test/html/paragraphs-in-links.html b/test/html/paragraphs-in-links.html
new file mode 100644
index 0000000..66b3a92
--- /dev/null
+++ b/test/html/paragraphs-in-links.html
@@ -0,0 +1,11 @@
+<html>
+<head></head>
+<body>
+<p>Hello world</p>
+<a href="foo">
+  <p>Paragraph 1</p>
+  <p>Paragraph 2</p>
+</a>
+<p>Goodbye world</p>
+</body>
+</html>
diff --git a/test/keystrokes/firefox/aria_alert.py b/test/keystrokes/firefox/aria_alert.py
index fa5853e..6f31e4b 100644
--- a/test/keystrokes/firefox/aria_alert.py
+++ b/test/keystrokes/firefox/aria_alert.py
@@ -20,8 +20,8 @@ sequence.append(TypeAction(" "))
 sequence.append(utils.AssertPresentationAction(
     "1. Press button",
     ["KNOWN ISSUE: Because the link has focus, we double-present it.",
-     "BRAILLE LINE:  'This popup is created as a div in the'",
-     "     VISIBLE:  'This popup is created as a div i', cursor=1",
+     "BRAILLE LINE:  'alert'",
+     "     VISIBLE:  'alert', cursor=1",
      "BRAILLE LINE:  'close'",
      "     VISIBLE:  'close', cursor=1",
      "BRAILLE LINE:  'close'",
@@ -140,8 +140,7 @@ sequence.append(utils.AssertPresentationAction(
     "15. Down Arrow",
     ["BRAILLE LINE:  'close'",
      "     VISIBLE:  'close', cursor=1",
-     "SPEECH OUTPUT: 'close'",
-     "SPEECH OUTPUT: 'link'"]))
+     "SPEECH OUTPUT: 'close link'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
@@ -155,7 +154,7 @@ sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Return"))
 sequence.append(utils.AssertPresentationAction(
     "18. Return on close link",
-    ["KNOWN ISSUE: We should present something here."
+    ["KNOWN ISSUE: We should present something here.",
      ""]))
 
 sequence.append(utils.AssertionSummaryAction())
diff --git a/test/keystrokes/firefox/aria_alert_dialog.py b/test/keystrokes/firefox/aria_alert_dialog.py
index 64316fb..d81d79f 100644
--- a/test/keystrokes/firefox/aria_alert_dialog.py
+++ b/test/keystrokes/firefox/aria_alert_dialog.py
@@ -12,12 +12,11 @@ sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Return"))
 sequence.append(utils.AssertPresentationAction(
     "1. Open Alert Box",
-    ["KNOWN ISSUE: We are missing spaces between the words in speech",
-     "BRAILLE LINE:  'dialog'",
+    ["BRAILLE LINE:  'dialog'",
      "     VISIBLE:  'dialog', cursor=1",
      "BRAILLE LINE:  'Browse mode'",
      "     VISIBLE:  'Browse mode', cursor=0",
-     "SPEECH OUTPUT: 'Alert BoxYou must choose a number between 1 and 10!Close'",
+     "SPEECH OUTPUT: 'Alert Box You must choose a number between 1 and 10!'",
      "SPEECH OUTPUT: 'Browse mode' voice=system"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -39,9 +38,17 @@ sequence.append(utils.AssertPresentationAction(
      "SPEECH OUTPUT: 'between 1 and 10!'"]))
 
 sequence.append(utils.StartRecordingAction())
+sequence.append(KeyComboAction("Down"))
+sequence.append(utils.AssertPresentationAction(
+    "4. Down arrow to read next line of message",
+    ["BRAILLE LINE:  'Close push button'",
+     "     VISIBLE:  'Close push button', cursor=1",
+     "SPEECH OUTPUT: 'Close push button'"]))
+
+sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Return"))
 sequence.append(utils.AssertPresentationAction(
-    "4. Close Alert",
+    "5. Close Alert",
     ["BRAILLE LINE:  'Guess a number between 1 and 10 12 $l'",
      "     VISIBLE:  'ss a number between 1 and 10 12 ', cursor=32",
      "BRAILLE LINE:  'Focus mode'",
diff --git a/test/keystrokes/firefox/aria_button.py b/test/keystrokes/firefox/aria_button.py
index 29a2786..7bf8ac9 100644
--- a/test/keystrokes/firefox/aria_button.py
+++ b/test/keystrokes/firefox/aria_button.py
@@ -37,8 +37,8 @@ sequence.append(utils.AssertPresentationAction(
     "3. Basic whereamI",
     ["BRAILLE LINE:  'Check Now push button'",
      "     VISIBLE:  'Check Now push button', cursor=1",
-     "BRAILLE LINE:  'Check Now push button Check to see if your order has been'",
-     "     VISIBLE:  'Check Now push button Check to s', cursor=1",
+     "BRAILLE LINE:  'Check Now push button'",
+     "     VISIBLE:  'Check Now push button', cursor=1",
      "SPEECH OUTPUT: 'Check Now push button Check to see if your order has been shipped.'"]))
 
 sequence.append(utils.AssertionSummaryAction())
diff --git a/test/keystrokes/firefox/aria_button_dojo.py b/test/keystrokes/firefox/aria_button_dojo.py
index bb3e512..b283455 100644
--- a/test/keystrokes/firefox/aria_button_dojo.py
+++ b/test/keystrokes/firefox/aria_button_dojo.py
@@ -5,27 +5,29 @@ import utils
 
 sequence = MacroSequence()
 
+sequence.append(PauseAction(3000))
+
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Tab"))
 sequence.append(utils.AssertPresentationAction(
     "1. Tab to the <button> button",
-    ["BRAILLE LINE:  '<button> push button <input type='button'> push button Create View Create save options 
push button Edit! Color'",
-     "     VISIBLE:  '<button> push button <input type', cursor=1",
+    ["BRAILLE LINE:  '<button> push button'",
+     "     VISIBLE:  '<button> push button', cursor=1",
      "SPEECH OUTPUT: '<button> push button'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("KP_Enter"))
 sequence.append(utils.AssertPresentationAction(
     "2. Basic Where Am I on <button>",
-    ["BRAILLE LINE:  '<button> push button <input type='button'> push button Create View Create save options 
push button Edit! Color'",
-     "     VISIBLE:  '<button> push button <input type', cursor=1",
+    ["BRAILLE LINE:  '<button> push button'",
+     "     VISIBLE:  '<button> push button', cursor=1",
      "SPEECH OUTPUT: '<button> push button'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Tab"))
 sequence.append(utils.AssertPresentationAction(
     "3. Tab to <input type='button'>",
-    ["BRAILLE LINE:  '<button> push button <input type='button'> push button Create View Create save options 
push button Edit! Color'",
+    ["BRAILLE LINE:  '<input type='button'> push button'",
      "     VISIBLE:  '<input type='button'> push butto', cursor=1",
      "SPEECH OUTPUT: '<input type='button'> push button'"]))
 
@@ -33,7 +35,7 @@ sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("KP_Enter"))
 sequence.append(utils.AssertPresentationAction(
     "4. Basic Where Am I on <input type='button'>",
-    ["BRAILLE LINE:  '<button> push button <input type='button'> push button Create View Create save options 
push button Edit! Color'",
+    ["BRAILLE LINE:  '<input type='button'> push button'",
      "     VISIBLE:  '<input type='button'> push butto', cursor=1",
      "SPEECH OUTPUT: '<input type='button'> push button'"]))
 
@@ -73,16 +75,16 @@ sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Tab"))
 sequence.append(utils.AssertPresentationAction(
     "9. Tab to drop down menu on Create -- whose tooltip and accessible name is 'save options'",
-    ["BRAILLE LINE:  '<button> push button <input type='button'> push button Create View Create save options 
push button Edit! Color'",
-     "     VISIBLE:  'save options push button Edit! C', cursor=1",
+    ["BRAILLE LINE:  'save options push button'",
+     "     VISIBLE:  'save options push button', cursor=1",
      "SPEECH OUTPUT: 'save options push button'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(TypeAction(" "))
 sequence.append(utils.AssertPresentationAction(
     "10. Open drop down menu on Create",
-    ["BRAILLE LINE:  '<button> push button <input type='button'> push button Create View Create save options 
push button Edit! Color'",
-     "     VISIBLE:  'save options push button Edit! C', cursor=1",
+    ["BRAILLE LINE:  'save options push button'",
+     "     VISIBLE:  'save options push button', cursor=1",
      "BRAILLE LINE:  'Create blank'",
      "     VISIBLE:  'Create blank', cursor=1",
      "BRAILLE LINE:  'Focus mode'",
@@ -192,7 +194,6 @@ sequence.append(utils.AssertPresentationAction(
     "21. Close the Submenu",
     ["BRAILLE LINE:  'Submenu menu'",
      "     VISIBLE:  'Submenu menu', cursor=1",
-     "SPEECH OUTPUT: 'Edit! menu'",
      "SPEECH OUTPUT: 'Submenu menu'"]))
 
 sequence.append(utils.StartRecordingAction())
diff --git a/test/keystrokes/firefox/aria_button_toggle.py b/test/keystrokes/firefox/aria_button_toggle.py
index a0bbfcb..44bed4c 100644
--- a/test/keystrokes/firefox/aria_button_toggle.py
+++ b/test/keystrokes/firefox/aria_button_toggle.py
@@ -13,54 +13,54 @@ sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Tab"))
 sequence.append(utils.AssertPresentationAction(
     "1. Tab to first button",
-    ["BRAILLE LINE:  '& y Font Larger toggle button & y Font Smaller toggle button &=y Italic toggle button 
& y Bold toggle button'",
-     "     VISIBLE:  '& y Font Larger toggle button & ', cursor=1",
+    ["BRAILLE LINE:  '& y Font Larger toggle button'",
+     "     VISIBLE:  '& y Font Larger toggle button', cursor=1",
      "SPEECH OUTPUT: 'Font Larger + toggle button not pressed'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("KP_Enter"))
 sequence.append(utils.AssertPresentationAction(
     "2. Basic whereamI",
-    ["BRAILLE LINE:  '& y Font Larger toggle button & y Font Smaller toggle button &=y Italic toggle button 
& y Bold toggle button'",
-     "     VISIBLE:  '& y Font Larger toggle button & ', cursor=1",
+    ["BRAILLE LINE:  '& y Font Larger toggle button'",
+     "     VISIBLE:  '& y Font Larger toggle button', cursor=1",
      "SPEECH OUTPUT: 'Font Larger + toggle button not pressed'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Tab"))
 sequence.append(utils.AssertPresentationAction(
     "3. Tab to second button",
-    ["BRAILLE LINE:  '& y Font Larger toggle button & y Font Smaller toggle button &=y Italic toggle button 
& y Bold toggle button'",
-     "     VISIBLE:  '& y Font Smaller toggle button &', cursor=1",
+    ["BRAILLE LINE:  '& y Font Smaller toggle button'",
+     "     VISIBLE:  '& y Font Smaller toggle button', cursor=1",
      "SPEECH OUTPUT: 'Font Smaller - toggle button not pressed'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(TypeAction(" "))
 sequence.append(utils.AssertPresentationAction(
     "4. Push second button",
-    ["KNOWN ISSUE: We're presenting nothing here.",
+    ["KNOWN ISSUE: We're presenting nothing here. Missing event.",
      ""]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Tab"))
 sequence.append(utils.AssertPresentationAction(
     "5. Tab to third button",
-    ["BRAILLE LINE:  '& y Font Larger toggle button & y Font Smaller toggle button &=y Italic toggle button 
& y Bold toggle button'",
-     "     VISIBLE:  '&=y Italic toggle button & y Bol', cursor=1",
+    ["BRAILLE LINE:  '&=y Italic toggle button'",
+     "     VISIBLE:  '&=y Italic toggle button', cursor=1",
      "SPEECH OUTPUT: 'Italic i toggle button pressed'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(TypeAction(" "))
 sequence.append(utils.AssertPresentationAction(
     "6. Push third button",
-    ["BRAILLE LINE:  '& y Font Larger toggle button & y Font Smaller toggle button & y Italic toggle button 
& y Bold toggle button'",
-     "     VISIBLE:  '& y Italic toggle button & y Bol', cursor=1",
+    ["BRAILLE LINE:  '& y Italic toggle button'",
+     "     VISIBLE:  '& y Italic toggle button', cursor=1",
      "SPEECH OUTPUT: 'not pressed'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Tab"))
 sequence.append(utils.AssertPresentationAction(
     "7. Tab to fourth button",
-    ["BRAILLE LINE:  '& y Font Larger toggle button & y Font Smaller toggle button & y Italic toggle button 
& y Bold toggle button'",
+    ["BRAILLE LINE:  '& y Bold toggle button'",
      "     VISIBLE:  '& y Bold toggle button', cursor=1",
      "SPEECH OUTPUT: 'Bold B toggle button not pressed'"]))
 
@@ -68,7 +68,7 @@ sequence.append(utils.StartRecordingAction())
 sequence.append(TypeAction(" "))
 sequence.append(utils.AssertPresentationAction(
     "8. Push fourth button",
-    ["BRAILLE LINE:  '& y Font Larger toggle button & y Font Smaller toggle button & y Italic toggle button 
&=y Bold toggle button'",
+    ["BRAILLE LINE:  '&=y Bold toggle button'",
      "     VISIBLE:  '&=y Bold toggle button', cursor=1",
      "SPEECH OUTPUT: 'pressed'"]))
 
@@ -76,7 +76,7 @@ sequence.append(utils.StartRecordingAction())
 sequence.append(TypeAction(" "))
 sequence.append(utils.AssertPresentationAction(
     "9. Push fourth button again",
-    ["BRAILLE LINE:  '& y Font Larger toggle button & y Font Smaller toggle button & y Italic toggle button 
& y Bold toggle button'",
+    ["BRAILLE LINE:  '& y Bold toggle button'",
      "     VISIBLE:  '& y Bold toggle button', cursor=1",
      "SPEECH OUTPUT: 'not pressed'"]))
 
diff --git a/test/keystrokes/firefox/aria_checkbox_dojo.py b/test/keystrokes/firefox/aria_checkbox_dojo.py
index fa452ce..fac12bf 100644
--- a/test/keystrokes/firefox/aria_checkbox_dojo.py
+++ b/test/keystrokes/firefox/aria_checkbox_dojo.py
@@ -27,7 +27,7 @@ sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Tab"))
 sequence.append(utils.AssertPresentationAction(
     "3. Tab to the cb1 checkbox",
-    ["BRAILLE LINE:  '< > cb1: normal checkbox, with value=foo, clicking generates console log messages 
check box get('value') push button'",
+    ["BRAILLE LINE:  '< > cb1: normal checkbox, with value=foo, clicking generates console log messages 
check box'",
      "     VISIBLE:  '< > cb1: normal checkbox, with v', cursor=1",
      "SPEECH OUTPUT: 'cb1: normal checkbox, with value=foo, clicking generates console log messages check 
box not checked'"]))
 
@@ -35,7 +35,7 @@ sequence.append(utils.StartRecordingAction())
 sequence.append(TypeAction(" "))
 sequence.append(utils.AssertPresentationAction(
     "4. Change state on cb1 checkbox",
-    ["BRAILLE LINE:  '<x> cb1: normal checkbox, with value=foo, clicking generates console log messages 
check box get('value') push button'",
+    ["BRAILLE LINE:  '<x> cb1: normal checkbox, with value=foo, clicking generates console log messages 
check box'",
      "     VISIBLE:  '<x> cb1: normal checkbox, with v', cursor=1",
      "SPEECH OUTPUT: 'checked'"]))
 
@@ -44,7 +44,7 @@ sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Tab"))
 sequence.append(utils.AssertPresentationAction(
     "5. Tab to the cb2 checkbox",
-    ["BRAILLE LINE:  '<x> cb2: normal checkbox, with default value, initially turned on. check box 
\"onChange\" handler updates: [] get('value') push button'",
+    ["BRAILLE LINE:  '<x> cb2: normal checkbox, with default value, initially turned on. check box'",
      "     VISIBLE:  '<x> cb2: normal checkbox, with d', cursor=1",
      "SPEECH OUTPUT: 'cb2: normal checkbox, with default value, initially turned on. check box checked'"]))
 
@@ -61,7 +61,7 @@ sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Tab"))
 sequence.append(utils.AssertPresentationAction(
     "7. Tab to the cb5 checkbox",
-    ["BRAILLE LINE:  '< > cb5: normal checkbox, with specified value=\"\", clicking generates console log 
messages check box get('value') push button'",
+    ["BRAILLE LINE:  '< > cb5: normal checkbox, with specified value=\"\", clicking generates console log 
messages check box'",
      "     VISIBLE:  '< > cb5: normal checkbox, with s', cursor=1",
      "SPEECH OUTPUT: 'cb5: normal checkbox, with specified value=\"\", clicking generates console log 
messages check box not checked'"]))
 
@@ -78,7 +78,7 @@ sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Tab"))
 sequence.append(utils.AssertPresentationAction(
     "9. Tab to the cb7 checkbox",
-    ["BRAILLE LINE:  '< > cb7: normal checkbox. check box disable push button enable push button set value 
to \"fish\" push button Reset value+checked push button \"onChange\" handler updates: []'",
+    ["BRAILLE LINE:  '< > cb7: normal checkbox. check box'",
      "     VISIBLE:  '< > cb7: normal checkbox. check ', cursor=1",
      "SPEECH OUTPUT: 'cb7: normal checkbox. check box not checked'"]))
 
@@ -86,7 +86,7 @@ sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("KP_Enter"))
 sequence.append(utils.AssertPresentationAction(
     "10. Basic Where Am I",
-    ["BRAILLE LINE:  '< > cb7: normal checkbox. check box disable push button enable push button set value 
to \"fish\" push button Reset value+checked push button \"onChange\" handler updates: []'",
+    ["BRAILLE LINE:  '< > cb7: normal checkbox. check box'",
      "     VISIBLE:  '< > cb7: normal checkbox. check ', cursor=1",
      "SPEECH OUTPUT: 'cb7: normal checkbox. check box not checked'"]))
 
diff --git a/test/keystrokes/firefox/aria_combobox_dojo.py b/test/keystrokes/firefox/aria_combobox_dojo.py
index 3ed7ba7..0eb9c72 100644
--- a/test/keystrokes/firefox/aria_combobox_dojo.py
+++ b/test/keystrokes/firefox/aria_combobox_dojo.py
@@ -29,10 +29,11 @@ sequence.append(utils.StartRecordingAction())
 sequence.append(TypeAction("C"))
 sequence.append(utils.AssertPresentationAction(
     "2. Replace existing text with a 'C'",
-    ["BRAILLE LINE:  'US State test 1 (200% Courier font): C $l'",
+    ["KNOWN ISSUE: The braille line is not quite right",
+     "BRAILLE LINE:  'US State test 1 (200% Courier font): C $l'",
      "     VISIBLE:  '(200% Courier font): C $l', cursor=23",
-     "BRAILLE LINE:  'US State test 1 (200% Courier font):'",
-     "     VISIBLE:  'US State test 1 (200% Courier fo', cursor=1",
+     "BRAILLE LINE:  'US State test 1 (200% Courier font): US State test 1 (200% Courier font): combo box'",
+     "     VISIBLE:  'te test 1 (200% Courier font): U', cursor=32",
      "SPEECH OUTPUT: 'expanded'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -105,7 +106,9 @@ sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Escape"))
 sequence.append(utils.AssertPresentationAction(
     "11. Escape",
-    ["BRAILLE LINE:  'US State test 1 (200% Courier font): California $l'",
+    ["BRAILLE LINE:  'US State test 1 (200% Courier font): US State test 1 (200% Courier font): combo box'",
+     "     VISIBLE:  'te test 1 (200% Courier font): U', cursor=32",
+     "BRAILLE LINE:  'US State test 1 (200% Courier font): California $l'",
      "     VISIBLE:  '(200% Courier font): California ', cursor=32",
      "SPEECH OUTPUT: 'collapsed'",
      "SPEECH OUTPUT: 'US State test 1 (200% Courier font): entry California selected'"]))
diff --git a/test/keystrokes/firefox/aria_dialog_dojo.py b/test/keystrokes/firefox/aria_dialog_dojo.py
index c2e0464..e42dee8 100644
--- a/test/keystrokes/firefox/aria_dialog_dojo.py
+++ b/test/keystrokes/firefox/aria_dialog_dojo.py
@@ -18,13 +18,11 @@ sequence.append(utils.AssertPresentationAction(
     "1. Launch dialog",
     ["BRAILLE LINE:  'TabContainer Dialog dialog'",
      "     VISIBLE:  'TabContainer Dialog dialog', cursor=1",
-     "BRAILLE LINE:  'First tab page tab Second tab page tab'",
-     "     VISIBLE:  'First tab page tab Second tab pa', cursor=1",
-     "BRAILLE LINE:  'Focus mode'",
-     "     VISIBLE:  'Focus mode', cursor=0",
      "BRAILLE LINE:  'First tab page tab'",
      "     VISIBLE:  'First tab page tab', cursor=1",
-     "SPEECH OUTPUT: 'TabContainer Dialog First tab Second tab This is the first tab. Lorem ipsum dolor sit 
amet, consectetuer adipiscing elit. Aenean semper sagittis velit. Cras in mi. Duis porta mauris ut ligula. 
Proin porta rutrum lacus. Etiam consequat scelerisque quam. Nulla facilisi. Maecenas luctus venenatis nulla. 
In sit amet dui non mi semper iaculis. Sed molestie tortor at ipsum. Morbi dictum rutrum magna. Sed vitae 
risus. '",
+     "BRAILLE LINE:  'Focus mode'",
+     "     VISIBLE:  'Focus mode', cursor=0",
+     "SPEECH OUTPUT: 'TabContainer Dialog This is the first tab.  Lorem ipsum dolor sit amet, consectetuer 
adipiscing elit. Aenean semper sagittis velit. Cras in mi. Duis porta mauris ut ligula. Proin porta rutrum 
lacus. Etiam consequat scelerisque quam. Nulla facilisi. Maecenas luctus venenatis nulla. In sit amet dui non 
mi semper iaculis. Sed molestie tortor at ipsum. Morbi dictum rutrum magna. Sed vitae risus.'",
      "SPEECH OUTPUT: 'First tab page tab'",
      "SPEECH OUTPUT: 'Focus mode' voice=system"]))
 
@@ -34,6 +32,8 @@ sequence.append(utils.AssertPresentationAction(
     "2. Basic whereAmI",
     ["BRAILLE LINE:  'First tab page tab'",
      "     VISIBLE:  'First tab page tab', cursor=1",
+     "BRAILLE LINE:  'First tab page tab'",
+     "     VISIBLE:  'First tab page tab', cursor=1",
      "SPEECH OUTPUT: 'page tab list First tab page tab 1 of 2'"]))
 
 sequence.append(KeyComboAction("Escape"))
diff --git a/test/keystrokes/firefox/aria_landmarks.py b/test/keystrokes/firefox/aria_landmarks.py
index 01d8d47..da6f4b6 100644
--- a/test/keystrokes/firefox/aria_landmarks.py
+++ b/test/keystrokes/firefox/aria_landmarks.py
@@ -33,7 +33,8 @@ sequence.append(utils.AssertPresentationAction(
     "3. m to next landmark",
     ["BRAILLE LINE:  'application embedded'",
      "     VISIBLE:  'application embedded', cursor=1",
-     "SPEECH OUTPUT: 'application embedded'"]))
+     "SPEECH OUTPUT: 'application'",
+     "SPEECH OUTPUT: 'embedded'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("m"))
@@ -104,7 +105,8 @@ sequence.append(utils.AssertPresentationAction(
     ["KNOWN ISSUE: We are skipping over complementary on the way back",
      "BRAILLE LINE:  'application embedded'",
      "     VISIBLE:  'application embedded', cursor=1",
-     "SPEECH OUTPUT: 'application embedded'"]))
+     "SPEECH OUTPUT: 'application'",
+     "SPEECH OUTPUT: 'embedded'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("<Shift>m"))
diff --git a/test/keystrokes/firefox/aria_menu.py b/test/keystrokes/firefox/aria_menu.py
index fdf3409..9de2c2e 100644
--- a/test/keystrokes/firefox/aria_menu.py
+++ b/test/keystrokes/firefox/aria_menu.py
@@ -15,9 +15,9 @@ sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("<Control><Alt>m"))
 sequence.append(utils.AssertPresentationAction(
     "1. Move to the menu",
-    ["BRAILLE LINE:  'table'",
-     "     VISIBLE:  'table', cursor=1",
-     "BRAILLE LINE:  'Edit menu'",
+    ["BRAILLE LINE:  'ARIA Spreadsheet and Menubar embedded Edit menu'",
+     "     VISIBLE:  'Edit menu', cursor=1",
+     "BRAILLE LINE:  'ARIA Spreadsheet and Menubar embedded Edit menu'",
      "     VISIBLE:  'Edit menu', cursor=1",
      "SPEECH OUTPUT: 'Edit menu'"]))
 
@@ -26,15 +26,18 @@ sequence.append(KeyComboAction("KP_Enter"))
 sequence.append(PauseAction(3000))
 sequence.append(utils.AssertPresentationAction(
     "2. basic whereAmI",
-    ["BRAILLE LINE:  'Edit menu'",
+    ["BRAILLE LINE:  'ARIA Spreadsheet and Menubar embedded Edit menu'",
      "     VISIBLE:  'Edit menu', cursor=1",
+     "SPEECH OUTPUT: 'ARIA Spreadsheet and Menubar - Mozilla Firefox frame'",
      "SPEECH OUTPUT: 'Edit menu 1 of 1'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Right"))
 sequence.append(utils.AssertPresentationAction(
     "3. Move to View",
-    ["BRAILLE LINE:  'View menu'",
+    ["BRAILLE LINE:  'ARIA Spreadsheet and Menubar embedded View menu'",
+     "     VISIBLE:  'View menu', cursor=1",
+     "BRAILLE LINE:  'ARIA Spreadsheet and Menubar embedded View menu'",
      "     VISIBLE:  'View menu', cursor=1",
      "SPEECH OUTPUT: 'View menu'"]))
 
@@ -42,23 +45,35 @@ sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
 sequence.append(utils.AssertPresentationAction(
     "4. Move to Themes",
-    ["BRAILLE LINE:  'Themes          > menu'",
+    ["BRAILLE LINE:  'ARIA Spreadsheet and Menubar embedded menu'",
+     "     VISIBLE:  'menu', cursor=1",
+     "BRAILLE LINE:  'ARIA Spreadsheet and Menubar embedded Themes          > menu'",
      "     VISIBLE:  'Themes          > menu', cursor=1",
+     "BRAILLE LINE:  'ARIA Spreadsheet and Menubar embedded Themes          > menu'",
+     "     VISIBLE:  'Themes          > menu', cursor=1",
+     "SPEECH OUTPUT: 'menu'",
      "SPEECH OUTPUT: 'Themes          > menu'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Right"))
 sequence.append(utils.AssertPresentationAction(
     "5. Move to basic grey",
-    ["BRAILLE LINE:  'Basic Grey'",
+    ["BRAILLE LINE:  'ARIA Spreadsheet and Menubar embedded menu'",
+     "     VISIBLE:  'menu', cursor=1",
+     "BRAILLE LINE:  'ARIA Spreadsheet and Menubar embedded Basic Grey'",
+     "     VISIBLE:  'Basic Grey', cursor=1",
+     "BRAILLE LINE:  'ARIA Spreadsheet and Menubar embedded Basic Grey'",
      "     VISIBLE:  'Basic Grey', cursor=1",
+     "SPEECH OUTPUT: 'menu'",
      "SPEECH OUTPUT: 'Basic Grey'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
 sequence.append(utils.AssertPresentationAction(
     "6. Move to the blues",
-    ["BRAILLE LINE:  'The Blues'",
+    ["BRAILLE LINE:  'ARIA Spreadsheet and Menubar embedded The Blues'",
+     "     VISIBLE:  'The Blues', cursor=1",
+     "BRAILLE LINE:  'ARIA Spreadsheet and Menubar embedded The Blues'",
      "     VISIBLE:  'The Blues', cursor=1",
      "SPEECH OUTPUT: 'The Blues'"]))
 
@@ -66,7 +81,9 @@ sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
 sequence.append(utils.AssertPresentationAction(
     "7. Move to garden",
-    ["BRAILLE LINE:  'Garden'",
+    ["BRAILLE LINE:  'ARIA Spreadsheet and Menubar embedded Garden'",
+     "     VISIBLE:  'Garden', cursor=1",
+     "BRAILLE LINE:  'ARIA Spreadsheet and Menubar embedded Garden'",
      "     VISIBLE:  'Garden', cursor=1",
      "SPEECH OUTPUT: 'Garden'"]))
 
@@ -74,7 +91,9 @@ sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
 sequence.append(utils.AssertPresentationAction(
     "8. Move to in the pink",
-    ["BRAILLE LINE:  'In the Pink grayed'",
+    ["BRAILLE LINE:  'ARIA Spreadsheet and Menubar embedded In the Pink grayed'",
+     "     VISIBLE:  'In the Pink grayed', cursor=1",
+     "BRAILLE LINE:  'ARIA Spreadsheet and Menubar embedded In the Pink grayed'",
      "     VISIBLE:  'In the Pink grayed', cursor=1",
      "SPEECH OUTPUT: 'In the Pink grayed'"]))
 
@@ -82,7 +101,9 @@ sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
 sequence.append(utils.AssertPresentationAction(
     "9. Move to rose",
-    ["BRAILLE LINE:  'Rose'",
+    ["BRAILLE LINE:  'ARIA Spreadsheet and Menubar embedded Rose'",
+     "     VISIBLE:  'Rose', cursor=1",
+     "BRAILLE LINE:  'ARIA Spreadsheet and Menubar embedded Rose'",
      "     VISIBLE:  'Rose', cursor=1",
      "SPEECH OUTPUT: 'Rose'"]))
 
@@ -90,7 +111,9 @@ sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Left"))
 sequence.append(utils.AssertPresentationAction(
     "10. Move back to Themes",
-    ["BRAILLE LINE:  'Themes          > menu'",
+    ["BRAILLE LINE:  'ARIA Spreadsheet and Menubar embedded Themes          > menu'",
+     "     VISIBLE:  'Themes          > menu', cursor=1",
+     "BRAILLE LINE:  'ARIA Spreadsheet and Menubar embedded Themes          > menu'",
      "     VISIBLE:  'Themes          > menu', cursor=1",
      "SPEECH OUTPUT: 'Themes          > menu'"]))
 
@@ -98,7 +121,9 @@ sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
 sequence.append(utils.AssertPresentationAction(
     "11. Move to hide",
-    ["BRAILLE LINE:  'Hide'",
+    ["BRAILLE LINE:  'ARIA Spreadsheet and Menubar embedded Hide'",
+     "     VISIBLE:  'Hide', cursor=1",
+     "BRAILLE LINE:  'ARIA Spreadsheet and Menubar embedded Hide'",
      "     VISIBLE:  'Hide', cursor=1",
      "SPEECH OUTPUT: 'Hide'"]))
 
@@ -106,7 +131,9 @@ sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
 sequence.append(utils.AssertPresentationAction(
     "12. Move to show",
-    ["BRAILLE LINE:  'Show'",
+    ["BRAILLE LINE:  'ARIA Spreadsheet and Menubar embedded Show'",
+     "     VISIBLE:  'Show', cursor=1",
+     "BRAILLE LINE:  'ARIA Spreadsheet and Menubar embedded Show'",
      "     VISIBLE:  'Show', cursor=1",
      "SPEECH OUTPUT: 'Show'"]))
 
@@ -114,7 +141,9 @@ sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
 sequence.append(utils.AssertPresentationAction(
     "13. Move to more",
-    ["BRAILLE LINE:  'More                > menu'",
+    ["BRAILLE LINE:  'ARIA Spreadsheet and Menubar embedded More                > menu'",
+     "     VISIBLE:  'More                > menu', cursor=1",
+     "BRAILLE LINE:  'ARIA Spreadsheet and Menubar embedded More                > menu'",
      "     VISIBLE:  'More                > menu', cursor=1",
      "SPEECH OUTPUT: 'More                > menu'"]))
 
@@ -122,15 +151,22 @@ sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Right"))
 sequence.append(utils.AssertPresentationAction(
     "14. Move to one",
-    ["BRAILLE LINE:  'one'",
+    ["BRAILLE LINE:  'ARIA Spreadsheet and Menubar embedded menu'",
+     "     VISIBLE:  'menu', cursor=1",
+     "BRAILLE LINE:  'ARIA Spreadsheet and Menubar embedded one'",
+     "     VISIBLE:  'one', cursor=1",
+     "BRAILLE LINE:  'ARIA Spreadsheet and Menubar embedded one'",
      "     VISIBLE:  'one', cursor=1",
+     "SPEECH OUTPUT: 'menu'",
      "SPEECH OUTPUT: 'one'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
 sequence.append(utils.AssertPresentationAction(
     "15. Move to two",
-    ["BRAILLE LINE:  'two'",
+    ["BRAILLE LINE:  'ARIA Spreadsheet and Menubar embedded two'",
+     "     VISIBLE:  'two', cursor=1",
+     "BRAILLE LINE:  'ARIA Spreadsheet and Menubar embedded two'",
      "     VISIBLE:  'two', cursor=1",
      "SPEECH OUTPUT: 'two'"]))
 
diff --git a/test/keystrokes/firefox/aria_slider.py b/test/keystrokes/firefox/aria_slider.py
index 1c8beab..aebdb90 100644
--- a/test/keystrokes/firefox/aria_slider.py
+++ b/test/keystrokes/firefox/aria_slider.py
@@ -11,7 +11,7 @@ sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Tab"))
 sequence.append(utils.AssertPresentationAction(
     "1. tab to slider",
-    ["BRAILLE LINE:  '0 Move slider left My slider 10% slider'",
+    ["BRAILLE LINE:  'My slider 10% slider'",
      "     VISIBLE:  'My slider 10% slider', cursor=1",
      "BRAILLE LINE:  'Focus mode'",
      "     VISIBLE:  'Focus mode', cursor=0",
@@ -22,7 +22,7 @@ sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("KP_Enter"))
 sequence.append(utils.AssertPresentationAction(
     "2. basic whereAmI",
-    ["BRAILLE LINE:  '0 Move slider left My slider 10% slider'",
+    ["BRAILLE LINE:  'My slider 10% slider'",
      "     VISIBLE:  'My slider 10% slider', cursor=1",
      "BRAILLE LINE:  'My slider 10% slider'",
      "     VISIBLE:  'My slider 10% slider', cursor=1",
diff --git a/test/keystrokes/firefox/aria_slider_dojo.py b/test/keystrokes/firefox/aria_slider_dojo.py
index 895669a..c9cf222 100644
--- a/test/keystrokes/firefox/aria_slider_dojo.py
+++ b/test/keystrokes/firefox/aria_slider_dojo.py
@@ -57,10 +57,10 @@ sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Tab"))
 sequence.append(utils.AssertPresentationAction(
     "6. Move to entry",
-    ["BRAILLE LINE:  'Slider1 Value: 10.0% $l rdonly'",
-     "     VISIBLE:  'Slider1 Value: 10.0% $l rdonly', cursor=21",
-     "BRAILLE LINE:  'Slider1 Value: 10.0% $l rdonly'",
-     "     VISIBLE:  'Slider1 Value: 10.0% $l rdonly', cursor=21",
+    ["BRAILLE LINE:  'Slider1 Value: 10.0% rdonly'",
+     "     VISIBLE:  'Slider1 Value: 10.0% rdonly', cursor=21",
+     "BRAILLE LINE:  'Slider1 Value: 10.0% rdonly'",
+     "     VISIBLE:  'Slider1 Value: 10.0% rdonly', cursor=21",
      "SPEECH OUTPUT: 'Slider1 Value: read only entry 10.0% selected'"]))
 
 sequence.append(utils.StartRecordingAction())
diff --git a/test/keystrokes/firefox/aria_spinner_dojo.py b/test/keystrokes/firefox/aria_spinner_dojo.py
index c6003d2..e7fbfc2 100644
--- a/test/keystrokes/firefox/aria_spinner_dojo.py
+++ b/test/keystrokes/firefox/aria_spinner_dojo.py
@@ -13,8 +13,8 @@ sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Tab"))
 sequence.append(utils.AssertPresentationAction(
     "1. Tab to the first spinner",
-    ["BRAILLE LINE:  'Spinbox #1:   $l'",
-     "     VISIBLE:  'Spinbox #1:   $l', cursor=10",
+    ["BRAILLE LINE:  'Spinbox #1:  900 $l'",
+     "     VISIBLE:  'Spinbox #1:  900 $l', cursor=17",
      "BRAILLE LINE:  'Focus mode'",
      "     VISIBLE:  'Focus mode', cursor=0",
      "BRAILLE LINE:  'Spinbox #1:  900 $l'",
diff --git a/test/keystrokes/firefox/aria_tabcontainer_dojo.py 
b/test/keystrokes/firefox/aria_tabcontainer_dojo.py
index 57a18ef..e2ce2c1 100644
--- a/test/keystrokes/firefox/aria_tabcontainer_dojo.py
+++ b/test/keystrokes/firefox/aria_tabcontainer_dojo.py
@@ -14,12 +14,10 @@ sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Tab"))
 sequence.append(utils.AssertPresentationAction(
     "1. Tab to tab list",
-    ["BRAILLE LINE:  '  push button Tab 1 page tab Tab 2 page tab Tab 3 page tab Inlined Sub TabContainer 
page tab Sub TabContainer from href page tab SplitContainer from href page tab Embedded layout widgets page 
tab'",
-     "     VISIBLE:  'Tab 2 page tab Tab 3 page tab In', cursor=1",
+    ["BRAILLE LINE:  'Tab 2 page tab'",
+     "     VISIBLE:  'Tab 2 page tab', cursor=1",
      "BRAILLE LINE:  'Focus mode'",
      "     VISIBLE:  'Focus mode', cursor=0",
-     "BRAILLE LINE:  'Tab 2 page tab'",
-     "     VISIBLE:  'Tab 2 page tab', cursor=1",
      "SPEECH OUTPUT: 'Tab 2 page tab'",
      "SPEECH OUTPUT: 'Focus mode' voice=system"]))
 
@@ -27,8 +25,8 @@ sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Right"))
 sequence.append(utils.AssertPresentationAction(
     "2. Right arrow to next tab",
-    ["BRAILLE LINE:  'Tab 3 page tab'",
-     "     VISIBLE:  'Tab 3 page tab', cursor=1",
+    ["BRAILLE LINE:  'Tab 2 page tab'",
+     "     VISIBLE:  'Tab 2 page tab', cursor=1",
      "BRAILLE LINE:  'Tab 3 page tab'",
      "     VISIBLE:  'Tab 3 page tab', cursor=1",
      "SPEECH OUTPUT: 'Tab 3 page tab'"]))
@@ -39,8 +37,6 @@ sequence.append(utils.AssertPresentationAction(
     "3. Right arrow to next tab",
     ["BRAILLE LINE:  'Inlined Sub TabContainer page tab'",
      "     VISIBLE:  'Inlined Sub TabContainer page ta', cursor=1",
-     "BRAILLE LINE:  'Inlined Sub TabContainer page tab'",
-     "     VISIBLE:  'Inlined Sub TabContainer page ta', cursor=1",
      "SPEECH OUTPUT: 'Inlined Sub TabContainer page tab'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -49,8 +45,6 @@ sequence.append(utils.AssertPresentationAction(
     "4. Tab to contents",
     ["BRAILLE LINE:  'SubTab 2 page tab'",
      "     VISIBLE:  'SubTab 2 page tab', cursor=1",
-     "BRAILLE LINE:  'SubTab 2 page tab'",
-     "     VISIBLE:  'SubTab 2 page tab', cursor=1",
      "SPEECH OUTPUT: 'SubTab 2 page tab'"]))
 
 sequence.append(utils.AssertionSummaryAction())
diff --git a/test/keystrokes/firefox/aria_tabpanel.py b/test/keystrokes/firefox/aria_tabpanel.py
index ade5319..26bc015 100644
--- a/test/keystrokes/firefox/aria_tabpanel.py
+++ b/test/keystrokes/firefox/aria_tabpanel.py
@@ -17,6 +17,8 @@ sequence.append(utils.AssertPresentationAction(
     "1. Basic whereAmI",
     ["BRAILLE LINE:  'Tab Zero page tab'",
      "     VISIBLE:  'Tab Zero page tab', cursor=1",
+     "BRAILLE LINE:  'Tab Zero page tab'",
+     "     VISIBLE:  'Tab Zero page tab', cursor=1",
      "SPEECH OUTPUT: 'page tab list Tab Zero page tab 1 of 5'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -25,8 +27,6 @@ sequence.append(utils.AssertPresentationAction(
     "2. Right arrow to next tab",
     ["BRAILLE LINE:  'Tab One page tab'",
      "     VISIBLE:  'Tab One page tab', cursor=1",
-     "BRAILLE LINE:  'Tab One page tab'",
-     "     VISIBLE:  'Tab One page tab', cursor=1",
      "SPEECH OUTPUT: 'Tab One page tab'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -35,8 +35,6 @@ sequence.append(utils.AssertPresentationAction(
     "3. Right arrow to next tab",
     ["BRAILLE LINE:  'Tab Two page tab'",
      "     VISIBLE:  'Tab Two page tab', cursor=1",
-     "BRAILLE LINE:  'Tab Two page tab'",
-     "     VISIBLE:  'Tab Two page tab', cursor=1",
      "SPEECH OUTPUT: 'Tab Two page tab'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -56,12 +54,10 @@ sequence.append(utils.AssertPresentationAction(
     "5. Shift+Tab out of contents",
     ["BRAILLE LINE:  '&=y Internal Portal Bookmark radio button'",
      "     VISIBLE:  '&=y Internal Portal Bookmark rad', cursor=1",
-     "BRAILLE LINE:  'Tab Zero page tab Tab One page tab Tab Two page tab Tab Three page tab Tab Four page 
tab'",
-     "     VISIBLE:  'Tab Two page tab Tab Three page ', cursor=1",
-     "BRAILLE LINE:  'Focus mode'",
-     "     VISIBLE:  'Focus mode', cursor=0",
      "BRAILLE LINE:  'Tab Two page tab'",
      "     VISIBLE:  'Tab Two page tab', cursor=1",
+     "BRAILLE LINE:  'Focus mode'",
+     "     VISIBLE:  'Focus mode', cursor=0",
      "SPEECH OUTPUT: 'Tab Two page tab'",
      "SPEECH OUTPUT: 'Focus mode' voice=system"]))
 
@@ -69,8 +65,8 @@ sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Right"))
 sequence.append(utils.AssertPresentationAction(
     "6. Right arrow to next tab",
-    ["BRAILLE LINE:  'Tab Three page tab'",
-     "     VISIBLE:  'Tab Three page tab', cursor=1",
+    ["BRAILLE LINE:  'Tab Two page tab'",
+     "     VISIBLE:  'Tab Two page tab', cursor=1",
      "BRAILLE LINE:  'Tab Three page tab'",
      "     VISIBLE:  'Tab Three page tab', cursor=1",
      "SPEECH OUTPUT: 'Tab Three page tab'"]))
@@ -81,8 +77,6 @@ sequence.append(utils.AssertPresentationAction(
     "7. Right arrow to next tab",
     ["BRAILLE LINE:  'Tab Four page tab'",
      "     VISIBLE:  'Tab Four page tab', cursor=1",
-     "BRAILLE LINE:  'Tab Four page tab'",
-     "     VISIBLE:  'Tab Four page tab', cursor=1",
      "SPEECH OUTPUT: 'Tab Four page tab'"]))
 
 sequence.append(utils.AssertionSummaryAction())
diff --git a/test/keystrokes/firefox/aria_tabpanel2.py b/test/keystrokes/firefox/aria_tabpanel2.py
index 5de724a..6e27635 100644
--- a/test/keystrokes/firefox/aria_tabpanel2.py
+++ b/test/keystrokes/firefox/aria_tabpanel2.py
@@ -21,12 +21,10 @@ sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("<Control>Page_Down"))
 sequence.append(utils.AssertPresentationAction(
     "2. Ctrl Page Down to second tab",
-    ["BRAILLE LINE:  'Crust Veggies page tab Carnivore Delivery'",
-     "     VISIBLE:  'Veggies page tab Carnivore Deliv', cursor=1",
+    ["BRAILLE LINE:  'Veggies page tab'",
+     "     VISIBLE:  'Veggies page tab', cursor=1",
      "BRAILLE LINE:  'Focus mode'",
      "     VISIBLE:  'Focus mode', cursor=0",
-     "BRAILLE LINE:  'Veggies page tab'",
-     "     VISIBLE:  'Veggies page tab', cursor=1",
      "SPEECH OUTPUT: 'Veggies page tab'",
      "SPEECH OUTPUT: 'Focus mode' voice=system"]))
 
@@ -34,8 +32,8 @@ sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Right"))
 sequence.append(utils.AssertPresentationAction(
     "3. Right arrow to third tab",
-    ["BRAILLE LINE:  'Carnivore page tab'",
-     "     VISIBLE:  'Carnivore page tab', cursor=1",
+    ["BRAILLE LINE:  'Veggies page tab'",
+     "     VISIBLE:  'Veggies page tab', cursor=1",
      "BRAILLE LINE:  'Carnivore page tab'",
      "     VISIBLE:  'Carnivore page tab', cursor=1",
      "SPEECH OUTPUT: 'Carnivore page tab'"]))
@@ -54,8 +52,6 @@ sequence.append(utils.AssertPresentationAction(
     "5. Right arrow to fourth tab",
     ["BRAILLE LINE:  'Delivery page tab'",
      "     VISIBLE:  'Delivery page tab', cursor=1",
-     "BRAILLE LINE:  'Delivery page tab'",
-     "     VISIBLE:  'Delivery page tab', cursor=1",
      "SPEECH OUTPUT: 'Delivery page tab'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -64,8 +60,6 @@ sequence.append(utils.AssertPresentationAction(
     "6. Left arrow back to third tab",
     ["BRAILLE LINE:  'Carnivore page tab'",
      "     VISIBLE:  'Carnivore page tab', cursor=1",
-     "BRAILLE LINE:  'Carnivore page tab'",
-     "     VISIBLE:  'Carnivore page tab', cursor=1",
      "SPEECH OUTPUT: 'Carnivore page tab'"]))
 
 sequence.append(utils.StartRecordingAction())
diff --git a/test/keystrokes/firefox/aria_tabpanel_text_dojo.py 
b/test/keystrokes/firefox/aria_tabpanel_text_dojo.py
index 796624a..b73eb09 100644
--- a/test/keystrokes/firefox/aria_tabpanel_text_dojo.py
+++ b/test/keystrokes/firefox/aria_tabpanel_text_dojo.py
@@ -7,6 +7,7 @@ import utils
 
 sequence = MacroSequence()
 
+sequence.append(PauseAction(3000))
 sequence.append(KeyComboAction("Tab"))
 sequence.append(KeyComboAction("Tab"))
 sequence.append(KeyComboAction("Tab"))
@@ -18,13 +19,11 @@ sequence.append(utils.AssertPresentationAction(
     "1. Space to press the Show TabContainer Dialog",
     ["BRAILLE LINE:  'TabContainer Dialog dialog'",
      "     VISIBLE:  'TabContainer Dialog dialog', cursor=1",
-     "BRAILLE LINE:  'First tab page tab Second tab page tab'",
-     "     VISIBLE:  'First tab page tab Second tab pa', cursor=1",
-     "BRAILLE LINE:  'Focus mode'",
-     "     VISIBLE:  'Focus mode', cursor=0",
      "BRAILLE LINE:  'First tab page tab'",
      "     VISIBLE:  'First tab page tab', cursor=1",
-     "SPEECH OUTPUT: 'TabContainer Dialog First tab Second tab This is the first tab. Lorem ipsum dolor sit 
amet, consectetuer adipiscing elit. Aenean semper sagittis velit. Cras in mi. Duis porta mauris ut ligula. 
Proin porta rutrum lacus. Etiam consequat scelerisque quam. Nulla facilisi. Maecenas luctus venenatis nulla. 
In sit amet dui non mi semper iaculis. Sed molestie tortor at ipsum. Morbi dictum rutrum magna. Sed vitae 
risus. '",
+     "BRAILLE LINE:  'Focus mode'",
+     "     VISIBLE:  'Focus mode', cursor=0",
+     "SPEECH OUTPUT: 'TabContainer Dialog This is the first tab.  Lorem ipsum dolor sit amet, consectetuer 
adipiscing elit. Aenean semper sagittis velit. Cras in mi. Duis porta mauris ut ligula. Proin porta rutrum 
lacus. Etiam consequat scelerisque quam. Nulla facilisi. Maecenas luctus venenatis nulla. In sit amet dui non 
mi semper iaculis. Sed molestie tortor at ipsum. Morbi dictum rutrum magna. Sed vitae risus.'",
      "SPEECH OUTPUT: 'First tab page tab'",
      "SPEECH OUTPUT: 'Focus mode' voice=system"]))
 
@@ -32,8 +31,8 @@ sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Right"))
 sequence.append(utils.AssertPresentationAction(
     "2. Right Arrow to the Second tab page",
-    ["BRAILLE LINE:  'Second tab page tab'",
-     "     VISIBLE:  'Second tab page tab', cursor=1",
+    ["BRAILLE LINE:  'First tab page tab'",
+     "     VISIBLE:  'First tab page tab', cursor=1",
      "BRAILLE LINE:  'Second tab page tab'",
      "     VISIBLE:  'Second tab page tab', cursor=1",
      "SPEECH OUTPUT: 'Second tab page tab'"]))
@@ -46,8 +45,8 @@ sequence.append(utils.AssertPresentationAction(
      "     VISIBLE:  'ipsum dolor sit amet', cursor=1",
      "BRAILLE LINE:  'Browse mode'",
      "     VISIBLE:  'Browse mode', cursor=0",
-     "BRAILLE LINE:  'Make it overflow. ipsum dolor sit amet, consectetuer adipiscing'",
-     "     VISIBLE:  'ipsum dolor sit amet, consectetu', cursor=1",
+     "BRAILLE LINE:  'ipsum dolor sit amet'",
+     "     VISIBLE:  'ipsum dolor sit amet', cursor=1",
      "SPEECH OUTPUT: 'ipsum dolor sit amet link'",
      "SPEECH OUTPUT: 'Browse mode' voice=system"]))
 
diff --git a/test/keystrokes/firefox/aria_toolbar_dojo.py b/test/keystrokes/firefox/aria_toolbar_dojo.py
index b4a830a..f69bbcb 100644
--- a/test/keystrokes/firefox/aria_toolbar_dojo.py
+++ b/test/keystrokes/firefox/aria_toolbar_dojo.py
@@ -37,20 +37,9 @@ sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
 sequence.append(utils.AssertPresentationAction(
     "4. Down Arrow",
-    ["BRAILLE LINE:  'Buttons: Copy Toggles: Italic Dropdowns: TooltipDialog ColorPalette  Combos: Menu save 
options push button Menu2 push button save options2 push button '",
-     "     VISIBLE:  'Buttons: Copy Toggles: Italic Dr', cursor=1",
-     "SPEECH OUTPUT: 'Buttons:'",
-     "SPEECH OUTPUT: 'Copy'",
-     "SPEECH OUTPUT: 'Toggles:'",
-     "SPEECH OUTPUT: 'Italic'",
-     "SPEECH OUTPUT: 'Dropdowns:'",
-     "SPEECH OUTPUT: 'TooltipDialog'",
-     "SPEECH OUTPUT: 'ColorPalette'",
-     "SPEECH OUTPUT: 'Combos:'",
-     "SPEECH OUTPUT: 'Menu'",
-     "SPEECH OUTPUT: 'save options push button'",
-     "SPEECH OUTPUT: 'Menu2 push button'",
-     "SPEECH OUTPUT: 'save options2 push button'"]))
+    ["BRAILLE LINE:  'tool bar'",
+     "     VISIBLE:  'tool bar', cursor=1",
+     "SPEECH OUTPUT: 'tool bar'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
diff --git a/test/keystrokes/firefox/aria_tree.py b/test/keystrokes/firefox/aria_tree.py
index 357b14d..526830a 100644
--- a/test/keystrokes/firefox/aria_tree.py
+++ b/test/keystrokes/firefox/aria_tree.py
@@ -36,8 +36,6 @@ sequence.append(utils.AssertPresentationAction(
     "3. Down arrow to oranges",
     ["BRAILLE LINE:  'Oranges list item'",
      "     VISIBLE:  'Oranges list item', cursor=1",
-     "BRAILLE LINE:  'Oranges list item'",
-     "     VISIBLE:  'Oranges list item', cursor=1",
      "SPEECH OUTPUT: 'Oranges tree level 2'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -46,8 +44,6 @@ sequence.append(utils.AssertPresentationAction(
     "4. Down arrow to pineapples",
     ["BRAILLE LINE:  'Pineapples list item'",
      "     VISIBLE:  'Pineapples list item', cursor=1",
-     "BRAILLE LINE:  'Pineapples list item'",
-     "     VISIBLE:  'Pineapples list item', cursor=1",
      "SPEECH OUTPUT: 'Pineapples'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -72,8 +68,6 @@ sequence.append(utils.AssertPresentationAction(
     "7. Down arrow to macintosh",
     ["BRAILLE LINE:  'Macintosh list item'",
      "     VISIBLE:  'Macintosh list item', cursor=1",
-     "BRAILLE LINE:  'Macintosh list item'",
-     "     VISIBLE:  'Macintosh list item', cursor=1",
      "SPEECH OUTPUT: 'Macintosh tree level 3'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -98,8 +92,6 @@ sequence.append(utils.AssertPresentationAction(
     "10. Down arrow to washington state",
     ["BRAILLE LINE:  'Washington State list item'",
      "     VISIBLE:  'Washington State list item', cursor=1",
-     "BRAILLE LINE:  'Washington State list item'",
-     "     VISIBLE:  'Washington State list item', cursor=1",
      "SPEECH OUTPUT: 'Washington State tree level 4'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -108,8 +100,6 @@ sequence.append(utils.AssertPresentationAction(
     "11. Down arrow to michigan",
     ["BRAILLE LINE:  'Michigan list item'",
      "     VISIBLE:  'Michigan list item', cursor=1",
-     "BRAILLE LINE:  'Michigan list item'",
-     "     VISIBLE:  'Michigan list item', cursor=1",
      "SPEECH OUTPUT: 'Michigan'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -118,8 +108,6 @@ sequence.append(utils.AssertPresentationAction(
     "12. Down arrow to new york",
     ["BRAILLE LINE:  'New York list item'",
      "     VISIBLE:  'New York list item', cursor=1",
-     "BRAILLE LINE:  'New York list item'",
-     "     VISIBLE:  'New York list item', cursor=1",
      "SPEECH OUTPUT: 'New York'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -128,8 +116,6 @@ sequence.append(utils.AssertPresentationAction(
     "13. Down arrow to fuji",
     ["BRAILLE LINE:  'Fuji list item'",
      "     VISIBLE:  'Fuji list item', cursor=1",
-     "BRAILLE LINE:  'Fuji list item'",
-     "     VISIBLE:  'Fuji list item', cursor=1",
      "SPEECH OUTPUT: 'Fuji tree level 3'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -138,8 +124,6 @@ sequence.append(utils.AssertPresentationAction(
     "14. Down arrow to bananas",
     ["BRAILLE LINE:  'Bananas list item'",
      "     VISIBLE:  'Bananas list item', cursor=1",
-     "BRAILLE LINE:  'Bananas list item'",
-     "     VISIBLE:  'Bananas list item', cursor=1",
      "SPEECH OUTPUT: 'Bananas tree level 2'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -148,8 +132,6 @@ sequence.append(utils.AssertPresentationAction(
     "15. Down arrow to pears",
     ["BRAILLE LINE:  'Pears list item'",
      "     VISIBLE:  'Pears list item', cursor=1",
-     "BRAILLE LINE:  'Pears list item'",
-     "     VISIBLE:  'Pears list item', cursor=1",
      "SPEECH OUTPUT: 'Pears'"]))
 
 sequence.append(utils.StartRecordingAction())
diff --git a/test/keystrokes/firefox/aria_tree_dojo.py b/test/keystrokes/firefox/aria_tree_dojo.py
index 97be6b3..86626db 100644
--- a/test/keystrokes/firefox/aria_tree_dojo.py
+++ b/test/keystrokes/firefox/aria_tree_dojo.py
@@ -18,8 +18,6 @@ sequence.append(utils.AssertPresentationAction(
      "     VISIBLE:  'before:  $l', cursor=9",
      "BRAILLE LINE:  'Continents expanded list item'",
      "     VISIBLE:  'Continents expanded list item', cursor=1",
-     "BRAILLE LINE:  'Continents expanded list item'",
-     "     VISIBLE:  'Continents expanded list item', cursor=1",
      "SPEECH OUTPUT: 'Continents expanded tree level 1'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -28,8 +26,6 @@ sequence.append(utils.AssertPresentationAction(
     "2. Down arrow to Africa",
     ["BRAILLE LINE:  'Africa collapsed list item'",
      "     VISIBLE:  'Africa collapsed list item', cursor=1",
-     "BRAILLE LINE:  'Africa collapsed list item'",
-     "     VISIBLE:  'Africa collapsed list item', cursor=1",
      "SPEECH OUTPUT: 'Africa collapsed tree level 2'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -54,8 +50,6 @@ sequence.append(utils.AssertPresentationAction(
     "5. Down arrow to Egypt",
     ["BRAILLE LINE:  'Egypt list item'",
      "     VISIBLE:  'Egypt list item', cursor=1",
-     "BRAILLE LINE:  'Egypt list item'",
-     "     VISIBLE:  'Egypt list item', cursor=1",
      "SPEECH OUTPUT: 'Egypt tree level 3'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -64,8 +58,6 @@ sequence.append(utils.AssertPresentationAction(
     "6. Down arrow to Kenya",
     ["BRAILLE LINE:  'Kenya collapsed list item'",
      "     VISIBLE:  'Kenya collapsed list item', cursor=1",
-     "BRAILLE LINE:  'Kenya collapsed list item'",
-     "     VISIBLE:  'Kenya collapsed list item', cursor=1",
      "SPEECH OUTPUT: 'Kenya collapsed'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -90,8 +82,6 @@ sequence.append(utils.AssertPresentationAction(
     "9. Down arrow to Sudan",
     ["BRAILLE LINE:  'Sudan collapsed list item'",
      "     VISIBLE:  'Sudan collapsed list item', cursor=1",
-     "BRAILLE LINE:  'Sudan collapsed list item'",
-     "     VISIBLE:  'Sudan collapsed list item', cursor=1",
      "SPEECH OUTPUT: 'Sudan collapsed'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -100,8 +90,6 @@ sequence.append(utils.AssertPresentationAction(
     "10. Down arrow to Asia",
     ["BRAILLE LINE:  'Asia collapsed list item'",
      "     VISIBLE:  'Asia collapsed list item', cursor=1",
-     "BRAILLE LINE:  'Asia collapsed list item'",
-     "     VISIBLE:  'Asia collapsed list item', cursor=1",
      "SPEECH OUTPUT: 'Asia collapsed tree level 2'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -118,8 +106,6 @@ sequence.append(utils.AssertPresentationAction(
     "12. Down arrow to China",
     ["BRAILLE LINE:  'China list item'",
      "     VISIBLE:  'China list item', cursor=1",
-     "BRAILLE LINE:  'China list item'",
-     "     VISIBLE:  'China list item', cursor=1",
      "SPEECH OUTPUT: 'China tree level 3'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -128,8 +114,6 @@ sequence.append(utils.AssertPresentationAction(
     "13. Down arrow to India",
     ["BRAILLE LINE:  'India list item'",
      "     VISIBLE:  'India list item', cursor=1",
-     "BRAILLE LINE:  'India list item'",
-     "     VISIBLE:  'India list item', cursor=1",
      "SPEECH OUTPUT: 'India'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -138,8 +122,6 @@ sequence.append(utils.AssertPresentationAction(
     "14. Down arrow to Russia",
     ["BRAILLE LINE:  'Russia list item'",
      "     VISIBLE:  'Russia list item', cursor=1",
-     "BRAILLE LINE:  'Russia list item'",
-     "     VISIBLE:  'Russia list item', cursor=1",
      "SPEECH OUTPUT: 'Russia'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -148,8 +130,6 @@ sequence.append(utils.AssertPresentationAction(
     "15. Down arrow to Mongolia",
     ["BRAILLE LINE:  'Mongolia list item'",
      "     VISIBLE:  'Mongolia list item', cursor=1",
-     "BRAILLE LINE:  'Mongolia list item'",
-     "     VISIBLE:  'Mongolia list item', cursor=1",
      "SPEECH OUTPUT: 'Mongolia'"]))
 
 sequence.append(utils.AssertionSummaryAction())
diff --git a/test/keystrokes/firefox/aria_treegrid.py b/test/keystrokes/firefox/aria_treegrid.py
index 78d4741..6cd5534 100644
--- a/test/keystrokes/firefox/aria_treegrid.py
+++ b/test/keystrokes/firefox/aria_treegrid.py
@@ -11,10 +11,11 @@ sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Tab"))
 sequence.append(utils.AssertPresentationAction(
     "1. Navigate to the treegrid",
-    ["BRAILLE LINE:  '+A Question of Love'",
-     "     VISIBLE:  '+A Question of Love', cursor=1",
+    ["BRAILLE LINE:  '+A Question of Love table cell'",
+     "     VISIBLE:  '+A Question of Love table cell', cursor=1",
      "BRAILLE LINE:  'Focus mode'",
      "     VISIBLE:  'Focus mode', cursor=0",
+     "SPEECH OUTPUT: 'collapsed'",
      "SPEECH OUTPUT: '+A Question of Love'",
      "SPEECH OUTPUT: 'Focus mode' voice=system"]))
 
@@ -22,10 +23,11 @@ sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
 sequence.append(utils.AssertPresentationAction(
     "2. Down Arrow",
-    ["BRAILLE LINE:  '+A Question of Love'",
-     "     VISIBLE:  '+A Question of Love', cursor=1",
+    ["BRAILLE LINE:  '+A Question of Love table cell'",
+     "     VISIBLE:  '+A Question of Love table cell', cursor=1",
      "BRAILLE LINE:  '+ Piece of Peace table cell'",
      "     VISIBLE:  '+ Piece of Peace table cell', cursor=1",
+     "SPEECH OUTPUT: 'collapsed'",
      "SPEECH OUTPUT: '+ Piece of Peace'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -34,6 +36,7 @@ sequence.append(utils.AssertPresentationAction(
     "3. Down Arrow",
     ["BRAILLE LINE:  '+ International Law table cell'",
      "     VISIBLE:  '+ International Law table cell', cursor=1",
+     "SPEECH OUTPUT: 'collapsed'",
      "SPEECH OUTPUT: '+ International Law'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -42,6 +45,7 @@ sequence.append(utils.AssertPresentationAction(
     "4. Up Arrow",
     ["BRAILLE LINE:  '+ Piece of Peace table cell'",
      "     VISIBLE:  '+ Piece of Peace table cell', cursor=1",
+     "SPEECH OUTPUT: 'collapsed'",
      "SPEECH OUTPUT: '+ Piece of Peace'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -50,6 +54,7 @@ sequence.append(utils.AssertPresentationAction(
     "5. Up Arrow",
     ["BRAILLE LINE:  '+A Question of Love table cell'",
      "     VISIBLE:  '+A Question of Love table cell', cursor=1",
+     "SPEECH OUTPUT: 'collapsed'",
      "SPEECH OUTPUT: '+A Question of Love'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -66,8 +71,6 @@ sequence.append(utils.AssertPresentationAction(
     "7. Space to expand the current item",
     ["BRAILLE LINE:  '-A Question of Love table row'",
      "     VISIBLE:  '-A Question of Love table row', cursor=1",
-     "BRAILLE LINE:  '-A Question of Love table cell'",
-     "     VISIBLE:  '-A Question of Love table cell', cursor=1",
      "SPEECH OUTPUT: 'expanded'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -124,6 +127,7 @@ sequence.append(utils.AssertPresentationAction(
     "14. Up Arrow back to parent",
     ["BRAILLE LINE:  '-A Question of Love table cell'",
      "     VISIBLE:  '-A Question of Love table cell', cursor=1",
+     "SPEECH OUTPUT: 'expanded'",
      "SPEECH OUTPUT: '-A Question of Love'"]))
 
 sequence.append(utils.AssertionSummaryAction())
diff --git a/test/keystrokes/firefox/find_wiki.py b/test/keystrokes/firefox/find_wiki.py
index e2344c7..74a7168 100644
--- a/test/keystrokes/firefox/find_wiki.py
+++ b/test/keystrokes/firefox/find_wiki.py
@@ -27,14 +27,13 @@ sequence.append(utils.AssertPresentationAction(
     ["BRAILLE LINE:  'Welcome to Orca!'",
      "     VISIBLE:  'Welcome to Orca!', cursor=1",
      "SPEECH OUTPUT: '1.'",
-     "SPEECH OUTPUT: 'Welcome to Orca!'",
-     "SPEECH OUTPUT: 'link'"]))
+     "SPEECH OUTPUT: 'Welcome to Orca! link'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Return"))
 sequence.append(utils.AssertPresentationAction(
     "3. Return to next result",
-    ["BRAILLE LINE:  'Orca is a free, open source, flexible, extensible, and  $l'",
+    ["BRAILLE LINE:  'Orca is a free, open source, flexible, extensible, and '",
      "     VISIBLE:  'Orca is a free, open source, fle', cursor=1",
      "SPEECH OUTPUT: 'Orca is a free, open source, flexible, extensible, and'"]))
 
@@ -42,7 +41,7 @@ sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Return"))
 sequence.append(utils.AssertPresentationAction(
     "4. Return to next result",
-    ["BRAILLE LINE:  'synthesis, braille, and magnification, Orca helps provide  $l'",
+    ["BRAILLE LINE:  'synthesis, braille, and magnification, Orca helps provide '",
      "     VISIBLE:  's, braille, and magnification, O', cursor=32",
      "SPEECH OUTPUT: 'synthesis, braille, and magnification, Orca helps provide'"]))
 
@@ -50,7 +49,7 @@ sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Escape"))
 sequence.append(utils.AssertPresentationAction(
     "5. Escape to return to page content",
-    ["BRAILLE LINE:  'synthesis, braille, and magnification, Orca helps provide'",
+    ["BRAILLE LINE:  'synthesis, braille, and magnification, Orca helps provide '",
      "     VISIBLE:  'raille, and magnification, Orca ', cursor=32",
      "SPEECH OUTPUT: 'synthesis, braille, and magnification, Orca helps provide  selected'"]))
 
diff --git a/test/keystrokes/firefox/flat_review_combo_box.py 
b/test/keystrokes/firefox/flat_review_combo_box.py
index 44d47cc..a1a0ebf 100644
--- a/test/keystrokes/firefox/flat_review_combo_box.py
+++ b/test/keystrokes/firefox/flat_review_combo_box.py
@@ -14,7 +14,7 @@ sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("KP_8"))
 sequence.append(utils.AssertPresentationAction(
     "1. Flat review current line",
-    ["BRAILLE LINE:  'Severity: Severity normal combo box'",
+    ["BRAILLE LINE:  'Severity normal combo box'",
      "     VISIBLE:  'Severity normal combo box', cursor=10",
      "BRAILLE LINE:  'Severity Severity :  normal $l'",
      "     VISIBLE:  'Severity Severity :  normal $l', cursor=22",
diff --git a/test/keystrokes/firefox/focus_tracking_descriptions.py 
b/test/keystrokes/firefox/focus_tracking_descriptions.py
index 7cb7891..6bc479d 100644
--- a/test/keystrokes/firefox/focus_tracking_descriptions.py
+++ b/test/keystrokes/firefox/focus_tracking_descriptions.py
@@ -13,37 +13,37 @@ sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Tab"))
 sequence.append(utils.AssertPresentationAction(
     "1. Tab",
-    ["BRAILLE LINE:  'Foo, Bar, and Baz.'",
-     "     VISIBLE:  'Foo, Bar, and Baz.', cursor=1",
-     "BRAILLE LINE:  'Foo, Bar, and Baz.'",
-     "     VISIBLE:  'Foo, Bar, and Baz.', cursor=1",
+    ["BRAILLE LINE:  'Foo'",
+     "     VISIBLE:  'Foo', cursor=1",
+     "BRAILLE LINE:  'Foo'",
+     "     VISIBLE:  'Foo', cursor=1",
      "SPEECH OUTPUT: 'Foo link Title of the Foo link.'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Tab"))
 sequence.append(utils.AssertPresentationAction(
     "2. Tab",
-    ["BRAILLE LINE:  'Foo, Bar, and Baz.'",
-     "     VISIBLE:  'Foo, Bar, and Baz.', cursor=6",
-     "BRAILLE LINE:  'Foo, Bar, and Baz.'",
-     "     VISIBLE:  'Foo, Bar, and Baz.', cursor=6",
+    ["BRAILLE LINE:  'Bar'",
+     "     VISIBLE:  'Bar', cursor=1",
+     "BRAILLE LINE:  'Bar'",
+     "     VISIBLE:  'Bar', cursor=1",
      "SPEECH OUTPUT: 'Bar link ARIA description text.'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Tab"))
 sequence.append(utils.AssertPresentationAction(
     "3. Tab",
-    ["BRAILLE LINE:  'Foo, Bar, and Baz.'",
-     "     VISIBLE:  'Foo, Bar, and Baz.', cursor=15",
-     "BRAILLE LINE:  'Foo, Bar, and Baz.'",
-     "     VISIBLE:  'Foo, Bar, and Baz.', cursor=15",
+    ["BRAILLE LINE:  'Baz'",
+     "     VISIBLE:  'Baz', cursor=1",
+     "BRAILLE LINE:  'Baz'",
+     "     VISIBLE:  'Baz', cursor=1",
      "SPEECH OUTPUT: 'Baz link Title of the Baz link.'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Tab"))
 sequence.append(utils.AssertPresentationAction(
     "4. Tab",
-    ["BRAILLE LINE:  '< > Title of the Black checkbox check box Black < > Title of the White checkbox check 
box White < > Title of the Grey checkbox check box Grey'",
+    ["BRAILLE LINE:  '< > Title of the Black checkbox check box'",
      "     VISIBLE:  '< > Title of the Black checkbox ', cursor=1",
      "SPEECH OUTPUT: 'Title of the Black checkbox check box not checked'"]))
 
@@ -51,7 +51,7 @@ sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Tab"))
 sequence.append(utils.AssertPresentationAction(
     "5. Tab",
-    ["BRAILLE LINE:  '< > Title of the Black checkbox check box Black < > Title of the White checkbox check 
box White < > Title of the Grey checkbox check box Grey'",
+    ["BRAILLE LINE:  '< > Title of the White checkbox check box'",
      "     VISIBLE:  '< > Title of the White checkbox ', cursor=1",
      "SPEECH OUTPUT: 'Title of the White checkbox check box not checked ARIA description text.'"]))
 
@@ -59,7 +59,7 @@ sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Tab"))
 sequence.append(utils.AssertPresentationAction(
     "6. Tab",
-    ["BRAILLE LINE:  '< > Title of the Black checkbox check box Black < > Title of the White checkbox check 
box White < > Title of the Grey checkbox check box Grey'",
+    ["BRAILLE LINE:  '< > Title of the Grey checkbox check box'",
      "     VISIBLE:  '< > Title of the Grey checkbox c', cursor=1",
      "SPEECH OUTPUT: 'Title of the Grey checkbox check box not checked'"]))
 
@@ -67,23 +67,23 @@ sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Tab"))
 sequence.append(utils.AssertPresentationAction(
     "7. Tab",
-    ["BRAILLE LINE:  '< > Black check box < > White check box < > Grey check box'",
-     "     VISIBLE:  '< > Black check box < > White ch', cursor=1",
+    ["BRAILLE LINE:  '< > Black check box'",
+     "     VISIBLE:  '< > Black check box', cursor=1",
      "SPEECH OUTPUT: 'Black check box not checked'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Tab"))
 sequence.append(utils.AssertPresentationAction(
     "8. Tab",
-    ["BRAILLE LINE:  '< > Black check box < > White check box < > Grey check box'",
-     "     VISIBLE:  '< > White check box < > Grey che', cursor=1",
+    ["BRAILLE LINE:  '< > White check box'",
+     "     VISIBLE:  '< > White check box', cursor=1",
      "SPEECH OUTPUT: 'White check box not checked ARIA description text.'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Tab"))
 sequence.append(utils.AssertPresentationAction(
     "9. Tab",
-    ["BRAILLE LINE:  '< > Black check box < > White check box < > Grey check box'",
+    ["BRAILLE LINE:  '< > Grey check box'",
      "     VISIBLE:  '< > Grey check box', cursor=1",
      "SPEECH OUTPUT: 'Grey check box not checked Title of the Grey checkbox'"]))
 
diff --git a/test/keystrokes/firefox/focus_tracking_imagemap.py 
b/test/keystrokes/firefox/focus_tracking_imagemap.py
index d81f3ab..819dfe7 100644
--- a/test/keystrokes/firefox/focus_tracking_imagemap.py
+++ b/test/keystrokes/firefox/focus_tracking_imagemap.py
@@ -15,16 +15,16 @@ sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Tab"))
 sequence.append(utils.AssertPresentationAction(
     "1. Tab",
-    ["BRAILLE LINE:  'Test: z y x w v u t s r q p o n m l k j i h g f e d c b a'",
-     "     VISIBLE:  'z y x w v u t s r q p o n m l k ', cursor=1",
+    ["BRAILLE LINE:  'z image map link'",
+     "     VISIBLE:  'z image map link', cursor=1",
      "SPEECH OUTPUT: 'z image map link rect'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Tab"))
 sequence.append(utils.AssertPresentationAction(
     "2. Tab",
-    ["BRAILLE LINE:  'Test: z y x w v u t s r q p o n m l k j i h g f e d c b a'",
-     "     VISIBLE:  'y x w v u t s r q p o n m l k j ', cursor=1",
+    ["BRAILLE LINE:  'y image map link'",
+     "     VISIBLE:  'y image map link', cursor=1",
      "SPEECH OUTPUT: 'y image map link rect'"]))
 
 sequence.append(KeyComboAction("Tab"))
@@ -55,8 +55,8 @@ sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Tab"))
 sequence.append(utils.AssertPresentationAction(
     "3. Tab",
-    ["BRAILLE LINE:  'Test: z y x w v u t s r q p o n m l k j i h g f e d c b a'",
-     "     VISIBLE:  'a', cursor=1",
+    ["BRAILLE LINE:  'a image map link'",
+     "     VISIBLE:  'a image map link', cursor=1",
      "SPEECH OUTPUT: 'a image map link rect'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -65,8 +65,7 @@ sequence.append(utils.AssertPresentationAction(
     "4. Tab",
     ["BRAILLE LINE:  'wk09_frozenmovie'",
      "     VISIBLE:  'wk09_frozenmovie', cursor=1",
-     "SPEECH OUTPUT: 'wk09_frozenmovie'",
-     "SPEECH OUTPUT: 'link image'"]))
+     "SPEECH OUTPUT: 'wk09_frozenmovie link'"]))
 
 sequence.append(utils.AssertionSummaryAction())
 sequence.start()
diff --git a/test/keystrokes/firefox/focus_tracking_link_child_of_body.py 
b/test/keystrokes/firefox/focus_tracking_link_child_of_body.py
index 02d7b12..d3f7582 100644
--- a/test/keystrokes/firefox/focus_tracking_link_child_of_body.py
+++ b/test/keystrokes/firefox/focus_tracking_link_child_of_body.py
@@ -15,26 +15,24 @@ sequence.append(utils.AssertPresentationAction(
     "1. Top of file",
     ["BRAILLE LINE:  'Foo'",
      "     VISIBLE:  'Foo', cursor=1",
-     "SPEECH OUTPUT: 'Foo'",
-     "SPEECH OUTPUT: 'link'"]))
+     "SPEECH OUTPUT: 'Foo link'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("<Shift>Tab"))
 sequence.append(utils.AssertPresentationAction(
     "2. Shift Tab",
-    ["KNOWN ISSUE: Extra 'F' in the braille.",
-     "BRAILLE LINE:  'F Foo'",
-     "     VISIBLE:  'F Foo', cursor=0",
+    ["BRAILLE LINE:  ''",
+     "     VISIBLE:  '', cursor=1",
      "SPEECH OUTPUT: 'document frame'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Tab"))
 sequence.append(utils.AssertPresentationAction(
     "3. Tab",
-    ["BRAILLE LINE:  'F Foo'",
-     "     VISIBLE:  'F Foo', cursor=1",
-     "BRAILLE LINE:  'F Foo'",
-     "     VISIBLE:  'F Foo', cursor=1",
+    ["BRAILLE LINE:  'Foo'",
+     "     VISIBLE:  'Foo', cursor=1",
+     "BRAILLE LINE:  'Foo'",
+     "     VISIBLE:  'Foo', cursor=1",
      "SPEECH OUTPUT: 'Foo link'"]))
 
 sequence.append(utils.AssertionSummaryAction())
diff --git a/test/keystrokes/firefox/focus_tracking_links.py b/test/keystrokes/firefox/focus_tracking_links.py
index a41fa06..0b40e7e 100644
--- a/test/keystrokes/firefox/focus_tracking_links.py
+++ b/test/keystrokes/firefox/focus_tracking_links.py
@@ -15,8 +15,7 @@ sequence.append(utils.AssertPresentationAction(
     "1. Top of file",
     ["BRAILLE LINE:  'Hello world, this is a test.'",
      "     VISIBLE:  'Hello world, this is a test.', cursor=1",
-     "SPEECH OUTPUT: 'Hello world'",
-     "SPEECH OUTPUT: 'link'",
+     "SPEECH OUTPUT: 'Hello world link'",
      "SPEECH OUTPUT: ', this is a test.'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -25,8 +24,7 @@ sequence.append(utils.AssertPresentationAction(
     "2. Line Down to the Foo link",
     ["BRAILLE LINE:  'Foo'",
      "     VISIBLE:  'Foo', cursor=1",
-     "SPEECH OUTPUT: 'Foo'",
-     "SPEECH OUTPUT: 'link'"]))
+     "SPEECH OUTPUT: 'Foo link'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Tab"))
diff --git a/test/keystrokes/firefox/html_role_combo_box.py b/test/keystrokes/firefox/html_role_combo_box.py
index 1709cf2..d9f00b7 100644
--- a/test/keystrokes/firefox/html_role_combo_box.py
+++ b/test/keystrokes/firefox/html_role_combo_box.py
@@ -13,7 +13,7 @@ sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Tab"))
 sequence.append(utils.AssertPresentationAction(
     "1. Tab to Severity combo box",
-    ["BRAILLE LINE:  'Severity: Severity normal combo box'",
+    ["BRAILLE LINE:  'Severity normal combo box'",
      "     VISIBLE:  'Severity normal combo box', cursor=10",
      "BRAILLE LINE:  'Focus mode'",
      "     VISIBLE:  'Focus mode', cursor=0",
@@ -24,7 +24,7 @@ sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("KP_Enter"))
 sequence.append(utils.AssertPresentationAction(
     "2. Basic Where Am I",
-    ["BRAILLE LINE:  'Severity: Severity normal combo box'",
+    ["BRAILLE LINE:  'Severity normal combo box'",
      "     VISIBLE:  'Severity normal combo box', cursor=10",
      "BRAILLE LINE:  'Severity normal combo box'",
      "     VISIBLE:  'Severity normal combo box', cursor=10",
@@ -38,8 +38,8 @@ sequence.append(utils.AssertPresentationAction(
      "     VISIBLE:  'Priority', cursor=1",
      "BRAILLE LINE:  'Browse mode'",
      "     VISIBLE:  'Browse mode', cursor=0",
-     "BRAILLE LINE:  'Priority: Normal combo box'",
-     "     VISIBLE:  'Priority: Normal combo box', cursor=1",
+     "BRAILLE LINE:  'Priority'",
+     "     VISIBLE:  'Priority', cursor=1",
      "SPEECH OUTPUT: 'Priority link'",
      "SPEECH OUTPUT: 'Browse mode' voice=system"]))
 
@@ -60,49 +60,49 @@ sequence.append(utils.AssertPresentationAction(
     "5. Tab to Resolution combo box",
     ["BRAILLE LINE:  'Priority: Normal combo box'",
      "     VISIBLE:  'Priority: Normal combo box', cursor=11",
-     "BRAILLE LINE:  'FIXED combo box'",
-     "     VISIBLE:  'FIXED combo box', cursor=1",
+     "BRAILLE LINE:  'Resolution: FIXED combo box'",
+     "     VISIBLE:  'Resolution: FIXED combo box', cursor=13",
      "SPEECH OUTPUT: 'Resolution: FIXED combo box'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
 sequence.append(utils.AssertPresentationAction(
     "6. Change selection Down: WONTFIX",
-    ["BRAILLE LINE:  'WONTFIX combo box'",
-     "     VISIBLE:  'WONTFIX combo box', cursor=1",
+    ["BRAILLE LINE:  'Resolution: WONTFIX combo box'",
+     "     VISIBLE:  'Resolution: WONTFIX combo box', cursor=1",
      "SPEECH OUTPUT: 'WONTFIX'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
 sequence.append(utils.AssertPresentationAction(
     "7. Change selection Up: FIXED",
-    ["BRAILLE LINE:  'FIXED combo box'",
-     "     VISIBLE:  'FIXED combo box', cursor=1",
+    ["BRAILLE LINE:  'Resolution: FIXED combo box'",
+     "     VISIBLE:  'Resolution: FIXED combo box', cursor=13",
      "SPEECH OUTPUT: 'FIXED'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("<Alt>Down"))
 sequence.append(utils.AssertPresentationAction(
     "8. Alt Down to Expand",
-    ["KNOWN ISSUE: We are presenting nothing here",
+    ["KNOWN ISSUE: We are presenting nothing here because we don't get the needed event from Gecko",
      ""]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
 sequence.append(utils.AssertPresentationAction(
     "9. Change selection Down: WONTFIX",
-    ["BRAILLE LINE:  'WONTFIX combo box'",
-     "     VISIBLE:  'WONTFIX combo box', cursor=1",
+    ["BRAILLE LINE:  'Resolution: WONTFIX combo box'",
+     "     VISIBLE:  'Resolution: WONTFIX combo box', cursor=13",
      "SPEECH OUTPUT: 'WONTFIX'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Return"))
 sequence.append(utils.AssertPresentationAction(
     "10. Return to collapse combo box",
-    ["BRAILLE LINE:  'WONTFIX combo box'",
-     "     VISIBLE:  'WONTFIX combo box', cursor=1",
-     "BRAILLE LINE:  'WONTFIX combo box'",
-     "     VISIBLE:  'WONTFIX combo box', cursor=1",
+    ["BRAILLE LINE:  'Resolution: WONTFIX combo box'",
+     "     VISIBLE:  'Resolution: WONTFIX combo box', cursor=13",
+     "BRAILLE LINE:  'Resolution: WONTFIX combo box'",
+     "     VISIBLE:  'Resolution: WONTFIX combo box', cursor=13",
      "SPEECH OUTPUT: 'Resolution: WONTFIX combo box'",
      "SPEECH OUTPUT: 'collapsed'"]))
 
@@ -110,8 +110,8 @@ sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Tab"))
 sequence.append(utils.AssertPresentationAction(
     "11. Tab to Version combo box",
-    ["BRAILLE LINE:  '2.16 combo box'",
-     "     VISIBLE:  '2.16 combo box', cursor=1",
+    ["BRAILLE LINE:  'Version 2.16 combo box'",
+     "     VISIBLE:  'Version 2.16 combo box', cursor=9",
      "SPEECH OUTPUT: 'Version 2.16 combo box'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -128,11 +128,11 @@ sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Left"))
 sequence.append(utils.AssertPresentationAction(
     "13. Left out of combo box",
-    ["BRAILLE LINE:  '2.16 combo box'",
-     "     VISIBLE:  '2.16 combo box', cursor=1",
-     "BRAILLE LINE:  'Version 2.16 combo box'",
+    ["BRAILLE LINE:  'Version 2.16 combo box'",
      "     VISIBLE:  'Version 2.16 combo box', cursor=9",
-     "SPEECH OUTPUT: 'Version 2.16 combo box'"]))
+     "BRAILLE LINE:  'Version 2.16 combo box'",
+     "     VISIBLE:  'Version 2.16 combo box', cursor=7",
+     "SPEECH OUTPUT: 'n'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
diff --git a/test/keystrokes/firefox/html_role_links.py b/test/keystrokes/firefox/html_role_links.py
index 261a5d0..024252c 100644
--- a/test/keystrokes/firefox/html_role_links.py
+++ b/test/keystrokes/firefox/html_role_links.py
@@ -19,48 +19,48 @@ sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Tab"))
 sequence.append(utils.AssertPresentationAction(
     "2. Tab to anchors.html link",
-    ["BRAILLE LINE:  '• anchors.html'",
-     "     VISIBLE:  '• anchors.html', cursor=3",
-     "BRAILLE LINE:  '• anchors.html'",
-     "     VISIBLE:  '• anchors.html', cursor=3",
+    ["BRAILLE LINE:  'anchors.html'",
+     "     VISIBLE:  'anchors.html', cursor=1",
+     "BRAILLE LINE:  'anchors.html'",
+     "     VISIBLE:  'anchors.html', cursor=1",
      "SPEECH OUTPUT: 'anchors.html link'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Tab"))
 sequence.append(utils.AssertPresentationAction(
     "3. Tab to blockquotes.html link",
-    ["BRAILLE LINE:  '• blockquotes.html'",
-     "     VISIBLE:  '• blockquotes.html', cursor=3",
-     "BRAILLE LINE:  '• blockquotes.html'",
-     "     VISIBLE:  '• blockquotes.html', cursor=3",
+    ["BRAILLE LINE:  'blockquotes.html'",
+     "     VISIBLE:  'blockquotes.html', cursor=1",
+     "BRAILLE LINE:  'blockquotes.html'",
+     "     VISIBLE:  'blockquotes.html', cursor=1",
      "SPEECH OUTPUT: 'blockquotes.html link'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Tab"))
 sequence.append(utils.AssertPresentationAction(
     "4. Tab to bugzilla_top.html link",
-    ["BRAILLE LINE:  '• bugzilla_top.html'",
-     "     VISIBLE:  '• bugzilla_top.html', cursor=3",
-     "BRAILLE LINE:  '• bugzilla_top.html'",
-     "     VISIBLE:  '• bugzilla_top.html', cursor=3",
+    ["BRAILLE LINE:  'bugzilla_top.html'",
+     "     VISIBLE:  'bugzilla_top.html', cursor=1",
+     "BRAILLE LINE:  'bugzilla_top.html'",
+     "     VISIBLE:  'bugzilla_top.html', cursor=1",
      "SPEECH OUTPUT: 'bugzilla_top.html link'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("<Shift>Tab"))
 sequence.append(utils.AssertPresentationAction(
     "5. Shift Tab to blockquotes.html link",
-    ["BRAILLE LINE:  '• blockquotes.html'",
-     "     VISIBLE:  '• blockquotes.html', cursor=3",
-     "BRAILLE LINE:  '• blockquotes.html'",
-     "     VISIBLE:  '• blockquotes.html', cursor=3",
+    ["BRAILLE LINE:  'blockquotes.html'",
+     "     VISIBLE:  'blockquotes.html', cursor=1",
+     "BRAILLE LINE:  'blockquotes.html'",
+     "     VISIBLE:  'blockquotes.html', cursor=1",
      "SPEECH OUTPUT: 'blockquotes.html link'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("KP_Enter"))
 sequence.append(utils.AssertPresentationAction(
     "6. Basic Where Am I",
-    ["BRAILLE LINE:  '• blockquotes.html'",
-     "     VISIBLE:  '• blockquotes.html', cursor=3",
+    ["BRAILLE LINE:  'blockquotes.html'",
+     "     VISIBLE:  'blockquotes.html', cursor=1",
      "SPEECH OUTPUT: 'file link to blockquotes.html same site 1188 bytes'"]))
 
 sequence.append(KeyComboAction("Return"))
@@ -76,8 +76,7 @@ sequence.append(utils.AssertPresentationAction(
     ["BRAILLE LINE:  '• anchors.html'",
      "     VISIBLE:  '• anchors.html', cursor=1",
      "SPEECH OUTPUT: '•'",
-     "SPEECH OUTPUT: 'anchors.html'",
-     "SPEECH OUTPUT: 'link'"]))
+     "SPEECH OUTPUT: 'anchors.html link'"]))
 
 sequence.append(utils.AssertionSummaryAction())
 sequence.start()
diff --git a/test/keystrokes/firefox/html_role_list_item_where_am_i.py 
b/test/keystrokes/firefox/html_role_list_item_where_am_i.py
index e5820d5..fd66d6f 100644
--- a/test/keystrokes/firefox/html_role_list_item_where_am_i.py
+++ b/test/keystrokes/firefox/html_role_list_item_where_am_i.py
@@ -21,7 +21,7 @@ sequence.append(KeyComboAction("KP_Enter"))
 sequence.append(utils.AssertPresentationAction(
     "2. Basic Where Am I next item",
     ["BRAILLE LINE:  '• In a paragraph'",
-     "     VISIBLE:  '• In a paragraph', cursor=3",
+     "     VISIBLE:  '• In a paragraph', cursor=1",
      "SPEECH OUTPUT: 'list item • In a paragraph'"]))
 
 sequence.append(KeyComboAction("Down"))
@@ -30,7 +30,7 @@ sequence.append(KeyComboAction("KP_Enter"))
 sequence.append(utils.AssertPresentationAction(
     "3. Basic Where Am I next item",
     ["BRAILLE LINE:  '• In a section'",
-     "     VISIBLE:  '• In a section', cursor=3",
+     "     VISIBLE:  '• In a section', cursor=1",
      "SPEECH OUTPUT: 'list item • In a section'"]))
 
 sequence.append(KeyComboAction("Down"))
@@ -38,7 +38,7 @@ sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("KP_Enter"))
 sequence.append(utils.AssertPresentationAction(
     "4. Basic Where Am I next item",
-    ["BRAILLE LINE:  '1. A nested list item, not in a paragraph'",
+    ["BRAILLE LINE:  '1. A nested list item, not in a paragraph LEVEL 1'",
      "     VISIBLE:  '1. A nested list item, not in a ', cursor=1",
      "SPEECH OUTPUT: 'list item 1. A nested list item, not in a paragraph Nesting level 1'"]))
 
@@ -47,8 +47,8 @@ sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("KP_Enter"))
 sequence.append(utils.AssertPresentationAction(
     "5. Basic Where Am I next item",
-    ["BRAILLE LINE:  '2. A nested list item, in a paragraph'",
-     "     VISIBLE:  '2. A nested list item, in a para', cursor=4",
+    ["BRAILLE LINE:  '2. A nested list item, in a paragraph LEVEL 1'",
+     "     VISIBLE:  '2. A nested list item, in a para', cursor=1",
      "SPEECH OUTPUT: 'list item 2. A nested list item, in a paragraph Nesting level 1'"]))
 
 sequence.append(KeyComboAction("Down"))
@@ -56,8 +56,8 @@ sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("KP_Enter"))
 sequence.append(utils.AssertPresentationAction(
     "6. Basic Where Am I next item",
-    ["BRAILLE LINE:  '3. A nested list item, in a section'",
-     "     VISIBLE:  '3. A nested list item, in a sect', cursor=4",
+    ["BRAILLE LINE:  '3. A nested list item, in a section LEVEL 1'",
+     "     VISIBLE:  '3. A nested list item, in a sect', cursor=1",
      "SPEECH OUTPUT: 'list item 3. A nested list item, in a section Nesting level 1'"]))
 
 sequence.append(KeyComboAction("Down"))
@@ -66,7 +66,7 @@ sequence.append(KeyComboAction("KP_Enter"))
 sequence.append(utils.AssertPresentationAction(
     "7. Basic Where Am I next item",
     ["BRAILLE LINE:  '• In a paragraph that's in a section'",
-     "     VISIBLE:  '• In a paragraph that's in a sec', cursor=3",
+     "     VISIBLE:  '• In a paragraph that's in a sec', cursor=1",
      "SPEECH OUTPUT: 'list item • In a paragraph that's in a section'"]))
 
 sequence.append(utils.AssertionSummaryAction())
diff --git a/test/keystrokes/firefox/html_struct_nav_activate_link.py 
b/test/keystrokes/firefox/html_struct_nav_activate_link.py
index e6faab1..021356e 100644
--- a/test/keystrokes/firefox/html_struct_nav_activate_link.py
+++ b/test/keystrokes/firefox/html_struct_nav_activate_link.py
@@ -15,11 +15,9 @@ sequence.append(utils.AssertPresentationAction(
     "1. Press 3 to move to the heading at level 3",
     ["BRAILLE LINE:  '1. Anchors2.html h3'",
      "     VISIBLE:  '1. Anchors2.html h3', cursor=4",
-     "BRAILLE LINE:  '1. Anchors2.html h3'",
-     "     VISIBLE:  '1. Anchors2.html h3', cursor=4",
-     "SPEECH OUTPUT: 'Anchors2.html'",
-     "SPEECH OUTPUT: 'link'",
-     "SPEECH OUTPUT: 'heading level 3'"]))
+     "BRAILLE LINE:  'Anchors2.html h3'",
+     "     VISIBLE:  'Anchors2.html h3', cursor=1",
+     "SPEECH OUTPUT: 'Anchors2.html link heading level 3'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Return"))
@@ -29,6 +27,8 @@ sequence.append(utils.AssertPresentationAction(
      "     VISIBLE:  'Finished loading Links to test f', cursor=0",
      "BRAILLE LINE:  'Here are some of our local test files:'",
      "     VISIBLE:  'Here are some of our local test ', cursor=1",
+     "BRAILLE LINE:  'Here are some of our local test files:'",
+     "     VISIBLE:  'Here are some of our local test ', cursor=1",
     "SPEECH OUTPUT: 'Finished loading Links to test files.' voice=system",
     "SPEECH OUTPUT: 'Here are some of our local test files:'",
     "SPEECH OUTPUT: '•'",
@@ -78,7 +78,8 @@ sequence.append(utils.AssertPresentationAction(
     "SPEECH OUTPUT: 'link'",
     "SPEECH OUTPUT: '•'",
     "SPEECH OUTPUT: 'textattributes.html'",
-    "SPEECH OUTPUT: 'link'"]))
+    "SPEECH OUTPUT: 'link'",
+    "SPEECH OUTPUT: 'Here are some of our local test files:'"]))
 
 sequence.append(utils.AssertionSummaryAction())
 sequence.start()
diff --git a/test/keystrokes/firefox/html_struct_nav_blockquote.py 
b/test/keystrokes/firefox/html_struct_nav_blockquote.py
index d0af995..aa82355 100644
--- a/test/keystrokes/firefox/html_struct_nav_blockquote.py
+++ b/test/keystrokes/firefox/html_struct_nav_blockquote.py
@@ -67,7 +67,7 @@ sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("KP_Enter"))
 sequence.append(utils.AssertPresentationAction(
     "7. Basic Where Am I",
-    ["BRAILLE LINE:  'Now old lady, you have one last chance. Confess the heinous sin of heresy, reject the 
works of the'",
+    ["BRAILLE LINE:  'Now old lady, you have one last chance. Confess the heinous sin of heresy, reject the 
works of the '",
      "     VISIBLE:  'Now old lady, you have one last ', cursor=1",
      "SPEECH OUTPUT: 'Now old lady, you have one last chance. Confess the heinous sin of heresy, reject the 
works of the '"]))
 
diff --git a/test/keystrokes/firefox/html_struct_nav_bug_554616.py 
b/test/keystrokes/firefox/html_struct_nav_bug_554616.py
index d8f9257..4ad927d 100644
--- a/test/keystrokes/firefox/html_struct_nav_bug_554616.py
+++ b/test/keystrokes/firefox/html_struct_nav_bug_554616.py
@@ -69,14 +69,12 @@ sequence.append(utils.AssertPresentationAction(
      "BRAILLE LINE:  'installer (10190 KB)'",
      "     VISIBLE:  'installer (10190 KB)', cursor=1",
      "SPEECH OUTPUT: 'Download'",
-     "SPEECH OUTPUT: 'installer'",
-     "SPEECH OUTPUT: 'link'",
+     "SPEECH OUTPUT: 'installer link'",
      "SPEECH OUTPUT: '(10190 KB)'",
-     "SPEECH OUTPUT: 'portable archive'",
-     "SPEECH OUTPUT: 'link'",
+     "SPEECH OUTPUT: 'portable archive link'",
      "SPEECH OUTPUT: '(9154 KB)'",
      "SPEECH OUTPUT: 'Row 2, column 3.' voice=system",
-     "SPEECH OUTPUT: 'i'"]))
+     "SPEECH OUTPUT: 'blank' voice=system"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("<Alt><Shift>Down"))
@@ -88,11 +86,9 @@ sequence.append(utils.AssertPresentationAction(
      "     VISIBLE:  'installer (10193 KB)', cursor=1",
      "BRAILLE LINE:  'Row 3, column 3.'",
      "     VISIBLE:  'Row 3, column 3.', cursor=0",
-     "SPEECH OUTPUT: 'installer'",
-     "SPEECH OUTPUT: 'link'",
+     "SPEECH OUTPUT: 'installer link'",
      "SPEECH OUTPUT: '(10193 KB)'",
-     "SPEECH OUTPUT: 'portable archive'",
-     "SPEECH OUTPUT: 'link'",
+     "SPEECH OUTPUT: 'portable archive link'",
      "SPEECH OUTPUT: '(9149 KB)'",
      "SPEECH OUTPUT: 'Row 3, column 3.' voice=system"]))
 
@@ -140,11 +136,9 @@ sequence.append(utils.AssertPresentationAction(
      "BRAILLE LINE:  'Row 4, column 3.'",
      "     VISIBLE:  'Row 4, column 3.', cursor=0",
      "SPEECH OUTPUT: 'Download'",
-     "SPEECH OUTPUT: 'installer'",
-     "SPEECH OUTPUT: 'link'",
+     "SPEECH OUTPUT: 'installer link'",
      "SPEECH OUTPUT: '(10186 KB)'",
-     "SPEECH OUTPUT: 'portable archive'",
-     "SPEECH OUTPUT: 'link'",
+     "SPEECH OUTPUT: 'portable archive link'",
      "SPEECH OUTPUT: '(9146 KB)'",
      "SPEECH OUTPUT: 'Row 4, column 3.' voice=system"]))
 
diff --git a/test/keystrokes/firefox/html_struct_nav_bug_567984.py 
b/test/keystrokes/firefox/html_struct_nav_bug_567984.py
index 0ecdd28..91bd136 100644
--- a/test/keystrokes/firefox/html_struct_nav_bug_567984.py
+++ b/test/keystrokes/firefox/html_struct_nav_bug_567984.py
@@ -27,14 +27,13 @@ sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("h"))
 sequence.append(utils.AssertPresentationAction(
     "3. h",
-    ["BRAILLE LINE:  'Izrael bejelentette az h3'",
-     "     VISIBLE:  'Izrael bejelentette az h3', cursor=1",
-     "BRAILLE LINE:  'Izrael bejelentette az h3'",
-     "     VISIBLE:  'Izrael bejelentette az h3', cursor=1",
+    ["BRAILLE LINE:  'Izrael bejelentette az  h3'",
+     "     VISIBLE:  'Izrael bejelentette az  h3', cursor=1",
+     "BRAILLE LINE:  'Izrael bejelentette az  h3'",
+     "     VISIBLE:  'Izrael bejelentette az  h3', cursor=1",
      "SPEECH OUTPUT: 'Izrael bejelentette az ",
      "egyoldalú tûzszünetet'",
-     "SPEECH OUTPUT: 'link'",
-     "SPEECH OUTPUT: 'heading level 3'"]))
+     "SPEECH OUTPUT: 'link heading level 3'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("h"))
@@ -42,9 +41,7 @@ sequence.append(utils.AssertPresentationAction(
     "4. h",
     ["BRAILLE LINE:  'Videók a Hudsonba zuhanó repülõrõl h3'",
      "     VISIBLE:  'Videók a Hudsonba zuhanó repülõr', cursor=1",
-     "SPEECH OUTPUT: 'Videók a Hudsonba zuhanó repülõrõl'",
-     "SPEECH OUTPUT: 'link'",
-     "SPEECH OUTPUT: 'heading level 3'"]))
+     "SPEECH OUTPUT: 'Videók a Hudsonba zuhanó repülõrõl link heading level 3'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("h"))
@@ -52,9 +49,7 @@ sequence.append(utils.AssertPresentationAction(
     "5. h",
     ["BRAILLE LINE:  'Újabb pénzügyi guru tûnt el, pénzzel együtt h3'",
      "     VISIBLE:  'Újabb pénzügyi guru tûnt el, pén', cursor=1",
-     "SPEECH OUTPUT: 'Újabb pénzügyi guru tûnt el, pénzzel együtt'",
-     "SPEECH OUTPUT: 'link'",
-     "SPEECH OUTPUT: 'heading level 3'"]))
+     "SPEECH OUTPUT: 'Újabb pénzügyi guru tûnt el, pénzzel együtt link heading level 3'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
@@ -70,9 +65,7 @@ sequence.append(utils.AssertPresentationAction(
     "7. Down",
     ["BRAILLE LINE:  '1150 embert utcára tesz a pécsi Elcoteq h3'",
      "     VISIBLE:  '1150 embert utcára tesz a pécsi ', cursor=1",
-     "SPEECH OUTPUT: '1150 embert utcára tesz a pécsi Elcoteq'",
-     "SPEECH OUTPUT: 'link'",
-     "SPEECH OUTPUT: 'heading level 3'"]))
+     "SPEECH OUTPUT: '1150 embert utcára tesz a pécsi Elcoteq link heading level 3'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("h"))
@@ -80,9 +73,7 @@ sequence.append(utils.AssertPresentationAction(
     "8. h",
     ["BRAILLE LINE:  'Hamarosan újraindul a gázszállítás h3'",
      "     VISIBLE:  'Hamarosan újraindul a gázszállít', cursor=1",
-     "SPEECH OUTPUT: 'Hamarosan újraindul a gázszállítás'",
-     "SPEECH OUTPUT: 'link'",
-     "SPEECH OUTPUT: 'heading level 3'"]))
+     "SPEECH OUTPUT: 'Hamarosan újraindul a gázszállítás link heading level 3'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
@@ -98,9 +89,7 @@ sequence.append(utils.AssertPresentationAction(
     "10. Shift+h",
     ["BRAILLE LINE:  'Hamarosan újraindul a gázszállítás h3'",
      "     VISIBLE:  'Hamarosan újraindul a gázszállít', cursor=1",
-     "SPEECH OUTPUT: 'Hamarosan újraindul a gázszállítás'",
-     "SPEECH OUTPUT: 'link'",
-     "SPEECH OUTPUT: 'heading level 3'"]))
+     "SPEECH OUTPUT: 'Hamarosan újraindul a gázszállítás link heading level 3'"]))
 
 sequence.append(utils.AssertionSummaryAction())
 sequence.start()
diff --git a/test/keystrokes/firefox/html_struct_nav_descriptions.py 
b/test/keystrokes/firefox/html_struct_nav_descriptions.py
index b284034..45d608d 100644
--- a/test/keystrokes/firefox/html_struct_nav_descriptions.py
+++ b/test/keystrokes/firefox/html_struct_nav_descriptions.py
@@ -15,10 +15,9 @@ sequence.append(utils.AssertPresentationAction(
     "1. k for next link",
     ["BRAILLE LINE:  'Foo, Bar, and Baz.'",
      "     VISIBLE:  'Foo, Bar, and Baz.', cursor=1",
-     "BRAILLE LINE:  'Foo, Bar, and Baz.'",
-     "     VISIBLE:  'Foo, Bar, and Baz.', cursor=1",
-     "SPEECH OUTPUT: 'Foo'",
-     "SPEECH OUTPUT: 'link Title of the Foo link.'"]))
+     "BRAILLE LINE:  'Foo'",
+     "     VISIBLE:  'Foo', cursor=1",
+     "SPEECH OUTPUT: 'Foo link Title of the Foo link.'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("k"))
@@ -26,8 +25,7 @@ sequence.append(utils.AssertPresentationAction(
     "2. k for next link",
     ["BRAILLE LINE:  'Foo, Bar, and Baz.'",
      "     VISIBLE:  'Foo, Bar, and Baz.', cursor=6",
-     "SPEECH OUTPUT: 'Bar'",
-     "SPEECH OUTPUT: 'link ARIA description text.'"]))
+     "SPEECH OUTPUT: 'Bar link ARIA description text.'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("k"))
@@ -35,14 +33,13 @@ sequence.append(utils.AssertPresentationAction(
     "3. k for next link",
     ["BRAILLE LINE:  'Foo, Bar, and Baz.'",
      "     VISIBLE:  'Foo, Bar, and Baz.', cursor=15",
-     "SPEECH OUTPUT: 'Baz'",
-     "SPEECH OUTPUT: 'link Title of the Baz link.'"]))
+     "SPEECH OUTPUT: 'Baz link Title of the Baz link.'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("x"))
 sequence.append(utils.AssertPresentationAction(
     "4. x for next checkbox",
-    ["BRAILLE LINE:  '< > Title of the Black checkbox check box Black < > Title of the White checkbox check 
box White < > Title of the Grey checkbox check box Grey'",
+    ["BRAILLE LINE:  '< > Title of the Black checkbox check box'",
      "     VISIBLE:  '< > Title of the Black checkbox ', cursor=1",
      "SPEECH OUTPUT: 'Title of the Black checkbox check box not checked'"]))
 
@@ -50,7 +47,7 @@ sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("x"))
 sequence.append(utils.AssertPresentationAction(
     "5. x for next checkbox",
-    ["BRAILLE LINE:  '< > Title of the Black checkbox check box Black < > Title of the White checkbox check 
box White < > Title of the Grey checkbox check box Grey'",
+    ["BRAILLE LINE:  '< > Title of the White checkbox check box'",
      "     VISIBLE:  '< > Title of the White checkbox ', cursor=1",
      "SPEECH OUTPUT: 'Title of the White checkbox check box not checked ARIA description text.'"]))
 
@@ -58,7 +55,7 @@ sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("x"))
 sequence.append(utils.AssertPresentationAction(
     "6. x for next checkbox",
-    ["BRAILLE LINE:  '< > Title of the Black checkbox check box Black < > Title of the White checkbox check 
box White < > Title of the Grey checkbox check box Grey'",
+    ["BRAILLE LINE:  '< > Title of the Grey checkbox check box'",
      "     VISIBLE:  '< > Title of the Grey checkbox c', cursor=1",
      "SPEECH OUTPUT: 'Title of the Grey checkbox check box not checked'"]))
 
@@ -66,23 +63,23 @@ sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("x"))
 sequence.append(utils.AssertPresentationAction(
     "7. x for next checkbox",
-    ["BRAILLE LINE:  '< > Black check box < > White check box < > Grey check box'",
-     "     VISIBLE:  '< > Black check box < > White ch', cursor=1",
+    ["BRAILLE LINE:  '< > Black check box'",
+     "     VISIBLE:  '< > Black check box', cursor=1",
      "SPEECH OUTPUT: 'Black check box not checked'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("x"))
 sequence.append(utils.AssertPresentationAction(
     "8. x for next checkbox",
-    ["BRAILLE LINE:  '< > Black check box < > White check box < > Grey check box'",
-     "     VISIBLE:  '< > White check box < > Grey che', cursor=1",
+    ["BRAILLE LINE:  '< > White check box'",
+     "     VISIBLE:  '< > White check box', cursor=1",
      "SPEECH OUTPUT: 'White check box not checked ARIA description text.'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("x"))
 sequence.append(utils.AssertPresentationAction(
     "9. x for next checkbox",
-    ["BRAILLE LINE:  '< > Black check box < > White check box < > Grey check box'",
+    ["BRAILLE LINE:  '< > Grey check box'",
      "     VISIBLE:  '< > Grey check box', cursor=1",
      "SPEECH OUTPUT: 'Grey check box not checked Title of the Grey checkbox'"]))
 
diff --git a/test/keystrokes/firefox/html_struct_nav_heading_in_div_with_text.py 
b/test/keystrokes/firefox/html_struct_nav_heading_in_div_with_text.py
index 7f7d8f3..15ed2dd 100644
--- a/test/keystrokes/firefox/html_struct_nav_heading_in_div_with_text.py
+++ b/test/keystrokes/firefox/html_struct_nav_heading_in_div_with_text.py
@@ -13,13 +13,11 @@ sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("2"))
 sequence.append(utils.AssertPresentationAction(
     "1. 2 for first heading",
-    ["BRAILLE LINE:  'First Heading h2'",
-     "     VISIBLE:  'First Heading h2', cursor=1",
-     "BRAILLE LINE:  'First Heading h2'",
-     "     VISIBLE:  'First Heading h2', cursor=1",
-     "SPEECH OUTPUT: 'First Heading'",
-     "SPEECH OUTPUT: 'link'",
-     "SPEECH OUTPUT: 'heading level 2'"]))
+    ["BRAILLE LINE:  'First Heading  h2'",
+     "     VISIBLE:  'First Heading  h2', cursor=1",
+     "BRAILLE LINE:  'First Heading  h2'",
+     "     VISIBLE:  'First Heading  h2', cursor=1",
+     "SPEECH OUTPUT: 'First Heading  link heading level 2'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
@@ -33,11 +31,9 @@ sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("2"))
 sequence.append(utils.AssertPresentationAction(
     "3. 2 to move to the next heading",
-    ["BRAILLE LINE:  'Second Heading h2'",
-     "     VISIBLE:  'Second Heading h2', cursor=1",
-     "SPEECH OUTPUT: 'Second Heading'",
-     "SPEECH OUTPUT: 'link'",
-     "SPEECH OUTPUT: 'heading level 2'"]))
+    ["BRAILLE LINE:  'Second Heading  h2'",
+     "     VISIBLE:  'Second Heading  h2', cursor=1",
+     "SPEECH OUTPUT: 'Second Heading  link heading level 2'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
@@ -51,11 +47,9 @@ sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("<Shift>2"))
 sequence.append(utils.AssertPresentationAction(
     "5. Shift+2 to move to the previous heading",
-    ["BRAILLE LINE:  'Second Heading h2'",
-     "     VISIBLE:  'Second Heading h2', cursor=1",
-     "SPEECH OUTPUT: 'Second Heading'",
-     "SPEECH OUTPUT: 'link'",
-     "SPEECH OUTPUT: 'heading level 2'"]))
+    ["BRAILLE LINE:  'Second Heading  h2'",
+     "     VISIBLE:  'Second Heading  h2', cursor=1",
+     "SPEECH OUTPUT: 'Second Heading  link heading level 2'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
@@ -69,11 +63,9 @@ sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("<Shift>2"))
 sequence.append(utils.AssertPresentationAction(
     "7. Shift+2 to move to the previous heading",
-    ["BRAILLE LINE:  'First Heading h2'",
-     "     VISIBLE:  'First Heading h2', cursor=1",
-     "SPEECH OUTPUT: 'First Heading'",
-     "SPEECH OUTPUT: 'link'",
-     "SPEECH OUTPUT: 'heading level 2'"]))
+    ["BRAILLE LINE:  'First Heading  h2'",
+     "     VISIBLE:  'First Heading  h2', cursor=1",
+     "SPEECH OUTPUT: 'First Heading  link heading level 2'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("<Shift>2"))
@@ -81,12 +73,10 @@ sequence.append(utils.AssertPresentationAction(
     "8. Shift+2 to move to the previous heading",
     ["BRAILLE LINE:  'Wrapping to bottom.'",
      "     VISIBLE:  'Wrapping to bottom.', cursor=0",
-     "BRAILLE LINE:  'Second Heading h2'",
-     "     VISIBLE:  'Second Heading h2', cursor=1",
+     "BRAILLE LINE:  'Second Heading  h2'",
+     "     VISIBLE:  'Second Heading  h2', cursor=1",
      "SPEECH OUTPUT: 'Wrapping to bottom.' voice=system",
-     "SPEECH OUTPUT: 'Second Heading'",
-     "SPEECH OUTPUT: 'link'",
-     "SPEECH OUTPUT: 'heading level 2'"]))
+     "SPEECH OUTPUT: 'Second Heading  link heading level 2'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("2"))
@@ -94,12 +84,10 @@ sequence.append(utils.AssertPresentationAction(
     "9. 2 to move to the next heading",
     ["BRAILLE LINE:  'Wrapping to top.'",
      "     VISIBLE:  'Wrapping to top.', cursor=0",
-     "BRAILLE LINE:  'First Heading h2'",
-     "     VISIBLE:  'First Heading h2', cursor=1",
+     "BRAILLE LINE:  'First Heading  h2'",
+     "     VISIBLE:  'First Heading  h2', cursor=1",
      "SPEECH OUTPUT: 'Wrapping to top.' voice=system",
-     "SPEECH OUTPUT: 'First Heading'",
-     "SPEECH OUTPUT: 'link'",
-     "SPEECH OUTPUT: 'heading level 2'"]))
+     "SPEECH OUTPUT: 'First Heading  link heading level 2'"]))
 
 sequence.append(utils.AssertionSummaryAction())
 sequence.start()
diff --git a/test/keystrokes/firefox/html_struct_nav_headings_buried_deep.py 
b/test/keystrokes/firefox/html_struct_nav_headings_buried_deep.py
index ab5fd07..5a44c80 100644
--- a/test/keystrokes/firefox/html_struct_nav_headings_buried_deep.py
+++ b/test/keystrokes/firefox/html_struct_nav_headings_buried_deep.py
@@ -22,7 +22,7 @@ sequence.append(utils.AssertPresentationAction(
      "BRAILLE LINE:  '• Heading 3 h3'",
      "     VISIBLE:  '• Heading 3 h3', cursor=3",
      "SPEECH OUTPUT: 'Wrapping to bottom.' voice=system",
-     "SPEECH OUTPUT: 'Heading 3 heading level 3'"]))
+     "SPEECH OUTPUT: 'Heading 3 heading level 3 link'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("<Shift>h"))
@@ -30,7 +30,7 @@ sequence.append(utils.AssertPresentationAction(
     "2. Shift+h for previous heading",
     ["BRAILLE LINE:  '• Heading 2 h3'",
      "     VISIBLE:  '• Heading 2 h3', cursor=3",
-     "SPEECH OUTPUT: 'Heading 2 heading level 3'"]))
+     "SPEECH OUTPUT: 'Heading 2 heading level 3 link'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("<Shift>h"))
@@ -38,7 +38,7 @@ sequence.append(utils.AssertPresentationAction(
     "3. Shift+h for previous heading",
     ["BRAILLE LINE:  '• Heading 1 h3'",
      "     VISIBLE:  '• Heading 1 h3', cursor=3",
-     "SPEECH OUTPUT: 'Heading 1 heading level 3'"]))
+     "SPEECH OUTPUT: 'Heading 1 heading level 3 link'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("h"))
@@ -46,7 +46,7 @@ sequence.append(utils.AssertPresentationAction(
     "4. h for next heading",
     ["BRAILLE LINE:  '• Heading 2 h3'",
      "     VISIBLE:  '• Heading 2 h3', cursor=3",
-     "SPEECH OUTPUT: 'Heading 2 heading level 3'"]))
+     "SPEECH OUTPUT: 'Heading 2 heading level 3 link'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("h"))
@@ -54,7 +54,7 @@ sequence.append(utils.AssertPresentationAction(
     "5. h for next heading",
     ["BRAILLE LINE:  '• Heading 3 h3'",
      "     VISIBLE:  '• Heading 3 h3', cursor=3",
-     "SPEECH OUTPUT: 'Heading 3 heading level 3'"]))
+     "SPEECH OUTPUT: 'Heading 3 heading level 3 link'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("h"))
@@ -65,7 +65,7 @@ sequence.append(utils.AssertPresentationAction(
      "BRAILLE LINE:  '• Heading 1 h3'",
      "     VISIBLE:  '• Heading 1 h3', cursor=3",
      "SPEECH OUTPUT: 'Wrapping to top.' voice=system",
-     "SPEECH OUTPUT: 'Heading 1 heading level 3'"]))
+     "SPEECH OUTPUT: 'Heading 1 heading level 3 link'"]))
 
 sequence.append(utils.AssertionSummaryAction())
 sequence.start()
diff --git a/test/keystrokes/firefox/html_struct_nav_hidden_paragraphs.py 
b/test/keystrokes/firefox/html_struct_nav_hidden_paragraphs.py
index 54d6a14..aed5e48 100644
--- a/test/keystrokes/firefox/html_struct_nav_hidden_paragraphs.py
+++ b/test/keystrokes/firefox/html_struct_nav_hidden_paragraphs.py
@@ -35,15 +35,6 @@ sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("p"))
 sequence.append(utils.AssertPresentationAction(
     "4. p to next paragraph",
-    ["KNOWN ISSUE: https://bugzilla.mozilla.org/show_bug.cgi?id=974238";,
-     "BRAILLE LINE:  'This element is in a parent hidden by ARIA.'",
-     "     VISIBLE:  'This element is in a parent hidd', cursor=1",
-     "SPEECH OUTPUT: 'This element is in a parent hidden by ARIA.'"]))
-
-sequence.append(utils.StartRecordingAction())
-sequence.append(KeyComboAction("p"))
-sequence.append(utils.AssertPresentationAction(
-    "5. p to next paragraph",
     ["BRAILLE LINE:  'This element is in a parent hidden by position off screen'",
      "     VISIBLE:  'This element is in a parent hidd', cursor=1",
      "SPEECH OUTPUT: 'This element is in a parent hidden by position off screen'"]))
@@ -51,16 +42,7 @@ sequence.append(utils.AssertPresentationAction(
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("<Shift>p"))
 sequence.append(utils.AssertPresentationAction(
-    "6. Shift p to previous paragraph",
-    ["KNOWN ISSUE: https://bugzilla.mozilla.org/show_bug.cgi?id=974238";,
-     "BRAILLE LINE:  'This element is in a parent hidden by ARIA.'",
-     "     VISIBLE:  'This element is in a parent hidd', cursor=1",
-     "SPEECH OUTPUT: 'This element is in a parent hidden by ARIA.'"]))
-
-sequence.append(utils.StartRecordingAction())
-sequence.append(KeyComboAction("<Shift>p"))
-sequence.append(utils.AssertPresentationAction(
-    "7. Shift p to previous paragraph",
+    "5. Shift p to previous paragraph",
     ["BRAILLE LINE:  'This element is in a parent which is not hidden.'",
      "     VISIBLE:  'This element is in a parent whic', cursor=1",
      "SPEECH OUTPUT: 'This element is in a parent which is not hidden.'"]))
@@ -68,7 +50,7 @@ sequence.append(utils.AssertPresentationAction(
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("<Shift>p"))
 sequence.append(utils.AssertPresentationAction(
-    "8. Shift p to previous paragraph",
+    "6. Shift p to previous paragraph",
     ["BRAILLE LINE:  'This element hidden by position off screen.'",
      "     VISIBLE:  'This element hidden by position ', cursor=1",
      "SPEECH OUTPUT: 'This element hidden by position off screen.'"]))
@@ -76,7 +58,7 @@ sequence.append(utils.AssertPresentationAction(
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("<Shift>p"))
 sequence.append(utils.AssertPresentationAction(
-    "9. Shift p to previous paragraph",
+    "7. Shift p to previous paragraph",
     ["BRAILLE LINE:  'This element is not hidden.'",
      "     VISIBLE:  'This element is not hidden.', cursor=1",
      "SPEECH OUTPUT: 'This element is not hidden.'"]))
diff --git a/test/keystrokes/firefox/html_struct_nav_links.py 
b/test/keystrokes/firefox/html_struct_nav_links.py
index 962c6d2..3ff62b4 100644
--- a/test/keystrokes/firefox/html_struct_nav_links.py
+++ b/test/keystrokes/firefox/html_struct_nav_links.py
@@ -15,10 +15,9 @@ sequence.append(utils.AssertPresentationAction(
     "1. u to anchors.html link",
     ["BRAILLE LINE:  '• anchors.html'",
      "     VISIBLE:  '• anchors.html', cursor=3",
-     "BRAILLE LINE:  '• anchors.html'",
-     "     VISIBLE:  '• anchors.html', cursor=3",
-     "SPEECH OUTPUT: 'anchors.html'",
-     "SPEECH OUTPUT: 'link'"]))
+     "BRAILLE LINE:  'anchors.html'",
+     "     VISIBLE:  'anchors.html', cursor=1",
+     "SPEECH OUTPUT: 'anchors.html link'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("u"))
@@ -26,8 +25,7 @@ sequence.append(utils.AssertPresentationAction(
     "2. u to blockquotes.html link",
     ["BRAILLE LINE:  '• blockquotes.html'",
      "     VISIBLE:  '• blockquotes.html', cursor=3",
-     "SPEECH OUTPUT: 'blockquotes.html'",
-     "SPEECH OUTPUT: 'link'"]))
+     "SPEECH OUTPUT: 'blockquotes.html link'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("<Shift>u"))
@@ -35,8 +33,7 @@ sequence.append(utils.AssertPresentationAction(
     "3. shift + u to anchors.html link",
     ["BRAILLE LINE:  '• anchors.html'",
      "     VISIBLE:  '• anchors.html', cursor=3",
-     "SPEECH OUTPUT: 'anchors.html'",
-     "SPEECH OUTPUT: 'link'"]))
+     "SPEECH OUTPUT: 'anchors.html link'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("<Shift>u"))
@@ -47,8 +44,7 @@ sequence.append(utils.AssertPresentationAction(
      "BRAILLE LINE:  '• textattributes.html'",
      "     VISIBLE:  '• textattributes.html', cursor=3",
      "SPEECH OUTPUT: 'Wrapping to bottom.' voice=system",
-     "SPEECH OUTPUT: 'textattributes.html'",
-     "SPEECH OUTPUT: 'link'"]))
+     "SPEECH OUTPUT: 'textattributes.html link'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("<Shift>u"))
@@ -56,8 +52,7 @@ sequence.append(utils.AssertPresentationAction(
     "5. shift + u to tables.html",
     ["BRAILLE LINE:  '• tables.html'",
      "     VISIBLE:  '• tables.html', cursor=3",
-     "SPEECH OUTPUT: 'tables.html'",
-     "SPEECH OUTPUT: 'link'"]))
+     "SPEECH OUTPUT: 'tables.html link'"]))
 
 sequence.append(KeyComboAction("Return"))
 sequence.append(WaitForDocLoad())
@@ -69,10 +64,11 @@ sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("u"))
 sequence.append(utils.AssertPresentationAction(
     "6. u to textattributes.html link",
-    ["BRAILLE LINE:  '• textattributes.html'",
+    ["BRAILLE LINE:  'tables.html'",
+     "     VISIBLE:  'tables.html', cursor=1",
+     "BRAILLE LINE:  '• textattributes.html'",
      "     VISIBLE:  '• textattributes.html', cursor=3",
-     "SPEECH OUTPUT: 'textattributes.html'",
-     "SPEECH OUTPUT: 'link'"]))
+     "SPEECH OUTPUT: 'textattributes.html link'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("u"))
@@ -83,8 +79,7 @@ sequence.append(utils.AssertPresentationAction(
      "BRAILLE LINE:  '• anchors.html'",
      "     VISIBLE:  '• anchors.html', cursor=3",
      "SPEECH OUTPUT: 'Wrapping to top.' voice=system",
-     "SPEECH OUTPUT: 'anchors.html'",
-     "SPEECH OUTPUT: 'link'"]))
+     "SPEECH OUTPUT: 'anchors.html link'"]))
 
 sequence.append(KeyComboAction("Return"))
 sequence.append(WaitForDocLoad())
@@ -96,10 +91,11 @@ sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("v"))
 sequence.append(utils.AssertPresentationAction(
     "8. v to tables.html link",
-    ["BRAILLE LINE:  '• tables.html'",
+    ["BRAILLE LINE:  'anchors.html'",
+     "     VISIBLE:  'anchors.html', cursor=1",
+     "BRAILLE LINE:  '• tables.html'",
      "     VISIBLE:  '• tables.html', cursor=3",
-     "SPEECH OUTPUT: 'tables.html'",
-     "SPEECH OUTPUT: 'link'"]))
+     "SPEECH OUTPUT: 'tables.html link'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("v"))
@@ -110,8 +106,7 @@ sequence.append(utils.AssertPresentationAction(
      "BRAILLE LINE:  '• anchors.html'",
      "     VISIBLE:  '• anchors.html', cursor=3",
      "SPEECH OUTPUT: 'Wrapping to top.' voice=system",
-     "SPEECH OUTPUT: 'anchors.html'",
-     "SPEECH OUTPUT: 'link'"]))
+     "SPEECH OUTPUT: 'anchors.html link'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("<Shift>v"))
@@ -122,8 +117,7 @@ sequence.append(utils.AssertPresentationAction(
      "BRAILLE LINE:  '• tables.html'",
      "     VISIBLE:  '• tables.html', cursor=3",
      "SPEECH OUTPUT: 'Wrapping to bottom.' voice=system",
-     "SPEECH OUTPUT: 'tables.html'",
-     "SPEECH OUTPUT: 'link'"]))
+     "SPEECH OUTPUT: 'tables.html link'"]))
 
 sequence.append(utils.AssertionSummaryAction())
 sequence.start()
diff --git a/test/keystrokes/firefox/label_inference_bug_546815.py 
b/test/keystrokes/firefox/label_inference_bug_546815.py
index 72e7032..a8c98c9 100644
--- a/test/keystrokes/firefox/label_inference_bug_546815.py
+++ b/test/keystrokes/firefox/label_inference_bug_546815.py
@@ -20,8 +20,8 @@ sequence.append(KeyComboAction("Tab"))
 sequence.append(KeyReleaseAction(0, None, "KP_Insert"))
 sequence.append(utils.AssertPresentationAction(
     "1. Next form field",
-    ["BRAILLE LINE:  'Enter your Name:  $l text field using default type=text'",
-     "     VISIBLE:  ' $l text field using default typ', cursor=1",
+    ["BRAILLE LINE:  'Enter your Name:  $l'",
+     "     VISIBLE:  'Enter your Name:  $l', cursor=18",
      "SPEECH OUTPUT: 'Enter your Name: entry'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -30,8 +30,8 @@ sequence.append(KeyComboAction("Tab"))
 sequence.append(KeyReleaseAction(0, None, "KP_Insert"))
 sequence.append(utils.AssertPresentationAction(
     "2. Next form field",
-    ["BRAILLE LINE:  '1. Enter your Address:  $l text field using SIZE and'",
-     "     VISIBLE:  ' $l text field using SIZE and', cursor=1",
+    ["BRAILLE LINE:  '1. Enter your Address:  $l'",
+     "     VISIBLE:  '1. Enter your Address:  $l', cursor=24",
      "SPEECH OUTPUT: '1. Enter your Address: entry'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -40,8 +40,8 @@ sequence.append(KeyComboAction("Tab"))
 sequence.append(KeyReleaseAction(0, None, "KP_Insert"))
 sequence.append(utils.AssertPresentationAction(
     "3. Next form field",
-    ["BRAILLE LINE:  '2. Enter your City:  $l 3. Enter your State:  $l 4. Enter your Country: US $l image 
text field using value'",
-     "     VISIBLE:  ' $l 3. Enter your State:  $l 4. ', cursor=1",
+    ["BRAILLE LINE:  '2. Enter your City:  $l'",
+     "     VISIBLE:  '2. Enter your City:  $l', cursor=21",
      "SPEECH OUTPUT: '2. Enter your City: entry'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -50,8 +50,8 @@ sequence.append(KeyComboAction("Tab"))
 sequence.append(KeyReleaseAction(0, None, "KP_Insert"))
 sequence.append(utils.AssertPresentationAction(
     "4. Next form field",
-    ["BRAILLE LINE:  '2. Enter your City:  $l 3. Enter your State:  $l 4. Enter your Country: US $l image 
text field using value'",
-     "     VISIBLE:  ' $l 4. Enter your Country: US $l', cursor=1",
+    ["BRAILLE LINE:  '3. Enter your State:  $l'",
+     "     VISIBLE:  '3. Enter your State:  $l', cursor=22",
      "SPEECH OUTPUT: '3. Enter your State: entry'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -60,8 +60,8 @@ sequence.append(KeyComboAction("Tab"))
 sequence.append(KeyReleaseAction(0, None, "KP_Insert"))
 sequence.append(utils.AssertPresentationAction(
     "5. Next form field",
-    ["BRAILLE LINE:  '2. Enter your City:  $l 3. Enter your State:  $l 4. Enter your Country: US $l image 
text field using value'",
-     "     VISIBLE:  'US $l image text field using val', cursor=1",
+    ["BRAILLE LINE:  '4. Enter your Country: US $l'",
+     "     VISIBLE:  '4. Enter your Country: US $l', cursor=24",
      "SPEECH OUTPUT: '4. Enter your Country: entry'",
      "SPEECH OUTPUT: 'US'"]))
 
@@ -71,8 +71,8 @@ sequence.append(KeyComboAction("Tab"))
 sequence.append(KeyReleaseAction(0, None, "KP_Insert"))
 sequence.append(utils.AssertPresentationAction(
     "6. Next form field",
-    ["BRAILLE LINE:  '5. Enter your Zip:  $l'",
-     "     VISIBLE:  '5. Enter your Zip:  $l', cursor=20",
+    ["BRAILLE LINE:  '5. Enter your Zip:  $l'",
+     "     VISIBLE:  '5. Enter your Zip:  $l', cursor=20",
      "SPEECH OUTPUT: '5. Enter your Zip: entry'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -81,8 +81,8 @@ sequence.append(KeyComboAction("Tab"))
 sequence.append(KeyReleaseAction(0, None, "KP_Insert"))
 sequence.append(utils.AssertPresentationAction(
     "7. Next form field",
-    ["BRAILLE LINE:  'character:  $l'",
-     "     VISIBLE:  'character:  $l', cursor=12",
+    ["BRAILLE LINE:  'character:  $l'",
+     "     VISIBLE:  'character:  $l', cursor=12",
      "SPEECH OUTPUT: 'character: entry'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -91,8 +91,8 @@ sequence.append(KeyComboAction("Tab"))
 sequence.append(KeyReleaseAction(0, None, "KP_Insert"))
 sequence.append(utils.AssertPresentationAction(
     "8. Next form field",
-    ["BRAILLE LINE:  '< > check box bird'",
-     "     VISIBLE:  '< > check box bird', cursor=1",
+    ["BRAILLE LINE:  '< > bird check box'",
+     "     VISIBLE:  '< > bird check box', cursor=1",
      "SPEECH OUTPUT: 'bird check box not checked'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -101,8 +101,8 @@ sequence.append(KeyComboAction("Tab"))
 sequence.append(KeyReleaseAction(0, None, "KP_Insert"))
 sequence.append(utils.AssertPresentationAction(
     "9. Next form field",
-    ["BRAILLE LINE:  '< > check box fish'",
-     "     VISIBLE:  '< > check box fish', cursor=1",
+    ["BRAILLE LINE:  '< > fish check box'",
+     "     VISIBLE:  '< > fish check box', cursor=1",
      "SPEECH OUTPUT: 'fish check box not checked'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -111,8 +111,8 @@ sequence.append(KeyComboAction("Tab"))
 sequence.append(KeyReleaseAction(0, None, "KP_Insert"))
 sequence.append(utils.AssertPresentationAction(
     "10. Next form field",
-    ["BRAILLE LINE:  '< > check box wild animal'",
-     "     VISIBLE:  '< > check box wild animal', cursor=1",
+    ["BRAILLE LINE:  '< > wild animal check box'",
+     "     VISIBLE:  '< > wild animal check box', cursor=1",
      "SPEECH OUTPUT: 'wild animal check box not checked'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -121,8 +121,8 @@ sequence.append(KeyComboAction("Tab"))
 sequence.append(KeyReleaseAction(0, None, "KP_Insert"))
 sequence.append(utils.AssertPresentationAction(
     "11. Next form field",
-    ["BRAILLE LINE:  '&=y radio button cabernet sauvignon'",
-     "     VISIBLE:  '&=y radio button cabernet sauvig', cursor=1",
+    ["BRAILLE LINE:  '&=y cabernet sauvignon radio button'",
+     "     VISIBLE:  '&=y cabernet sauvignon radio but', cursor=1",
      "SPEECH OUTPUT: 'cabernet sauvignon selected radio button'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -131,8 +131,8 @@ sequence.append(KeyComboAction("Tab"))
 sequence.append(KeyReleaseAction(0, None, "KP_Insert"))
 sequence.append(utils.AssertPresentationAction(
     "12. Next form field",
-    ["BRAILLE LINE:  '& y radio button merlot'",
-     "     VISIBLE:  '& y radio button merlot', cursor=1",
+    ["BRAILLE LINE:  '& y merlot radio button'",
+     "     VISIBLE:  '& y merlot radio button', cursor=1",
      "SPEECH OUTPUT: 'merlot not selected radio button'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -141,8 +141,8 @@ sequence.append(KeyComboAction("Tab"))
 sequence.append(KeyReleaseAction(0, None, "KP_Insert"))
 sequence.append(utils.AssertPresentationAction(
     "13. Next form field",
-    ["BRAILLE LINE:  '& y radio button nebbiolo'",
-     "     VISIBLE:  '& y radio button nebbiolo', cursor=1",
+    ["BRAILLE LINE:  '& y nebbiolo radio button'",
+     "     VISIBLE:  '& y nebbiolo radio button', cursor=1",
      "SPEECH OUTPUT: 'nebbiolo not selected radio button'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -151,8 +151,8 @@ sequence.append(KeyComboAction("Tab"))
 sequence.append(KeyReleaseAction(0, None, "KP_Insert"))
 sequence.append(utils.AssertPresentationAction(
     "14. Next form field",
-    ["BRAILLE LINE:  '& y radio button pinot noir'",
-     "     VISIBLE:  '& y radio button pinot noir', cursor=1",
+    ["BRAILLE LINE:  '& y pinot noir radio button'",
+     "     VISIBLE:  '& y pinot noir radio button', cursor=1",
      "SPEECH OUTPUT: 'pinot noir not selected radio button'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -161,8 +161,8 @@ sequence.append(KeyComboAction("Tab"))
 sequence.append(KeyReleaseAction(0, None, "KP_Insert"))
 sequence.append(utils.AssertPresentationAction(
     "15. Next form field",
-    ["BRAILLE LINE:  '& y radio button don't drink wine'",
-     "     VISIBLE:  '& y radio button don't drink win', cursor=1",
+    ["BRAILLE LINE:  '& y don't drink wine radio button'",
+     "     VISIBLE:  '& y don't drink wine radio butto', cursor=1",
      "SPEECH OUTPUT: 'don't drink wine not selected radio button'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -173,8 +173,8 @@ sequence.append(utils.AssertPresentationAction(
     "16. Next form field",
     ["BRAILLE LINE:  'Wrapping to top.'",
      "     VISIBLE:  'Wrapping to top.', cursor=0",
-     "BRAILLE LINE:  'Enter your Name:  $l text field using default type=text'",
-     "     VISIBLE:  ' $l text field using default typ', cursor=1",
+     "BRAILLE LINE:  'Enter your Name:  $l'",
+     "     VISIBLE:  'Enter your Name:  $l', cursor=18",
      "SPEECH OUTPUT: 'Wrapping to top.' voice=system",
      "SPEECH OUTPUT: 'Enter your Name: entry'"]))
 
diff --git a/test/keystrokes/firefox/label_inference_bugzilla_search.py 
b/test/keystrokes/firefox/label_inference_bugzilla_search.py
index 9a72d4c..a32e37d 100644
--- a/test/keystrokes/firefox/label_inference_bugzilla_search.py
+++ b/test/keystrokes/firefox/label_inference_bugzilla_search.py
@@ -7,14 +7,19 @@ import utils
 
 sequence = MacroSequence()
 
+# Work around some new quirk in Gecko that causes this test to fail if
+# run via the test harness rather than manually.
+sequence.append(KeyComboAction("<Control>r"))
 sequence.append(PauseAction(3000))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("<Shift>ISO_Left_Tab"))
 sequence.append(utils.AssertPresentationAction(
     "1. Shift Tab",
-    ["BRAILLE LINE:  'contains all of the words/strings combo box'",
-     "     VISIBLE:  'contains all of the words/string', cursor=1",
+    ["BRAILLE LINE:  ' $l'",
+     "     VISIBLE:  ' $l', cursor=1",
+     "BRAILLE LINE:  'Summary: contains all of the words/strings combo box'",
+     "     VISIBLE:  'Summary: contains all of the wor', cursor=10",
      "SPEECH OUTPUT: 'Summary: contains all of the words/strings combo box'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -42,8 +47,8 @@ sequence.append(utils.AssertPresentationAction(
     "4. Tab",
     ["BRAILLE LINE:  'Search push button'",
      "     VISIBLE:  'Search push button', cursor=1",
-     "BRAILLE LINE:  'Admin'",
-     "     VISIBLE:  'Admin', cursor=1",
+     "BRAILLE LINE:  'Admin '",
+     "     VISIBLE:  'Admin ', cursor=1",
      "BRAILLE LINE:  'Focus mode'",
      "     VISIBLE:  'Focus mode', cursor=0",
      "SPEECH OUTPUT: 'table with 2 rows 1 column'",
@@ -55,8 +60,8 @@ sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Tab"))
 sequence.append(utils.AssertPresentationAction(
     "5. Tab",
-    ["BRAILLE LINE:  'Admin'",
-     "     VISIBLE:  'Admin', cursor=1",
+    ["BRAILLE LINE:  'Admin '",
+     "     VISIBLE:  'Admin ', cursor=1",
      "BRAILLE LINE:  'accerciser'",
      "     VISIBLE:  'accerciser', cursor=1",
      "SPEECH OUTPUT: 'table with 2 rows 1 column'",
@@ -71,8 +76,8 @@ sequence.append(utils.AssertPresentationAction(
      "     VISIBLE:  'Component', cursor=1",
      "BRAILLE LINE:  'Browse mode'",
      "     VISIBLE:  'Browse mode', cursor=0",
-     "BRAILLE LINE:  'Component:'",
-     "     VISIBLE:  'Component:', cursor=1",
+     "BRAILLE LINE:  'Component'",
+     "     VISIBLE:  'Component', cursor=1",
      "SPEECH OUTPUT: 'Component link'",
      "SPEECH OUTPUT: 'Browse mode' voice=system"]))
 
@@ -114,8 +119,8 @@ sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Tab"))
 sequence.append(utils.AssertPresentationAction(
     "10. Tab",
-    ["BRAILLE LINE:  'contains the string combo box'",
-     "     VISIBLE:  'contains the string combo box', cursor=1",
+    ["BRAILLE LINE:  'A Comment: contains the string combo box'",
+     "     VISIBLE:  'A Comment: contains the string c', cursor=12",
      "SPEECH OUTPUT: 'A Comment: contains the string combo box'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -130,8 +135,8 @@ sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Tab"))
 sequence.append(utils.AssertPresentationAction(
     "12. Tab",
-    ["BRAILLE LINE:  'contains all of the words/strings combo box'",
-     "     VISIBLE:  'contains all of the words/string', cursor=1",
+    ["BRAILLE LINE:  'Whiteboard: contains all of the words/strings combo box'",
+     "     VISIBLE:  'Whiteboard: contains all of the ', cursor=13",
      "SPEECH OUTPUT: 'Whiteboard: contains all of the words/strings combo box'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -150,8 +155,8 @@ sequence.append(utils.AssertPresentationAction(
      "     VISIBLE:  'Keywords', cursor=1",
      "BRAILLE LINE:  'Browse mode'",
      "     VISIBLE:  'Browse mode', cursor=0",
-     "BRAILLE LINE:  'Keywords: contains all of the keywords combo box $l'",
-     "     VISIBLE:  'Keywords: contains all of the ke', cursor=1",
+     "BRAILLE LINE:  'Keywords'",
+     "     VISIBLE:  'Keywords', cursor=1",
      "SPEECH OUTPUT: 'Keywords link'",
      "SPEECH OUTPUT: 'Browse mode' voice=system"]))
 
@@ -159,8 +164,8 @@ sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Tab"))
 sequence.append(utils.AssertPresentationAction(
     "15. Tab",
-    ["BRAILLE LINE:  'Keywords: contains all of the keywords combo box $l'",
-     "     VISIBLE:  'contains all of the keywords com', cursor=1",
+    ["BRAILLE LINE:  'Keywords: contains all of the keywords combo box'",
+     "     VISIBLE:  'Keywords: contains all of the ke', cursor=11",
      "BRAILLE LINE:  'Focus mode'",
      "     VISIBLE:  'Focus mode', cursor=0",
      "SPEECH OUTPUT: 'Keywords: contains all of the keywords combo box'",
@@ -170,8 +175,8 @@ sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Tab"))
 sequence.append(utils.AssertPresentationAction(
     "16. Tab",
-    ["BRAILLE LINE:  'Keywords: contains all of the keywords combo box $l'",
-     "     VISIBLE:  'contains all of the keywords com', cursor=1",
+    ["BRAILLE LINE:  'Keywords: contains all of the keywords combo box'",
+     "     VISIBLE:  'Keywords: contains all of the ke', cursor=11",
      "BRAILLE LINE:  ' $l'",
      "     VISIBLE:  ' $l', cursor=1",
      "SPEECH OUTPUT: 'entry'"]))
@@ -230,8 +235,8 @@ sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Tab"))
 sequence.append(utils.AssertPresentationAction(
     "22. Tab",
-    ["BRAILLE LINE:  '<x> check box'",
-     "     VISIBLE:  '<x> check box', cursor=1",
+    ["BRAILLE LINE:  '<x> the bug assignee check box'",
+     "     VISIBLE:  '<x> the bug assignee check box', cursor=1",
      "BRAILLE LINE:  'Browse mode'",
      "     VISIBLE:  'Browse mode', cursor=0",
      "SPEECH OUTPUT: 'Email and Numbering  panel'",
@@ -242,34 +247,34 @@ sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Tab"))
 sequence.append(utils.AssertPresentationAction(
     "23. Tab",
-    ["BRAILLE LINE:  '<x> check box'",
-     "     VISIBLE:  '<x> check box', cursor=1",
-     "BRAILLE LINE:  '< > check box the reporter'",
-     "     VISIBLE:  '< > check box the reporter', cursor=1",
+    ["BRAILLE LINE:  '<x> the bug assignee check box'",
+     "     VISIBLE:  '<x> the bug assignee check box', cursor=1",
+     "BRAILLE LINE:  '< > the reporter check box'",
+     "     VISIBLE:  '< > the reporter check box', cursor=1",
      "SPEECH OUTPUT: 'the reporter check box not checked'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Tab"))
 sequence.append(utils.AssertPresentationAction(
     "24. Tab",
-    ["BRAILLE LINE:  '< > check box the QA contact'",
-     "     VISIBLE:  '< > check box the QA contact', cursor=1",
+    ["BRAILLE LINE:  '< > the QA contact check box'",
+     "     VISIBLE:  '< > the QA contact check box', cursor=1",
      "SPEECH OUTPUT: 'the QA contact check box not checked'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Tab"))
 sequence.append(utils.AssertPresentationAction(
     "25. Tab",
-    ["BRAILLE LINE:  '< > check box a CC list member'",
-     "     VISIBLE:  '< > check box a CC list member', cursor=1",
+    ["BRAILLE LINE:  '< > a CC list member check box'",
+     "     VISIBLE:  '< > a CC list member check box', cursor=1",
      "SPEECH OUTPUT: 'a CC list member check box not checked'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Tab"))
 sequence.append(utils.AssertPresentationAction(
     "26. Tab",
-    ["BRAILLE LINE:  '< > check box a commenter'",
-     "     VISIBLE:  '< > check box a commenter', cursor=1",
+    ["BRAILLE LINE:  '< > a commenter check box'",
+     "     VISIBLE:  '< > a commenter check box', cursor=1",
      "SPEECH OUTPUT: 'a commenter check box not checked'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -297,8 +302,8 @@ sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Tab"))
 sequence.append(utils.AssertPresentationAction(
     "29. Tab",
-    ["BRAILLE LINE:  '<x> check box'",
-     "     VISIBLE:  '<x> check box', cursor=1",
+    ["BRAILLE LINE:  '<x> the bug assignee check box'",
+     "     VISIBLE:  '<x> the bug assignee check box', cursor=1",
      "BRAILLE LINE:  'Browse mode'",
      "     VISIBLE:  'Browse mode', cursor=0",
      "SPEECH OUTPUT: 'the bug assignee check box checked'",
@@ -308,34 +313,34 @@ sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Tab"))
 sequence.append(utils.AssertPresentationAction(
     "30. Tab",
-    ["BRAILLE LINE:  '<x> check box'",
-     "     VISIBLE:  '<x> check box', cursor=1",
-     "BRAILLE LINE:  '<x> check box the reporter'",
-     "     VISIBLE:  '<x> check box the reporter', cursor=1",
+    ["BRAILLE LINE:  '<x> the bug assignee check box'",
+     "     VISIBLE:  '<x> the bug assignee check box', cursor=1",
+     "BRAILLE LINE:  '<x> the reporter check box'",
+     "     VISIBLE:  '<x> the reporter check box', cursor=1",
      "SPEECH OUTPUT: 'the reporter check box checked'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Tab"))
 sequence.append(utils.AssertPresentationAction(
     "31. Tab",
-    ["BRAILLE LINE:  '<x> check box the QA contact'",
-     "     VISIBLE:  '<x> check box the QA contact', cursor=1",
+    ["BRAILLE LINE:  '<x> the QA contact check box'",
+     "     VISIBLE:  '<x> the QA contact check box', cursor=1",
      "SPEECH OUTPUT: 'the QA contact check box checked'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Tab"))
 sequence.append(utils.AssertPresentationAction(
     "32. Tab",
-    ["BRAILLE LINE:  '<x> check box a CC list member'",
-     "     VISIBLE:  '<x> check box a CC list member', cursor=1",
+    ["BRAILLE LINE:  '<x> a CC list member check box'",
+     "     VISIBLE:  '<x> a CC list member check box', cursor=1",
      "SPEECH OUTPUT: 'a CC list member check box checked'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Tab"))
 sequence.append(utils.AssertPresentationAction(
     "33. Tab",
-    ["BRAILLE LINE:  '< > check box a commenter'",
-     "     VISIBLE:  '< > check box a commenter', cursor=1",
+    ["BRAILLE LINE:  '< > a commenter check box'",
+     "     VISIBLE:  '< > a commenter check box', cursor=1",
      "SPEECH OUTPUT: 'a commenter check box not checked'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -372,28 +377,27 @@ sequence.append(KeyComboAction("Tab"))
 sequence.append(utils.AssertPresentationAction(
     "37. Tab",
     ["KNOWN ISSUE: This could be improved",
-     "BRAILLE LINE:  ' $l'",
-     "     VISIBLE:  ' $l', cursor=1",
+     "BRAILLE LINE:  '(comma-separated list)  $l'",
+     "     VISIBLE:  '(comma-separated list)  $l', cursor=24",
      "SPEECH OUTPUT: '(comma-separated list) entry'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Tab"))
 sequence.append(utils.AssertPresentationAction(
     "38. Tab",
-    ["KNOWN ISSUE: This could be improved",
-     "BRAILLE LINE:  ' $l'",
-     "     VISIBLE:  ' $l', cursor=1",
+    ["BRAILLE LINE:  'Only bugs changed between:  $l'",
+     "     VISIBLE:  'Only bugs changed between:  $l', cursor=28",
      "SPEECH OUTPUT: 'Bug Changes panel'",
-     "SPEECH OUTPUT: '(YYYY-MM-DD or relative dates) entry'"]))
+     "SPEECH OUTPUT: 'Only bugs changed between: entry'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Tab"))
 sequence.append(utils.AssertPresentationAction(
     "39. Tab",
-    ["BRAILLE LINE:  'Now $l'",
-     "     VISIBLE:  'Now $l', cursor=4",
-     "BRAILLE LINE:  'Now $l'",
-     "     VISIBLE:  'Now $l', cursor=4",
+    ["BRAILLE LINE:  'and Now $l'",
+     "     VISIBLE:  'and Now $l', cursor=8",
+     "BRAILLE LINE:  'and Now $l'",
+     "     VISIBLE:  'and Now $l', cursor=8",
      "SPEECH OUTPUT: 'and entry Now selected'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -402,16 +406,16 @@ sequence.append(utils.AssertPresentationAction(
     "40. Tab",
     ["BRAILLE LINE:  '[Bug creation]'",
      "     VISIBLE:  '[Bug creation]', cursor=1",
-     "SPEECH OUTPUT: 'multi-select List with 26 items'",
+     "SPEECH OUTPUT: 'where one or more of the following changed: multi-select List with 26 items'",
      "SPEECH OUTPUT: '[Bug creation]'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Tab"))
 sequence.append(utils.AssertPresentationAction(
     "41. Tab",
-    ["BRAILLE LINE:  ' $l'",
-     "     VISIBLE:  ' $l', cursor=1",
-     "SPEECH OUTPUT: 'entry'"]))
+    ["BRAILLE LINE:  'and the new value was:  $l'",
+     "     VISIBLE:  'and the new value was:  $l', cursor=24",
+     "SPEECH OUTPUT: 'and the new value was: entry'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Tab"))
@@ -437,8 +441,8 @@ sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Tab"))
 sequence.append(utils.AssertPresentationAction(
     "44. Tab",
-    ["BRAILLE LINE:  'Reuse same sort as last time combo box'",
-     "     VISIBLE:  'Reuse same sort as last time com', cursor=1",
+    ["BRAILLE LINE:  'Sort results by: Reuse same sort as last time combo box'",
+     "     VISIBLE:  'Sort results by: Reuse same sort', cursor=18",
      "SPEECH OUTPUT: 'Sort results by: Reuse same sort as last time combo box'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -458,24 +462,24 @@ sequence.append(utils.AssertPresentationAction(
     "46. Tab",
     ["BRAILLE LINE:  'Search push button'",
      "     VISIBLE:  'Search push button', cursor=1",
-     "BRAILLE LINE:  '< > check box and remember these as my default search options'",
-     "     VISIBLE:  '< > check box and remember these', cursor=1",
+     "BRAILLE LINE:  '< > and remember these as my default search options check box'",
+     "     VISIBLE:  '< > and remember these as my def', cursor=1",
      "SPEECH OUTPUT: 'and remember these as my default search options check box not checked'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Tab"))
 sequence.append(utils.AssertPresentationAction(
     "47. Tab",
-    ["BRAILLE LINE:  '< > check box Not (negate this whole chart)'",
-     "     VISIBLE:  '< > check box Not \(negate this w', cursor=1",
+    ["BRAILLE LINE:  '< > Not (negate this whole chart) check box'",
+     "     VISIBLE:  '< > Not \(negate this whole chart', cursor=1",
      "SPEECH OUTPUT: 'Not (negate this whole chart) check box not checked'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Tab"))
 sequence.append(utils.AssertPresentationAction(
     "48. Tab",
-    ["BRAILLE LINE:  '--- combo box --- combo box $l Or push button'",
-     "     VISIBLE:  '--- combo box --- combo box $l O', cursor=1",
+    ["BRAILLE LINE:  '--- combo box'",
+     "     VISIBLE:  '--- combo box', cursor=1",
      "BRAILLE LINE:  'Focus mode'",
      "     VISIBLE:  'Focus mode', cursor=0",
      "SPEECH OUTPUT: '--- combo box'",
@@ -485,8 +489,8 @@ sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Tab"))
 sequence.append(utils.AssertPresentationAction(
     "49. Tab",
-    ["BRAILLE LINE:  '--- combo box --- combo box $l Or push button'",
-     "     VISIBLE:  '--- combo box --- combo box $l O', cursor=1",
+    ["BRAILLE LINE:  '--- combo box'",
+     "     VISIBLE:  '--- combo box', cursor=1",
      "BRAILLE LINE:  '--- combo box'",
      "     VISIBLE:  '--- combo box', cursor=1",
      "SPEECH OUTPUT: '--- combo box'"]))
diff --git a/test/keystrokes/firefox/label_inference_entries.py 
b/test/keystrokes/firefox/label_inference_entries.py
index daa84a4..ed56576 100644
--- a/test/keystrokes/firefox/label_inference_entries.py
+++ b/test/keystrokes/firefox/label_inference_entries.py
@@ -17,7 +17,7 @@ sequence.append(KeyReleaseAction(0, None, "KP_Insert"))
 sequence.append(utils.AssertPresentationAction(
     "1. Next form field",
     ["BRAILLE LINE:  'Type something rather amusing here:  $l'",
-     "     VISIBLE:  ' $l', cursor=1",
+     "     VISIBLE:  'something rather amusing here:  ', cursor=32",
      "SPEECH OUTPUT: 'Type something rather amusing here: entry'"]))
 
 sequence.append(PauseAction(3000))
@@ -28,8 +28,8 @@ sequence.append(KeyComboAction("Tab"))
 sequence.append(KeyReleaseAction(0, None, "KP_Insert"))
 sequence.append(utils.AssertPresentationAction(
     "2. Next form field",
-    ["BRAILLE LINE:  'Amusing numbers fall between  $l and  $l.'",
-     "     VISIBLE:  ' $l and  $l.', cursor=1",
+    ["BRAILLE LINE:  'Amusing numbers fall between  $l'",
+     "     VISIBLE:  'Amusing numbers fall between  $l', cursor=30",
      "SPEECH OUTPUT: 'Amusing numbers fall between entry'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -38,8 +38,8 @@ sequence.append(KeyComboAction("Tab"))
 sequence.append(KeyReleaseAction(0, None, "KP_Insert"))
 sequence.append(utils.AssertPresentationAction(
     "3. Next form field",
-    ["BRAILLE LINE:  'Amusing numbers fall between  $l and  $l.'",
-     "     VISIBLE:  ' $l.', cursor=1",
+    ["BRAILLE LINE:  'and  $l'",
+     "     VISIBLE:  'and  $l', cursor=5",
      "SPEECH OUTPUT: 'and entry'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -48,8 +48,8 @@ sequence.append(KeyComboAction("Tab"))
 sequence.append(KeyReleaseAction(0, None, "KP_Insert"))
 sequence.append(utils.AssertPresentationAction(
     "4. Next form field",
-    ["BRAILLE LINE:  ' $l I'm a label'",
-     "     VISIBLE:  ' $l I'm a label', cursor=1",
+    ["BRAILLE LINE:  'I'm a label  $l'",
+     "     VISIBLE:  'I'm a label  $l', cursor=13",
      "SPEECH OUTPUT: 'I'm a label entry'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -58,8 +58,8 @@ sequence.append(KeyComboAction("Tab"))
 sequence.append(KeyReleaseAction(0, None, "KP_Insert"))
 sequence.append(utils.AssertPresentationAction(
     "5. Next form field",
-    ["BRAILLE LINE:  ' $l Am I a label as well?'",
-     "     VISIBLE:  ' $l Am I a label as well?', cursor=1",
+    ["BRAILLE LINE:  ' $l'",
+     "     VISIBLE:  ' $l', cursor=1",
      "SPEECH OUTPUT: 'entry'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -68,8 +68,8 @@ sequence.append(KeyComboAction("Tab"))
 sequence.append(KeyReleaseAction(0, None, "KP_Insert"))
 sequence.append(utils.AssertPresentationAction(
     "6. Next form field",
-    ["BRAILLE LINE:  ' $l Too far away to be a label.'",
-     "     VISIBLE:  ' $l Too far away to be a label.', cursor=1",
+    ["BRAILLE LINE:  'Looking at what follows visually, I'm not sure what I would type/i.e. what the labels 
are.  $l'",
+     "     VISIBLE:  'type/i.e. what the labels are.  ', cursor=32",
      "SPEECH OUTPUT: 'Looking at what follows visually, I'm not sure what I would type/i.e. what the labels 
are. entry'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -78,8 +78,8 @@ sequence.append(KeyComboAction("Tab"))
 sequence.append(KeyReleaseAction(0, None, "KP_Insert"))
 sequence.append(utils.AssertPresentationAction(
     "7. Next form field",
-    ["BRAILLE LINE:  'Distance doesn't count on the left $l'",
-     "     VISIBLE:  ' $l', cursor=1",
+    ["BRAILLE LINE:  'Distance doesn't count on the left  $l'",
+     "     VISIBLE:  'ance doesn't count on the left  ', cursor=32",
      "SPEECH OUTPUT: 'Distance doesn't count on the left entry'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -88,8 +88,8 @@ sequence.append(KeyComboAction("Tab"))
 sequence.append(KeyReleaseAction(0, None, "KP_Insert"))
 sequence.append(utils.AssertPresentationAction(
     "8. Next form field",
-    ["BRAILLE LINE:  ' $l'",
-     "     VISIBLE:  ' $l', cursor=1",
+    ["BRAILLE LINE:  'First Name  $l'",
+     "     VISIBLE:  'First Name  $l', cursor=12",
      "SPEECH OUTPUT: 'First Name entry'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -98,8 +98,8 @@ sequence.append(KeyComboAction("Tab"))
 sequence.append(KeyReleaseAction(0, None, "KP_Insert"))
 sequence.append(utils.AssertPresentationAction(
     "9. Next form field",
-    ["BRAILLE LINE:  ' $l'",
-     "     VISIBLE:  ' $l', cursor=1",
+    ["BRAILLE LINE:  'M.I.  $l'",
+     "     VISIBLE:  'M.I.  $l', cursor=6",
      "SPEECH OUTPUT: 'M.I. entry'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -108,8 +108,8 @@ sequence.append(KeyComboAction("Tab"))
 sequence.append(KeyReleaseAction(0, None, "KP_Insert"))
 sequence.append(utils.AssertPresentationAction(
     "10. Next form field",
-    ["BRAILLE LINE:  ' $l'",
-     "     VISIBLE:  ' $l', cursor=1",
+    ["BRAILLE LINE:  'Last Name  $l'",
+     "     VISIBLE:  'Last Name  $l', cursor=11",
      "SPEECH OUTPUT: 'Last Name entry'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -118,8 +118,8 @@ sequence.append(KeyComboAction("Tab"))
 sequence.append(KeyReleaseAction(0, None, "KP_Insert"))
 sequence.append(utils.AssertPresentationAction(
     "11. Next form field",
-    ["BRAILLE LINE:  ' $l $l $l'",
-     "     VISIBLE:  ' $l $l $l', cursor=1",
+    ["BRAILLE LINE:  'First name  $l'",
+     "     VISIBLE:  'First name  $l', cursor=12",
      "SPEECH OUTPUT: 'First name entry'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -128,8 +128,8 @@ sequence.append(KeyComboAction("Tab"))
 sequence.append(KeyReleaseAction(0, None, "KP_Insert"))
 sequence.append(utils.AssertPresentationAction(
     "12. Next form field",
-    ["BRAILLE LINE:  ' $l $l $l'",
-     "     VISIBLE:  ' $l $l $l', cursor=4",
+    ["BRAILLE LINE:  'Middle initial  $l'",
+     "     VISIBLE:  'Middle initial  $l', cursor=16",
      "SPEECH OUTPUT: 'Middle initial entry'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -138,8 +138,8 @@ sequence.append(KeyComboAction("Tab"))
 sequence.append(KeyReleaseAction(0, None, "KP_Insert"))
 sequence.append(utils.AssertPresentationAction(
     "13. Next form field",
-    ["BRAILLE LINE:  ' $l $l $l'",
-     "     VISIBLE:  ' $l $l $l', cursor=7",
+    ["BRAILLE LINE:  'Last name  $l'",
+     "     VISIBLE:  'Last name  $l', cursor=11",
      "SPEECH OUTPUT: 'Last name entry'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -148,8 +148,8 @@ sequence.append(KeyComboAction("Tab"))
 sequence.append(KeyReleaseAction(0, None, "KP_Insert"))
 sequence.append(utils.AssertPresentationAction(
     "14. Next form field",
-    ["BRAILLE LINE:  ' $l $l $l'",
-     "     VISIBLE:  ' $l $l $l', cursor=1",
+    ["BRAILLE LINE:  'First Name  $l'",
+     "     VISIBLE:  'First Name  $l', cursor=12",
      "SPEECH OUTPUT: 'First Name entry'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -158,8 +158,8 @@ sequence.append(KeyComboAction("Tab"))
 sequence.append(KeyReleaseAction(0, None, "KP_Insert"))
 sequence.append(utils.AssertPresentationAction(
     "15. Next form field",
-    ["BRAILLE LINE:  ' $l $l $l'",
-     "     VISIBLE:  ' $l $l $l', cursor=4",
+    ["BRAILLE LINE:  'Middle initial  $l'",
+     "     VISIBLE:  'Middle initial  $l', cursor=16",
      "SPEECH OUTPUT: 'Middle initial entry'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -168,8 +168,8 @@ sequence.append(KeyComboAction("Tab"))
 sequence.append(KeyReleaseAction(0, None, "KP_Insert"))
 sequence.append(utils.AssertPresentationAction(
     "16. Next form field",
-    ["BRAILLE LINE:  ' $l $l $l'",
-     "     VISIBLE:  ' $l $l $l', cursor=7",
+    ["BRAILLE LINE:  'Last name  $l'",
+     "     VISIBLE:  'Last name  $l', cursor=11",
      "SPEECH OUTPUT: 'Last name entry'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -178,8 +178,8 @@ sequence.append(KeyComboAction("Tab"))
 sequence.append(KeyReleaseAction(0, None, "KP_Insert"))
 sequence.append(utils.AssertPresentationAction(
     "17. Next form field",
-    ["BRAILLE LINE:  ' $l $l $l'",
-     "     VISIBLE:  ' $l $l $l', cursor=1",
+    ["BRAILLE LINE:  'Given name  $l'",
+     "     VISIBLE:  'Given name  $l', cursor=12",
      "SPEECH OUTPUT: 'Given name entry'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -188,8 +188,8 @@ sequence.append(KeyComboAction("Tab"))
 sequence.append(KeyReleaseAction(0, None, "KP_Insert"))
 sequence.append(utils.AssertPresentationAction(
     "18. Next form field",
-    ["BRAILLE LINE:  ' $l $l $l'",
-     "     VISIBLE:  ' $l $l $l', cursor=4",
+    ["BRAILLE LINE:  'initial  $l'",
+     "     VISIBLE:  'initial  $l', cursor=9",
      "SPEECH OUTPUT: 'initial entry'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -198,8 +198,8 @@ sequence.append(KeyComboAction("Tab"))
 sequence.append(KeyReleaseAction(0, None, "KP_Insert"))
 sequence.append(utils.AssertPresentationAction(
     "19. Next form field",
-    ["BRAILLE LINE:  ' $l $l $l'",
-     "     VISIBLE:  ' $l $l $l', cursor=7",
+    ["BRAILLE LINE:  'Surname  $l'",
+     "     VISIBLE:  'Surname  $l', cursor=9",
      "SPEECH OUTPUT: 'Surname entry'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -208,8 +208,8 @@ sequence.append(KeyComboAction("Tab"))
 sequence.append(KeyReleaseAction(0, None, "KP_Insert"))
 sequence.append(utils.AssertPresentationAction(
     "20. Next form field",
-    ["BRAILLE LINE:  ' $l $l $l'",
-     "     VISIBLE:  ' $l $l $l', cursor=1",
+    ["BRAILLE LINE:  'First name  $l'",
+     "     VISIBLE:  'First name  $l', cursor=12",
      "SPEECH OUTPUT: 'First name entry'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -218,8 +218,8 @@ sequence.append(KeyComboAction("Tab"))
 sequence.append(KeyReleaseAction(0, None, "KP_Insert"))
 sequence.append(utils.AssertPresentationAction(
     "21. Next form field",
-    ["BRAILLE LINE:  ' $l $l $l'",
-     "     VISIBLE:  ' $l $l $l', cursor=4",
+    ["BRAILLE LINE:  'Middle initial  $l'",
+     "     VISIBLE:  'Middle initial  $l', cursor=16",
      "SPEECH OUTPUT: 'Middle initial entry'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -228,8 +228,8 @@ sequence.append(KeyComboAction("Tab"))
 sequence.append(KeyReleaseAction(0, None, "KP_Insert"))
 sequence.append(utils.AssertPresentationAction(
     "22. Next form field",
-    ["BRAILLE LINE:  ' $l $l $l'",
-     "     VISIBLE:  ' $l $l $l', cursor=7",
+    ["BRAILLE LINE:  'Last name  $l'",
+     "     VISIBLE:  'Last name  $l', cursor=11",
      "SPEECH OUTPUT: 'Last name entry'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -238,8 +238,8 @@ sequence.append(KeyComboAction("Tab"))
 sequence.append(KeyReleaseAction(0, None, "KP_Insert"))
 sequence.append(utils.AssertPresentationAction(
     "23. Next form field",
-    ["BRAILLE LINE:  ' $l $l $l $l'",
-     "     VISIBLE:  ' $l $l $l $l', cursor=1",
+    ["BRAILLE LINE:  'First name  $l'",
+     "     VISIBLE:  'First name  $l', cursor=12",
      "SPEECH OUTPUT: 'First name entry'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -248,8 +248,8 @@ sequence.append(KeyComboAction("Tab"))
 sequence.append(KeyReleaseAction(0, None, "KP_Insert"))
 sequence.append(utils.AssertPresentationAction(
     "24. Next form field",
-    ["BRAILLE LINE:  ' $l $l $l $l'",
-     "     VISIBLE:  ' $l $l $l $l', cursor=4",
+    ["BRAILLE LINE:  'Middle initial  $l'",
+     "     VISIBLE:  'Middle initial  $l', cursor=16",
      "SPEECH OUTPUT: 'Middle initial entry'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -258,8 +258,8 @@ sequence.append(KeyComboAction("Tab"))
 sequence.append(KeyReleaseAction(0, None, "KP_Insert"))
 sequence.append(utils.AssertPresentationAction(
     "25. Next form field",
-    ["BRAILLE LINE:  ' $l $l $l $l'",
-     "     VISIBLE:  ' $l $l $l $l', cursor=7",
+    ["BRAILLE LINE:  'Last name  $l'",
+     "     VISIBLE:  'Last name  $l', cursor=11",
      "SPEECH OUTPUT: 'Last name entry'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -268,18 +268,19 @@ sequence.append(KeyComboAction("Tab"))
 sequence.append(KeyReleaseAction(0, None, "KP_Insert"))
 sequence.append(utils.AssertPresentationAction(
     "26. Next form field",
-    ["BRAILLE LINE:  ' $l $l $l $l'",
-     "     VISIBLE:  ' $l $l $l $l', cursor=10",
+    ["BRAILLE LINE:  'patched image  $l'",
+     "     VISIBLE:  'patched image  $l', cursor=15",
      "SPEECH OUTPUT: 'patched image entry'"]))
 
+
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyPressAction(0, None, "KP_Insert"))
 sequence.append(KeyComboAction("Tab"))
 sequence.append(KeyReleaseAction(0, None, "KP_Insert"))
 sequence.append(utils.AssertPresentationAction(
     "27. Next form field",
-    ["BRAILLE LINE:  ' $l $l $l $l'",
-     "     VISIBLE:  ' $l $l $l $l', cursor=1",
+    ["BRAILLE LINE:  'First name  $l'",
+     "     VISIBLE:  'First name  $l', cursor=12",
      "SPEECH OUTPUT: 'First name entry'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -288,8 +289,8 @@ sequence.append(KeyComboAction("Tab"))
 sequence.append(KeyReleaseAction(0, None, "KP_Insert"))
 sequence.append(utils.AssertPresentationAction(
     "28. Next form field",
-    ["BRAILLE LINE:  ' $l $l $l $l'",
-     "     VISIBLE:  ' $l $l $l $l', cursor=4",
+    ["BRAILLE LINE:  'Middle initial  $l'",
+     "     VISIBLE:  'Middle initial  $l', cursor=16",
      "SPEECH OUTPUT: 'Middle initial entry'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -298,8 +299,8 @@ sequence.append(KeyComboAction("Tab"))
 sequence.append(KeyReleaseAction(0, None, "KP_Insert"))
 sequence.append(utils.AssertPresentationAction(
     "29. Next form field",
-    ["BRAILLE LINE:  ' $l $l $l $l'",
-     "     VISIBLE:  ' $l $l $l $l', cursor=7",
+    ["BRAILLE LINE:  'Last name  $l'",
+     "     VISIBLE:  'Last name  $l', cursor=11",
      "SPEECH OUTPUT: 'Last name entry'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -308,8 +309,8 @@ sequence.append(KeyComboAction("Tab"))
 sequence.append(KeyReleaseAction(0, None, "KP_Insert"))
 sequence.append(utils.AssertPresentationAction(
     "30. Next form field",
-    ["BRAILLE LINE:  ' $l $l $l $l'",
-     "     VISIBLE:  ' $l $l $l $l', cursor=10",
+    ["BRAILLE LINE:  'patched image  $l'",
+     "     VISIBLE:  'patched image  $l', cursor=15",
      "SPEECH OUTPUT: 'patched image entry'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -318,8 +319,8 @@ sequence.append(KeyComboAction("Tab"))
 sequence.append(KeyReleaseAction(0, None, "KP_Insert"))
 sequence.append(utils.AssertPresentationAction(
     "31. Next form field",
-    ["BRAILLE LINE:  ' $l $l $l $l'",
-     "     VISIBLE:  ' $l $l $l $l', cursor=1",
+    ["BRAILLE LINE:  'First name  $l'",
+     "     VISIBLE:  'First name  $l', cursor=12",
      "SPEECH OUTPUT: 'First name entry'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -328,8 +329,8 @@ sequence.append(KeyComboAction("Tab"))
 sequence.append(KeyReleaseAction(0, None, "KP_Insert"))
 sequence.append(utils.AssertPresentationAction(
     "32. Next form field",
-    ["BRAILLE LINE:  ' $l $l $l $l'",
-     "     VISIBLE:  ' $l $l $l $l', cursor=4",
+    ["BRAILLE LINE:  'Middle initial  $l'",
+     "     VISIBLE:  'Middle initial  $l', cursor=16",
      "SPEECH OUTPUT: 'Middle initial entry'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -338,8 +339,8 @@ sequence.append(KeyComboAction("Tab"))
 sequence.append(KeyReleaseAction(0, None, "KP_Insert"))
 sequence.append(utils.AssertPresentationAction(
     "33. Next form field",
-    ["BRAILLE LINE:  ' $l $l $l $l'",
-     "     VISIBLE:  ' $l $l $l $l', cursor=7",
+    ["BRAILLE LINE:  'Last name  $l'",
+     "     VISIBLE:  'Last name  $l', cursor=11",
      "SPEECH OUTPUT: 'Last name entry'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -348,8 +349,8 @@ sequence.append(KeyComboAction("Tab"))
 sequence.append(KeyReleaseAction(0, None, "KP_Insert"))
 sequence.append(utils.AssertPresentationAction(
     "34. Next form field",
-    ["BRAILLE LINE:  ' $l $l $l $l'",
-     "     VISIBLE:  ' $l $l $l $l', cursor=10",
+    ["BRAILLE LINE:  'patched image  $l'",
+     "     VISIBLE:  'patched image  $l', cursor=15",
      "SPEECH OUTPUT: 'patched image entry'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -358,8 +359,8 @@ sequence.append(KeyComboAction("Tab"))
 sequence.append(KeyReleaseAction(0, None, "KP_Insert"))
 sequence.append(utils.AssertPresentationAction(
     "35. Next form field",
-    ["BRAILLE LINE:  'bandaid graphic $l'",
-     "     VISIBLE:  'bandaid graphic $l', cursor=16",
+    ["BRAILLE LINE:  'bandaid graphic  $l'",
+     "     VISIBLE:  'bandaid graphic  $l', cursor=17",
      "SPEECH OUTPUT: 'bandaid graphic entry'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -368,8 +369,8 @@ sequence.append(KeyComboAction("Tab"))
 sequence.append(KeyReleaseAction(0, None, "KP_Insert"))
 sequence.append(utils.AssertPresentationAction(
     "36. Next form field",
-    ["BRAILLE LINE:  ' $l bandaid graphic redux'",
-     "     VISIBLE:  ' $l bandaid graphic redux', cursor=1",
+    ["BRAILLE LINE:  'bandaid graphic redux  $l'",
+     "     VISIBLE:  'bandaid graphic redux  $l', cursor=23",
      "SPEECH OUTPUT: 'bandaid graphic redux entry'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -379,9 +380,9 @@ sequence.append(KeyReleaseAction(0, None, "KP_Insert"))
 sequence.append(utils.AssertPresentationAction(
     "37. Next form field",
     ["BRAILLE LINE:  'Magic disappearing text trick:  $l'",
-     "     VISIBLE:  ' $l', cursor=1",
+     "     VISIBLE:  'Magic disappearing text trick:  ', cursor=32",
      "BRAILLE LINE:  'Magic disappearing text trick:  $l'",
-     "     VISIBLE:  ' $l', cursor=1",
+     "     VISIBLE:  'Magic disappearing text trick:  ', cursor=32",
      "SPEECH OUTPUT: 'Magic disappearing text trick: entry'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -400,8 +401,8 @@ sequence.append(KeyComboAction("Tab"))
 sequence.append(KeyReleaseAction(0, None, "KP_Insert"))
 sequence.append(utils.AssertPresentationAction(
     "39. Next form field",
-    ["BRAILLE LINE:  'I $l'",
-     "     VISIBLE:  'I $l', cursor=1",
+    ["BRAILLE LINE:  'Tell me a little more about yourself: I $l'",
+     "     VISIBLE:  ' a little more about yourself: I', cursor=32",
      "SPEECH OUTPUT: 'Tell me a little more about yourself: entry I",
      "am a monkey with a long tail. I like to swing from trees and eat",
      "bananas. I've recently taken up typing and plan to write my memoirs. '"]))
@@ -415,7 +416,7 @@ sequence.append(utils.AssertPresentationAction(
     ["BRAILLE LINE:  'Wrapping to top.'",
      "     VISIBLE:  'Wrapping to top.', cursor=0",
      "BRAILLE LINE:  'Type something rather amusing here:  $l'",
-     "     VISIBLE:  ' $l', cursor=1",
+     "     VISIBLE:  'something rather amusing here:  ', cursor=32",
      "SPEECH OUTPUT: 'Wrapping to top.' voice=system",
      "SPEECH OUTPUT: 'Type something rather amusing here: entry'"]))
 
diff --git a/test/keystrokes/firefox/label_inference_mailman.py 
b/test/keystrokes/firefox/label_inference_mailman.py
index 5d81289..201e665 100644
--- a/test/keystrokes/firefox/label_inference_mailman.py
+++ b/test/keystrokes/firefox/label_inference_mailman.py
@@ -15,8 +15,8 @@ sequence.append(KeyComboAction("Tab"))
 sequence.append(KeyReleaseAction(0, None, "KP_Insert"))
 sequence.append(utils.AssertPresentationAction(
     "1. Next form field",
-    ["BRAILLE LINE:  'search mozilla:  $l Go push button'",
-     "     VISIBLE:  'search mozilla:  $l Go push butt', cursor=17",
+    ["BRAILLE LINE:  'search mozilla:  $l'",
+     "     VISIBLE:  'search mozilla:  $l', cursor=17",
      "SPEECH OUTPUT: 'search mozilla: entry'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -25,7 +25,7 @@ sequence.append(KeyComboAction("Tab"))
 sequence.append(KeyReleaseAction(0, None, "KP_Insert"))
 sequence.append(utils.AssertPresentationAction(
     "2. Next form field",
-    ["BRAILLE LINE:  'search mozilla:  $l Go push button'",
+    ["BRAILLE LINE:  'Go push button'",
      "     VISIBLE:  'Go push button', cursor=1",
      "SPEECH OUTPUT: 'Go push button'"]))
 
@@ -35,8 +35,8 @@ sequence.append(KeyComboAction("Tab"))
 sequence.append(KeyReleaseAction(0, None, "KP_Insert"))
 sequence.append(utils.AssertPresentationAction(
     "3. Next form field",
-    ["BRAILLE LINE:  'Your email address: $l'",
-     "     VISIBLE:  'Your email address: $l', cursor=20",
+    ["BRAILLE LINE:  'Your email address:  $l'",
+     "     VISIBLE:  'Your email address:  $l', cursor=21",
      "SPEECH OUTPUT: 'Your email address: entry'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -45,8 +45,8 @@ sequence.append(KeyComboAction("Tab"))
 sequence.append(KeyReleaseAction(0, None, "KP_Insert"))
 sequence.append(utils.AssertPresentationAction(
     "4. Next form field",
-    ["BRAILLE LINE:  'Your name (optional): $l'",
-     "     VISIBLE:  'Your name (optional): $l', cursor=22",
+    ["BRAILLE LINE:  'Your name (optional):  $l'",
+     "     VISIBLE:  'Your name (optional):  $l', cursor=23",
      "SPEECH OUTPUT: 'Your name (optional): entry'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -55,8 +55,8 @@ sequence.append(KeyComboAction("Tab"))
 sequence.append(KeyReleaseAction(0, None, "KP_Insert"))
 sequence.append(utils.AssertPresentationAction(
     "5. Next form field",
-    ["BRAILLE LINE:  'Pick a password: $l'",
-     "     VISIBLE:  'Pick a password: $l', cursor=17",
+    ["BRAILLE LINE:  'Pick a password:  $l'",
+     "     VISIBLE:  'Pick a password:  $l', cursor=18",
      "SPEECH OUTPUT: 'Pick a password: password text'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -65,8 +65,8 @@ sequence.append(KeyComboAction("Tab"))
 sequence.append(KeyReleaseAction(0, None, "KP_Insert"))
 sequence.append(utils.AssertPresentationAction(
     "6. Next form field",
-    ["BRAILLE LINE:  'Reenter password to confirm: $l'",
-     "     VISIBLE:  'Reenter password to confirm: $l', cursor=29",
+    ["BRAILLE LINE:  'Reenter password to confirm:  $l'",
+     "     VISIBLE:  'Reenter password to confirm:  $l', cursor=30",
      "SPEECH OUTPUT: 'Reenter password to confirm: password text'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -75,8 +75,8 @@ sequence.append(KeyComboAction("Tab"))
 sequence.append(KeyReleaseAction(0, None, "KP_Insert"))
 sequence.append(utils.AssertPresentationAction(
     "7. Next form field",
-    ["BRAILLE LINE:  '&=y radio button No & y radio button Yes'",
-     "     VISIBLE:  '&=y radio button No & y radio bu', cursor=1",
+    ["BRAILLE LINE:  '&=y No radio button'",
+     "     VISIBLE:  '&=y No radio button', cursor=1",
      "SPEECH OUTPUT: 'No selected radio button'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -85,8 +85,8 @@ sequence.append(KeyComboAction("Tab"))
 sequence.append(KeyReleaseAction(0, None, "KP_Insert"))
 sequence.append(utils.AssertPresentationAction(
     "8. Next form field",
-    ["BRAILLE LINE:  '&=y radio button No & y radio button Yes'",
-     "     VISIBLE:  '& y radio button Yes', cursor=1",
+    ["BRAILLE LINE:  '& y Yes radio button'",
+     "     VISIBLE:  '& y Yes radio button', cursor=1",
      "SPEECH OUTPUT: 'Yes not selected radio button'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -105,8 +105,8 @@ sequence.append(KeyComboAction("Tab"))
 sequence.append(KeyReleaseAction(0, None, "KP_Insert"))
 sequence.append(utils.AssertPresentationAction(
     "10. Next form field",
-    ["BRAILLE LINE:  'Admin address:  $l Password:  $l Visit Subscriber List push button'",
-     "     VISIBLE:  ' $l Password:  $l Visit Subscrib', cursor=1",
+    ["BRAILLE LINE:  'Admin address:  $l'",
+     "     VISIBLE:  'Admin address:  $l', cursor=16",
      "SPEECH OUTPUT: 'Admin address: entry'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -115,8 +115,8 @@ sequence.append(KeyComboAction("Tab"))
 sequence.append(KeyReleaseAction(0, None, "KP_Insert"))
 sequence.append(utils.AssertPresentationAction(
     "11. Next form field",
-    ["BRAILLE LINE:  'Admin address:  $l Password:  $l Visit Subscriber List push button'",
-     "     VISIBLE:  ' $l Visit Subscriber List push b', cursor=1",
+    ["BRAILLE LINE:  'Password:  $l'",
+     "     VISIBLE:  'Password:  $l', cursor=11",
      "SPEECH OUTPUT: 'Password: password text'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -125,7 +125,7 @@ sequence.append(KeyComboAction("Tab"))
 sequence.append(KeyReleaseAction(0, None, "KP_Insert"))
 sequence.append(utils.AssertPresentationAction(
     "12. Next form field",
-    ["BRAILLE LINE:  'Admin address:  $l Password:  $l Visit Subscriber List push button'",
+    ["BRAILLE LINE:  'Visit Subscriber List push button'",
      "     VISIBLE:  'Visit Subscriber List push butto', cursor=1",
      "SPEECH OUTPUT: 'Visit Subscriber List push button'"]))
 
@@ -135,9 +135,9 @@ sequence.append(KeyComboAction("Tab"))
 sequence.append(KeyReleaseAction(0, None, "KP_Insert"))
 sequence.append(utils.AssertPresentationAction(
     "13. Next form field",
-    ["BRAILLE LINE:  ' $l Unsubscribe or edit options push button'",
-     "     VISIBLE:  ' $l Unsubscribe or edit options ', cursor=1",
-     "SPEECH OUTPUT: 'entry'"]))
+    ["BRAILLE LINE:  'your subscription email address:  $l'",
+     "     VISIBLE:  'ur subscription email address:  ', cursor=32",
+     "SPEECH OUTPUT: 'your subscription email address: entry'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyPressAction(0, None, "KP_Insert"))
@@ -145,7 +145,7 @@ sequence.append(KeyComboAction("Tab"))
 sequence.append(KeyReleaseAction(0, None, "KP_Insert"))
 sequence.append(utils.AssertPresentationAction(
     "14. Next form field",
-    ["BRAILLE LINE:  ' $l Unsubscribe or edit options push button'",
+    ["BRAILLE LINE:  'Unsubscribe or edit options push button'",
      "     VISIBLE:  'Unsubscribe or edit options push', cursor=1",
      "SPEECH OUTPUT: 'Unsubscribe or edit options push button'"]))
 
diff --git a/test/keystrokes/firefox/line_nav_bug_546815.py b/test/keystrokes/firefox/line_nav_bug_546815.py
index 5fb302c..0a10726 100644
--- a/test/keystrokes/firefox/line_nav_bug_546815.py
+++ b/test/keystrokes/firefox/line_nav_bug_546815.py
@@ -42,7 +42,8 @@ sequence.append(utils.AssertPresentationAction(
     "4. Line Down",
     ["BRAILLE LINE:  'Enter your Name:  $l text field using default type=text'",
      "     VISIBLE:  'Enter your Name:  $l text field ', cursor=1",
-     "SPEECH OUTPUT: 'Enter your Name: entry'",
+     "SPEECH OUTPUT: 'Enter your Name:'",
+     "SPEECH OUTPUT: 'entry'",
      "SPEECH OUTPUT: 'text field using default type=text'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -51,7 +52,8 @@ sequence.append(utils.AssertPresentationAction(
     "5. Line Down",
     ["BRAILLE LINE:  '1. Enter your Address:  $l text field using SIZE and'",
      "     VISIBLE:  '1. Enter your Address:  $l text ', cursor=1",
-     "SPEECH OUTPUT: '1. Enter your Address: entry'",
+     "SPEECH OUTPUT: '1. Enter your Address:'",
+     "SPEECH OUTPUT: 'entry'",
      "SPEECH OUTPUT: 'text field using SIZE and'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -68,9 +70,12 @@ sequence.append(utils.AssertPresentationAction(
     "7. Line Down",
     ["BRAILLE LINE:  '2. Enter your City:  $l 3. Enter your State:  $l 4. Enter your Country: US $l image 
text field using value'",
      "     VISIBLE:  '2. Enter your City:  $l 3. Enter', cursor=1",
-     "SPEECH OUTPUT: '2. Enter your City: entry'",
-     "SPEECH OUTPUT: '3. Enter your State: entry'",
-     "SPEECH OUTPUT: '4. Enter your Country: entry'",
+     "SPEECH OUTPUT: '2. Enter your City:'",
+     "SPEECH OUTPUT: 'entry'",
+     "SPEECH OUTPUT: '3. Enter your State:'",
+     "SPEECH OUTPUT: 'entry'",
+     "SPEECH OUTPUT: '4. Enter your Country:'",
+     "SPEECH OUTPUT: 'entry'",
      "SPEECH OUTPUT: 'US'",
      "SPEECH OUTPUT: 'image'",
      "SPEECH OUTPUT: 'text field using value'"]))
@@ -81,7 +86,8 @@ sequence.append(utils.AssertPresentationAction(
     "8. Line Down",
     ["BRAILLE LINE:  '5. Enter your Zip:  $l'",
      "     VISIBLE:  '5. Enter your Zip:  $l', cursor=1",
-     "SPEECH OUTPUT: '5. Enter your Zip: entry'"]))
+     "SPEECH OUTPUT: '5. Enter your Zip:'",
+     "SPEECH OUTPUT: 'entry'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
@@ -97,7 +103,8 @@ sequence.append(utils.AssertPresentationAction(
     "10. Line Down",
     ["BRAILLE LINE:  'character:  $l'",
      "     VISIBLE:  'character:  $l', cursor=1",
-     "SPEECH OUTPUT: 'character: entry'"]))
+     "SPEECH OUTPUT: 'character:'",
+     "SPEECH OUTPUT: 'entry'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
@@ -127,24 +134,24 @@ sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
 sequence.append(utils.AssertPresentationAction(
     "14. Line Down",
-    ["BRAILLE LINE:  '< > check box bird'",
-     "     VISIBLE:  '< > check box bird', cursor=1",
+    ["BRAILLE LINE:  '< > bird check box'",
+     "     VISIBLE:  '< > bird check box', cursor=1",
      "SPEECH OUTPUT: 'bird check box not checked'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
 sequence.append(utils.AssertPresentationAction(
     "15. Line Down",
-    ["BRAILLE LINE:  '< > check box fish'",
-     "     VISIBLE:  '< > check box fish', cursor=1",
+    ["BRAILLE LINE:  '< > fish check box'",
+     "     VISIBLE:  '< > fish check box', cursor=1",
      "SPEECH OUTPUT: 'fish check box not checked'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
 sequence.append(utils.AssertPresentationAction(
     "16. Line Down",
-    ["BRAILLE LINE:  '< > check box wild animal'",
-     "     VISIBLE:  '< > check box wild animal', cursor=1",
+    ["BRAILLE LINE:  '< > wild animal check box'",
+     "     VISIBLE:  '< > wild animal check box', cursor=1",
      "SPEECH OUTPUT: 'wild animal check box not checked'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -175,72 +182,72 @@ sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
 sequence.append(utils.AssertPresentationAction(
     "20. Line Down",
-    ["BRAILLE LINE:  '&=y radio button cabernet sauvignon'",
-     "     VISIBLE:  '&=y radio button cabernet sauvig', cursor=1",
+    ["BRAILLE LINE:  '&=y cabernet sauvignon radio button'",
+     "     VISIBLE:  '&=y cabernet sauvignon radio but', cursor=1",
      "SPEECH OUTPUT: 'cabernet sauvignon selected radio button'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
 sequence.append(utils.AssertPresentationAction(
     "21. Line Down",
-    ["BRAILLE LINE:  '& y radio button merlot'",
-     "     VISIBLE:  '& y radio button merlot', cursor=1",
+    ["BRAILLE LINE:  '& y merlot radio button'",
+     "     VISIBLE:  '& y merlot radio button', cursor=1",
      "SPEECH OUTPUT: 'merlot not selected radio button'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
 sequence.append(utils.AssertPresentationAction(
     "22. Line Down",
-    ["BRAILLE LINE:  '& y radio button nebbiolo'",
-     "     VISIBLE:  '& y radio button nebbiolo', cursor=1",
+    ["BRAILLE LINE:  '& y nebbiolo radio button'",
+     "     VISIBLE:  '& y nebbiolo radio button', cursor=1",
      "SPEECH OUTPUT: 'nebbiolo not selected radio button'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
 sequence.append(utils.AssertPresentationAction(
     "23. Line Down",
-    ["BRAILLE LINE:  '& y radio button pinot noir'",
-     "     VISIBLE:  '& y radio button pinot noir', cursor=1",
+    ["BRAILLE LINE:  '& y pinot noir radio button'",
+     "     VISIBLE:  '& y pinot noir radio button', cursor=1",
      "SPEECH OUTPUT: 'pinot noir not selected radio button'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
 sequence.append(utils.AssertPresentationAction(
     "24. Line Down",
-    ["BRAILLE LINE:  '& y radio button don't drink wine'",
-     "     VISIBLE:  '& y radio button don't drink win', cursor=1",
+    ["BRAILLE LINE:  '& y don't drink wine radio button'",
+     "     VISIBLE:  '& y don't drink wine radio butto', cursor=1",
      "SPEECH OUTPUT: 'don't drink wine not selected radio button'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
 sequence.append(utils.AssertPresentationAction(
     "25. Line Up",
-    ["BRAILLE LINE:  '& y radio button pinot noir'",
-     "     VISIBLE:  '& y radio button pinot noir', cursor=1",
+    ["BRAILLE LINE:  '& y pinot noir radio button'",
+     "     VISIBLE:  '& y pinot noir radio button', cursor=1",
      "SPEECH OUTPUT: 'pinot noir not selected radio button'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
 sequence.append(utils.AssertPresentationAction(
     "26. Line Up",
-    ["BRAILLE LINE:  '& y radio button nebbiolo'",
-     "     VISIBLE:  '& y radio button nebbiolo', cursor=1",
+    ["BRAILLE LINE:  '& y nebbiolo radio button'",
+     "     VISIBLE:  '& y nebbiolo radio button', cursor=1",
      "SPEECH OUTPUT: 'nebbiolo not selected radio button'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
 sequence.append(utils.AssertPresentationAction(
     "27. Line Up",
-    ["BRAILLE LINE:  '& y radio button merlot'",
-     "     VISIBLE:  '& y radio button merlot', cursor=1",
+    ["BRAILLE LINE:  '& y merlot radio button'",
+     "     VISIBLE:  '& y merlot radio button', cursor=1",
      "SPEECH OUTPUT: 'merlot not selected radio button'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
 sequence.append(utils.AssertPresentationAction(
     "28. Line Up",
-    ["BRAILLE LINE:  '&=y radio button cabernet sauvignon'",
-     "     VISIBLE:  '&=y radio button cabernet sauvig', cursor=1",
+    ["BRAILLE LINE:  '&=y cabernet sauvignon radio button'",
+     "     VISIBLE:  '&=y cabernet sauvignon radio but', cursor=1",
      "SPEECH OUTPUT: 'cabernet sauvignon selected radio button'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -271,24 +278,24 @@ sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
 sequence.append(utils.AssertPresentationAction(
     "32. Line Up",
-    ["BRAILLE LINE:  '< > check box wild animal'",
-     "     VISIBLE:  '< > check box wild animal', cursor=1",
+    ["BRAILLE LINE:  '< > wild animal check box'",
+     "     VISIBLE:  '< > wild animal check box', cursor=1",
      "SPEECH OUTPUT: 'wild animal check box not checked'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
 sequence.append(utils.AssertPresentationAction(
     "33. Line Up",
-    ["BRAILLE LINE:  '< > check box fish'",
-     "     VISIBLE:  '< > check box fish', cursor=1",
+    ["BRAILLE LINE:  '< > fish check box'",
+     "     VISIBLE:  '< > fish check box', cursor=1",
      "SPEECH OUTPUT: 'fish check box not checked'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
 sequence.append(utils.AssertPresentationAction(
     "34. Line Up",
-    ["BRAILLE LINE:  '< > check box bird'",
-     "     VISIBLE:  '< > check box bird', cursor=1",
+    ["BRAILLE LINE:  '< > bird check box'",
+     "     VISIBLE:  '< > bird check box', cursor=1",
      "SPEECH OUTPUT: 'bird check box not checked'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -321,7 +328,8 @@ sequence.append(utils.AssertPresentationAction(
     "38. Line Up",
     ["BRAILLE LINE:  'character:  $l'",
      "     VISIBLE:  'character:  $l', cursor=1",
-     "SPEECH OUTPUT: 'character: entry'"]))
+     "SPEECH OUTPUT: 'character:'",
+     "SPEECH OUTPUT: 'entry'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
@@ -337,7 +345,8 @@ sequence.append(utils.AssertPresentationAction(
     "40. Line Up",
     ["BRAILLE LINE:  '5. Enter your Zip:  $l'",
      "     VISIBLE:  '5. Enter your Zip:  $l', cursor=1",
-     "SPEECH OUTPUT: '5. Enter your Zip: entry'"]))
+     "SPEECH OUTPUT: '5. Enter your Zip:'",
+     "SPEECH OUTPUT: 'entry'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
@@ -345,9 +354,12 @@ sequence.append(utils.AssertPresentationAction(
     "41. Line Up",
     ["BRAILLE LINE:  '2. Enter your City:  $l 3. Enter your State:  $l 4. Enter your Country: US $l image 
text field using value'",
      "     VISIBLE:  '2. Enter your City:  $l 3. Enter', cursor=1",
-     "SPEECH OUTPUT: '2. Enter your City: entry'",
-     "SPEECH OUTPUT: '3. Enter your State: entry'",
-     "SPEECH OUTPUT: '4. Enter your Country: entry'",
+     "SPEECH OUTPUT: '2. Enter your City:'",
+     "SPEECH OUTPUT: 'entry'",
+     "SPEECH OUTPUT: '3. Enter your State:'",
+     "SPEECH OUTPUT: 'entry'",
+     "SPEECH OUTPUT: '4. Enter your Country:'",
+     "SPEECH OUTPUT: 'entry'",
      "SPEECH OUTPUT: 'US'",
      "SPEECH OUTPUT: 'image'",
      "SPEECH OUTPUT: 'text field using value'"]))
@@ -366,7 +378,8 @@ sequence.append(utils.AssertPresentationAction(
     "43. Line Up",
     ["BRAILLE LINE:  '1. Enter your Address:  $l text field using SIZE and'",
      "     VISIBLE:  '1. Enter your Address:  $l text ', cursor=1",
-     "SPEECH OUTPUT: '1. Enter your Address: entry'",
+     "SPEECH OUTPUT: '1. Enter your Address:'",
+     "SPEECH OUTPUT: 'entry'",
      "SPEECH OUTPUT: 'text field using SIZE and'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -375,7 +388,8 @@ sequence.append(utils.AssertPresentationAction(
     "44. Line Up",
     ["BRAILLE LINE:  'Enter your Name:  $l text field using default type=text'",
      "     VISIBLE:  'Enter your Name:  $l text field ', cursor=1",
-     "SPEECH OUTPUT: 'Enter your Name: entry'",
+     "SPEECH OUTPUT: 'Enter your Name:'",
+     "SPEECH OUTPUT: 'entry'",
      "SPEECH OUTPUT: 'text field using default type=text'"]))
 
 sequence.append(utils.StartRecordingAction())
diff --git a/test/keystrokes/firefox/line_nav_bug_549128.py b/test/keystrokes/firefox/line_nav_bug_549128.py
index a9ca72f..5779393 100644
--- a/test/keystrokes/firefox/line_nav_bug_549128.py
+++ b/test/keystrokes/firefox/line_nav_bug_549128.py
@@ -49,15 +49,14 @@ sequence.append(utils.AssertPresentationAction(
     "5. Line Down",
     ["BRAILLE LINE:  'The Ideal Gift Collection'",
      "     VISIBLE:  'The Ideal Gift Collection', cursor=1",
-     "SPEECH OUTPUT: 'The Ideal Gift Collection'",
-     "SPEECH OUTPUT: 'link'"]))
+     "SPEECH OUTPUT: 'The Ideal Gift Collection link'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
 sequence.append(utils.AssertPresentationAction(
     "6. Line Down",
     ["BRAILLE LINE:  '2 (5 oz.) Filet Mignons'",
-     "     VISIBLE:  '2 (5 oz.) Filet Mignons', cursor=0",
+     "     VISIBLE:  '2 (5 oz.) Filet Mignons', cursor=1",
      "SPEECH OUTPUT: '2 (5 oz.) Filet Mignons'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -65,7 +64,7 @@ sequence.append(KeyComboAction("Down"))
 sequence.append(utils.AssertPresentationAction(
     "7. Line Down",
     ["BRAILLE LINE:  '2 (5 oz.) Top Sirloins'",
-     "     VISIBLE:  '2 (5 oz.) Top Sirloins', cursor=0",
+     "     VISIBLE:  '2 (5 oz.) Top Sirloins', cursor=1",
      "SPEECH OUTPUT: '2 (5 oz.) Top Sirloins'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -73,7 +72,7 @@ sequence.append(KeyComboAction("Down"))
 sequence.append(utils.AssertPresentationAction(
     "8. Line Down",
     ["BRAILLE LINE:  '4 (4 oz.) Foobar Steaks Burgers'",
-     "     VISIBLE:  '4 (4 oz.) Foobar Steaks Burgers', cursor=0",
+     "     VISIBLE:  '4 (4 oz.) Foobar Steaks Burgers', cursor=1",
      "SPEECH OUTPUT: '4 (4 oz.) Foobar Steaks Burgers'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -81,7 +80,7 @@ sequence.append(KeyComboAction("Down"))
 sequence.append(utils.AssertPresentationAction(
     "9. Line Down",
     ["BRAILLE LINE:  '6 (5.75 oz.) Stuffed Baked Potatoes'",
-     "     VISIBLE:  '6 (5.75 oz.) Stuffed Baked Potat', cursor=0",
+     "     VISIBLE:  '6 (5.75 oz.) Stuffed Baked Potat', cursor=1",
      "SPEECH OUTPUT: '6 (5.75 oz.) Stuffed Baked Potatoes'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -89,7 +88,7 @@ sequence.append(KeyComboAction("Down"))
 sequence.append(utils.AssertPresentationAction(
     "10. Line Down",
     ["BRAILLE LINE:  '2 (4.5 oz.) Stuffed Sole with Scallops and Crab'",
-     "     VISIBLE:  '2 (4.5 oz.) Stuffed Sole with Sc', cursor=0",
+     "     VISIBLE:  '2 (4.5 oz.) Stuffed Sole with Sc', cursor=1",
      "SPEECH OUTPUT: '2 (4.5 oz.) Stuffed Sole with Scallops and Crab'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -97,7 +96,7 @@ sequence.append(KeyComboAction("Down"))
 sequence.append(utils.AssertPresentationAction(
     "11. Line Down",
     ["BRAILLE LINE:  '1 (6 in.) Chocolate Lover's Cake'",
-     "     VISIBLE:  '1 (6 in.) Chocolate Lover's Cake', cursor=0",
+     "     VISIBLE:  '1 (6 in.) Chocolate Lover's Cake', cursor=1",
      "SPEECH OUTPUT: '1 (6 in.) Chocolate Lover's Cake'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -119,7 +118,7 @@ sequence.append(KeyComboAction("Up"))
 sequence.append(utils.AssertPresentationAction(
     "14. Line Up",
     ["BRAILLE LINE:  '1 (6 in.) Chocolate Lover's Cake'",
-     "     VISIBLE:  '1 (6 in.) Chocolate Lover's Cake', cursor=0",
+     "     VISIBLE:  '1 (6 in.) Chocolate Lover's Cake', cursor=1",
      "SPEECH OUTPUT: '1 (6 in.) Chocolate Lover's Cake'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -127,7 +126,7 @@ sequence.append(KeyComboAction("Up"))
 sequence.append(utils.AssertPresentationAction(
     "15. Line Up",
     ["BRAILLE LINE:  '2 (4.5 oz.) Stuffed Sole with Scallops and Crab'",
-     "     VISIBLE:  '2 (4.5 oz.) Stuffed Sole with Sc', cursor=0",
+     "     VISIBLE:  '2 (4.5 oz.) Stuffed Sole with Sc', cursor=1",
      "SPEECH OUTPUT: '2 (4.5 oz.) Stuffed Sole with Scallops and Crab'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -135,7 +134,7 @@ sequence.append(KeyComboAction("Up"))
 sequence.append(utils.AssertPresentationAction(
     "16. Line Up",
     ["BRAILLE LINE:  '6 (5.75 oz.) Stuffed Baked Potatoes'",
-     "     VISIBLE:  '6 (5.75 oz.) Stuffed Baked Potat', cursor=0",
+     "     VISIBLE:  '6 (5.75 oz.) Stuffed Baked Potat', cursor=1",
      "SPEECH OUTPUT: '6 (5.75 oz.) Stuffed Baked Potatoes'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -143,7 +142,7 @@ sequence.append(KeyComboAction("Up"))
 sequence.append(utils.AssertPresentationAction(
     "17. Line Up",
     ["BRAILLE LINE:  '4 (4 oz.) Foobar Steaks Burgers'",
-     "     VISIBLE:  '4 (4 oz.) Foobar Steaks Burgers', cursor=0",
+     "     VISIBLE:  '4 (4 oz.) Foobar Steaks Burgers', cursor=1",
      "SPEECH OUTPUT: '4 (4 oz.) Foobar Steaks Burgers'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -151,7 +150,7 @@ sequence.append(KeyComboAction("Up"))
 sequence.append(utils.AssertPresentationAction(
     "18. Line Up",
     ["BRAILLE LINE:  '2 (5 oz.) Top Sirloins'",
-     "     VISIBLE:  '2 (5 oz.) Top Sirloins', cursor=0",
+     "     VISIBLE:  '2 (5 oz.) Top Sirloins', cursor=1",
      "SPEECH OUTPUT: '2 (5 oz.) Top Sirloins'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -159,7 +158,7 @@ sequence.append(KeyComboAction("Up"))
 sequence.append(utils.AssertPresentationAction(
     "19. Line Up",
     ["BRAILLE LINE:  '2 (5 oz.) Filet Mignons'",
-     "     VISIBLE:  '2 (5 oz.) Filet Mignons', cursor=0",
+     "     VISIBLE:  '2 (5 oz.) Filet Mignons', cursor=1",
      "SPEECH OUTPUT: '2 (5 oz.) Filet Mignons'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -168,8 +167,7 @@ sequence.append(utils.AssertPresentationAction(
     "20. Line Up",
     ["BRAILLE LINE:  'The Ideal Gift Collection'",
      "     VISIBLE:  'The Ideal Gift Collection', cursor=1",
-     "SPEECH OUTPUT: 'The Ideal Gift Collection'",
-     "SPEECH OUTPUT: 'link'"]))
+     "SPEECH OUTPUT: 'The Ideal Gift Collection link'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
diff --git a/test/keystrokes/firefox/line_nav_bug_552887a.py b/test/keystrokes/firefox/line_nav_bug_552887a.py
index ca1f871..5645dcc 100644
--- a/test/keystrokes/firefox/line_nav_bug_552887a.py
+++ b/test/keystrokes/firefox/line_nav_bug_552887a.py
@@ -15,8 +15,8 @@ sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("<Control>Home"))
 sequence.append(utils.AssertPresentationAction(
     "1. Top of file",
-    ["BRAILLE LINE:  ' $l'",
-     "     VISIBLE:  ' $l', cursor=1",
+    ["BRAILLE LINE:  ''",
+     "     VISIBLE:  '', cursor=0",
      "SPEECH OUTPUT: 'blank'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -49,7 +49,7 @@ sequence.append(utils.AssertPresentationAction(
     "5. Line Down",
     ["BRAILLE LINE:  'The Orca logo image '",
      "     VISIBLE:  'The Orca logo image ', cursor=1",
-     "SPEECH OUTPUT: 'The Orca logo image link Hey, look, it's our logo!'"]))
+     "SPEECH OUTPUT: 'The Orca logo image Hey, look, it's our logo!'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
@@ -57,7 +57,7 @@ sequence.append(utils.AssertPresentationAction(
     "6. Line Down",
     ["BRAILLE LINE:  'Can an Orca really'",
      "     VISIBLE:  'Can an Orca really', cursor=1",
-     "SPEECH OUTPUT: 'Can an Orca really'"]))
+     "SPEECH OUTPUT: 'link Can an Orca really'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
@@ -65,7 +65,7 @@ sequence.append(utils.AssertPresentationAction(
     "7. Line Down",
     ["BRAILLE LINE:  'hold a white cane?'",
      "     VISIBLE:  'hold a white cane?', cursor=1",
-     "SPEECH OUTPUT: 'hold a white cane?'"]))
+     "SPEECH OUTPUT: 'link hold a white cane?'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
@@ -73,7 +73,7 @@ sequence.append(utils.AssertPresentationAction(
     "8. Line Down",
     ["BRAILLE LINE:  '\(And why aren't we'",
      "     VISIBLE:  '\(And why aren't we', cursor=1",
-     "SPEECH OUTPUT: '\(And why aren't we'"]))
+     "SPEECH OUTPUT: 'link \(And why aren't we'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
@@ -81,7 +81,7 @@ sequence.append(utils.AssertPresentationAction(
     "9. Line Down",
     ["BRAILLE LINE:  'speaking this text?'",
      "     VISIBLE:  'speaking this text?', cursor=1",
-     "SPEECH OUTPUT: 'speaking this text?'"]))
+     "SPEECH OUTPUT: 'link speaking this text?'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
@@ -183,14 +183,6 @@ sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
 sequence.append(utils.AssertPresentationAction(
     "22. Line Up",
-    ["BRAILLE LINE:  ' $l'",
-     "     VISIBLE:  ' $l', cursor=1",
-     "SPEECH OUTPUT: 'blank'"]))
-
-sequence.append(utils.StartRecordingAction())
-sequence.append(KeyComboAction("Up"))
-sequence.append(utils.AssertPresentationAction(
-    "23. Line Up",
     ["BRAILLE LINE:  'This text comes before the box section'",
      "     VISIBLE:  'This text comes before the box s', cursor=1",
      "SPEECH OUTPUT: 'This text comes before the box section'"]))
@@ -198,47 +190,47 @@ sequence.append(utils.AssertPresentationAction(
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
 sequence.append(utils.AssertPresentationAction(
-    "24. Line Up",
+    "23. Line Up",
     ["BRAILLE LINE:  'speaking this text?'",
      "     VISIBLE:  'speaking this text?', cursor=1",
-     "SPEECH OUTPUT: 'speaking this text?'"]))
+     "SPEECH OUTPUT: 'link speaking this text?'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
 sequence.append(utils.AssertPresentationAction(
-    "25. Line Up",
+    "24. Line Up",
     ["BRAILLE LINE:  '\(And why aren't we'",
      "     VISIBLE:  '\(And why aren't we', cursor=1",
-     "SPEECH OUTPUT: '\(And why aren't we'"]))
+     "SPEECH OUTPUT: 'link \(And why aren't we'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
 sequence.append(utils.AssertPresentationAction(
-    "26. Line Up",
+    "25. Line Up",
     ["BRAILLE LINE:  'hold a white cane?'",
      "     VISIBLE:  'hold a white cane?', cursor=1",
-     "SPEECH OUTPUT: 'hold a white cane?'"]))
+     "SPEECH OUTPUT: 'link hold a white cane?'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
 sequence.append(utils.AssertPresentationAction(
-    "27. Line Up",
+    "26. Line Up",
     ["BRAILLE LINE:  'Can an Orca really'",
      "     VISIBLE:  'Can an Orca really', cursor=1",
-     "SPEECH OUTPUT: 'Can an Orca really'"]))
+     "SPEECH OUTPUT: 'link Can an Orca really'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
 sequence.append(utils.AssertPresentationAction(
-    "28. Line Up",
+    "27. Line Up",
     ["BRAILLE LINE:  'The Orca logo image '",
      "     VISIBLE:  'The Orca logo image ', cursor=1",
-     "SPEECH OUTPUT: 'The Orca logo image link Hey, look, it's our logo!'"]))
+     "SPEECH OUTPUT: 'The Orca logo image Hey, look, it's our logo!'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
 sequence.append(utils.AssertPresentationAction(
-    "29. Line Up",
+    "28. Line Up",
     ["BRAILLE LINE:  'Line 3'",
      "     VISIBLE:  'Line 3', cursor=1",
      "SPEECH OUTPUT: 'Line 3'"]))
@@ -246,7 +238,7 @@ sequence.append(utils.AssertPresentationAction(
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
 sequence.append(utils.AssertPresentationAction(
-    "30. Line Up",
+    "29. Line Up",
     ["BRAILLE LINE:  'Line 2 h2'",
      "     VISIBLE:  'Line 2 h2', cursor=1",
      "SPEECH OUTPUT: 'Line 2 heading level 2'"]))
@@ -254,20 +246,10 @@ sequence.append(utils.AssertPresentationAction(
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
 sequence.append(utils.AssertPresentationAction(
-    "31. Line Up",
-    ["KNOWN ISSUE: We're presenting these together on the way up",
-     "BRAILLE LINE:  'Line 1 Line 2 h2'",
-     "     VISIBLE:  'Line 1 Line 2 h2', cursor=1",
-     "SPEECH OUTPUT: 'Line 1'",
-     "SPEECH OUTPUT: 'Line 2 heading level 2'"]))
-
-sequence.append(utils.StartRecordingAction())
-sequence.append(KeyComboAction("Up"))
-sequence.append(utils.AssertPresentationAction(
-    "32. Line Up",
-    ["BRAILLE LINE:  ' $l'",
-     "     VISIBLE:  ' $l', cursor=1",
-     "SPEECH OUTPUT: 'blank'"]))
+    "30. Line Up",
+    ["BRAILLE LINE:  'Line 1'",
+     "     VISIBLE:  'Line 1', cursor=1",
+     "SPEECH OUTPUT: 'Line 1'"]))
 
 sequence.append(utils.AssertionSummaryAction())
 sequence.start()
diff --git a/test/keystrokes/firefox/line_nav_bug_554616.py b/test/keystrokes/firefox/line_nav_bug_554616.py
index 1317dd2..a3e0bb3 100644
--- a/test/keystrokes/firefox/line_nav_bug_554616.py
+++ b/test/keystrokes/firefox/line_nav_bug_554616.py
@@ -34,8 +34,7 @@ sequence.append(utils.AssertPresentationAction(
     "3. Line Down",
     ["BRAILLE LINE:  'installer (10190 KB)'",
      "     VISIBLE:  'installer (10190 KB)', cursor=1",
-     "SPEECH OUTPUT: 'installer'",
-     "SPEECH OUTPUT: 'link'",
+     "SPEECH OUTPUT: 'installer link'",
      "SPEECH OUTPUT: '(10190 KB)'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -44,8 +43,7 @@ sequence.append(utils.AssertPresentationAction(
     "4. Line Down",
     ["BRAILLE LINE:  'portable archive (9154 KB)'",
      "     VISIBLE:  'portable archive (9154 KB)', cursor=1",
-     "SPEECH OUTPUT: 'portable archive'",
-     "SPEECH OUTPUT: 'link'",
+     "SPEECH OUTPUT: 'portable archive link'",
      "SPEECH OUTPUT: '(9154 KB)'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -63,8 +61,7 @@ sequence.append(utils.AssertPresentationAction(
     "6. Line Down",
     ["BRAILLE LINE:  'installer (10193 KB)'",
      "     VISIBLE:  'installer (10193 KB)', cursor=1",
-     "SPEECH OUTPUT: 'installer'",
-     "SPEECH OUTPUT: 'link'",
+     "SPEECH OUTPUT: 'installer link'",
      "SPEECH OUTPUT: '(10193 KB)'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -73,48 +70,58 @@ sequence.append(utils.AssertPresentationAction(
     "7. Line Down",
     ["BRAILLE LINE:  'portable archive (9149 KB)'",
      "     VISIBLE:  'portable archive (9149 KB)', cursor=1",
-     "SPEECH OUTPUT: 'portable archive'",
-     "SPEECH OUTPUT: 'link'",
+     "SPEECH OUTPUT: 'portable archive link'",
      "SPEECH OUTPUT: '(9149 KB)'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
 sequence.append(utils.AssertPresentationAction(
     "8. Line Up",
-    ["BRAILLE LINE:  'r2468 Tue Nov 4 16:39:02 2008 installer (10193 KB)'",
-     "     VISIBLE:  'r2468 Tue Nov 4 16:39:02 2008 in', cursor=1",
-     "SPEECH OUTPUT: 'r2468'",
-     "SPEECH OUTPUT: 'Tue Nov 4 16:39:02 2008'",
-     "SPEECH OUTPUT: 'installer'",
-     "SPEECH OUTPUT: 'link'",
+    ["BRAILLE LINE:  'installer (10193 KB)'",
+     "     VISIBLE:  'installer (10193 KB)', cursor=1",
+     "SPEECH OUTPUT: 'installer link'",
      "SPEECH OUTPUT: '(10193 KB)'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
 sequence.append(utils.AssertPresentationAction(
     "9. Line Up",
+    ["BRAILLE LINE:  'r2468 Tue Nov 4 16:39:02 2008'",
+     "     VISIBLE:  'r2468 Tue Nov 4 16:39:02 2008', cursor=1",
+     "SPEECH OUTPUT: 'r2468'",
+     "SPEECH OUTPUT: 'Tue Nov 4 16:39:02 2008'"]))
+
+sequence.append(utils.StartRecordingAction())
+sequence.append(KeyComboAction("Up"))
+sequence.append(utils.AssertPresentationAction(
+    "10. Line Up",
     ["BRAILLE LINE:  'portable archive (9154 KB)'",
      "     VISIBLE:  'portable archive (9154 KB)', cursor=1",
-     "SPEECH OUTPUT: 'portable archive'",
-     "SPEECH OUTPUT: 'link'",
+     "SPEECH OUTPUT: 'portable archive link'",
      "SPEECH OUTPUT: '(9154 KB)'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
 sequence.append(utils.AssertPresentationAction(
-    "10. Line Up",
-    ["BRAILLE LINE:  'r2477 Wed Nov 5 16:39:00 2008 installer (10190 KB)'",
-     "     VISIBLE:  'r2477 Wed Nov 5 16:39:00 2008 in', cursor=1",
-     "SPEECH OUTPUT: 'r2477'",
-     "SPEECH OUTPUT: 'Wed Nov 5 16:39:00 2008'",
-     "SPEECH OUTPUT: 'installer'",
-     "SPEECH OUTPUT: 'link'",
+    "11. Line Up",
+    ["BRAILLE LINE:  'installer (10190 KB)'",
+     "     VISIBLE:  'installer (10190 KB)', cursor=1",
+     "SPEECH OUTPUT: 'installer link'",
      "SPEECH OUTPUT: '(10190 KB)'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
 sequence.append(utils.AssertPresentationAction(
-    "11. Line Up",
+    "12. Line Up",
+    ["BRAILLE LINE:  'r2477 Wed Nov 5 16:39:00 2008'",
+     "     VISIBLE:  'r2477 Wed Nov 5 16:39:00 2008', cursor=1",
+     "SPEECH OUTPUT: 'r2477'",
+     "SPEECH OUTPUT: 'Wed Nov 5 16:39:00 2008'"]))
+
+sequence.append(utils.StartRecordingAction())
+sequence.append(KeyComboAction("Up"))
+sequence.append(utils.AssertPresentationAction(
+    "13. Line Up",
     ["BRAILLE LINE:  'Snapshot version Date (UTC) Download'",
      "     VISIBLE:  'Snapshot version Date (UTC) Down', cursor=1",
      "SPEECH OUTPUT: 'Snapshot version column header'",
diff --git a/test/keystrokes/firefox/line_nav_bug_555055.py b/test/keystrokes/firefox/line_nav_bug_555055.py
index 7711e8a..2ebe0b4 100644
--- a/test/keystrokes/firefox/line_nav_bug_555055.py
+++ b/test/keystrokes/firefox/line_nav_bug_555055.py
@@ -54,14 +54,6 @@ sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
 sequence.append(utils.AssertPresentationAction(
     "6. Line Down",
-    ["BRAILLE LINE:  ''",
-     "     VISIBLE:  '', cursor=1",
-     "SPEECH OUTPUT: 'blank'"]))
-
-sequence.append(utils.StartRecordingAction())
-sequence.append(KeyComboAction("Down"))
-sequence.append(utils.AssertPresentationAction(
-    "7. Line Down",
     ["BRAILLE LINE:  'Item 1'",
      "     VISIBLE:  'Item 1', cursor=1",
      "SPEECH OUTPUT: 'Item 1'"]))
@@ -69,7 +61,7 @@ sequence.append(utils.AssertPresentationAction(
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
 sequence.append(utils.AssertPresentationAction(
-    "8. Line Down",
+    "7. Line Down",
     ["BRAILLE LINE:  'Item 2'",
      "     VISIBLE:  'Item 2', cursor=1",
      "SPEECH OUTPUT: 'Item 2'"]))
@@ -77,7 +69,7 @@ sequence.append(utils.AssertPresentationAction(
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
 sequence.append(utils.AssertPresentationAction(
-    "9. Line Down",
+    "8. Line Down",
     ["BRAILLE LINE:  'Item 3'",
      "     VISIBLE:  'Item 3', cursor=1",
      "SPEECH OUTPUT: 'Item 3'"]))
@@ -85,15 +77,7 @@ sequence.append(utils.AssertPresentationAction(
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
 sequence.append(utils.AssertPresentationAction(
-    "10. Line Down",
-    ["BRAILLE LINE:  ''",
-     "     VISIBLE:  '', cursor=1",
-     "SPEECH OUTPUT: 'blank'"]))
-
-sequence.append(utils.StartRecordingAction())
-sequence.append(KeyComboAction("Down"))
-sequence.append(utils.AssertPresentationAction(
-    "11. Line Down",
+    "9. Line Down",
     ["BRAILLE LINE:  'This table is messed up.'",
      "     VISIBLE:  'This table is messed up.', cursor=1",
      "SPEECH OUTPUT: 'This table is messed up.'"]))
@@ -101,7 +85,7 @@ sequence.append(utils.AssertPresentationAction(
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
 sequence.append(utils.AssertPresentationAction(
-    "12. Line Down",
+    "10. Line Down",
     ["BRAILLE LINE:  'Here's a cell'",
      "     VISIBLE:  'Here's a cell', cursor=1",
      "SPEECH OUTPUT: 'Here's a cell'"]))
@@ -109,7 +93,7 @@ sequence.append(utils.AssertPresentationAction(
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
 sequence.append(utils.AssertPresentationAction(
-    "13. Line Up",
+    "11. Line Up",
     ["BRAILLE LINE:  'This table is messed up.'",
      "     VISIBLE:  'This table is messed up.', cursor=1",
      "SPEECH OUTPUT: 'This table is messed up.'"]))
@@ -117,23 +101,7 @@ sequence.append(utils.AssertPresentationAction(
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
 sequence.append(utils.AssertPresentationAction(
-    "14. Line Up",
-    ["BRAILLE LINE:  ''",
-     "     VISIBLE:  '', cursor=1",
-     "SPEECH OUTPUT: 'blank'"]))
-
-sequence.append(utils.StartRecordingAction())
-sequence.append(KeyComboAction("Up"))
-sequence.append(utils.AssertPresentationAction(
-    "15. Line Up",
-    ["BRAILLE LINE:  '  '",
-     "     VISIBLE:  '  ', cursor=1",
-     "SPEECH OUTPUT: 'blank'"]))
-
-sequence.append(utils.StartRecordingAction())
-sequence.append(KeyComboAction("Up"))
-sequence.append(utils.AssertPresentationAction(
-    "16. Line Up",
+    "12. Line Up",
     ["BRAILLE LINE:  'Item 3'",
      "     VISIBLE:  'Item 3', cursor=1",
      "SPEECH OUTPUT: 'Item 3'"]))
@@ -141,7 +109,7 @@ sequence.append(utils.AssertPresentationAction(
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
 sequence.append(utils.AssertPresentationAction(
-    "17. Line Up",
+    "13. Line Up",
     ["BRAILLE LINE:  'Item 2'",
      "     VISIBLE:  'Item 2', cursor=1",
      "SPEECH OUTPUT: 'Item 2'"]))
@@ -149,7 +117,7 @@ sequence.append(utils.AssertPresentationAction(
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
 sequence.append(utils.AssertPresentationAction(
-    "18. Line Up",
+    "14. Line Up",
     ["BRAILLE LINE:  'Item 1'",
      "     VISIBLE:  'Item 1', cursor=1",
      "SPEECH OUTPUT: 'Item 1'"]))
@@ -157,31 +125,7 @@ sequence.append(utils.AssertPresentationAction(
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
 sequence.append(utils.AssertPresentationAction(
-    "19. Line Up",
-    ["BRAILLE LINE:  ' '",
-     "     VISIBLE:  ' ', cursor=1",
-     "SPEECH OUTPUT: 'blank'"]))
-
-sequence.append(utils.StartRecordingAction())
-sequence.append(KeyComboAction("Up"))
-sequence.append(utils.AssertPresentationAction(
-    "20. Line Up",
-    ["BRAILLE LINE:  ''",
-     "     VISIBLE:  '', cursor=1",
-     "SPEECH OUTPUT: 'blank'"]))
-
-sequence.append(utils.StartRecordingAction())
-sequence.append(KeyComboAction("Up"))
-sequence.append(utils.AssertPresentationAction(
-    "21. Line Up",
-    ["BRAILLE LINE:  ' '",
-     "     VISIBLE:  ' ', cursor=1",
-     "SPEECH OUTPUT: 'blank'"]))
-
-sequence.append(utils.StartRecordingAction())
-sequence.append(KeyComboAction("Up"))
-sequence.append(utils.AssertPresentationAction(
-    "22. Line Up",
+    "15. Line Up",
     ["BRAILLE LINE:  'hi'",
      "     VISIBLE:  'hi', cursor=1",
      "SPEECH OUTPUT: 'hi'"]))
@@ -189,7 +133,7 @@ sequence.append(utils.AssertPresentationAction(
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
 sequence.append(utils.AssertPresentationAction(
-    "23. Line Up",
+    "16. Line Up",
     ["BRAILLE LINE:  'image'",
      "     VISIBLE:  'image', cursor=1",
      "SPEECH OUTPUT: 'image'"]))
@@ -197,7 +141,7 @@ sequence.append(utils.AssertPresentationAction(
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
 sequence.append(utils.AssertPresentationAction(
-    "24. Line Up",
+    "17. Line Up",
     ["BRAILLE LINE:  'image'",
      "     VISIBLE:  'image', cursor=1",
      "SPEECH OUTPUT: 'image'"]))
@@ -205,7 +149,7 @@ sequence.append(utils.AssertPresentationAction(
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
 sequence.append(utils.AssertPresentationAction(
-    "25. Line Up",
+    "18. Line Up",
     ["BRAILLE LINE:  'image'",
      "     VISIBLE:  'image', cursor=1",
      "SPEECH OUTPUT: 'image'"]))
@@ -213,15 +157,7 @@ sequence.append(utils.AssertPresentationAction(
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
 sequence.append(utils.AssertPresentationAction(
-    "26. Line Up",
-    ["BRAILLE LINE:  ' '",
-     "     VISIBLE:  ' ', cursor=1",
-     "SPEECH OUTPUT: 'blank'"]))
-
-sequence.append(utils.StartRecordingAction())
-sequence.append(KeyComboAction("Up"))
-sequence.append(utils.AssertPresentationAction(
-    "27. Line Up",
+    "19. Line Up",
     ["BRAILLE LINE:  'Hello world!'",
      "     VISIBLE:  'Hello world!', cursor=1",
      "SPEECH OUTPUT: 'Hello world!'"]))
diff --git a/test/keystrokes/firefox/line_nav_bug_577239.py b/test/keystrokes/firefox/line_nav_bug_577239.py
index 77c95b7..2db145f 100644
--- a/test/keystrokes/firefox/line_nav_bug_577239.py
+++ b/test/keystrokes/firefox/line_nav_bug_577239.py
@@ -29,7 +29,7 @@ sequence.append(utils.AssertPresentationAction(
     "3. Line Down",
     ["BRAILLE LINE:  '1. This is a short list item.'",
      "     VISIBLE:  '1. This is a short list item.', cursor=1",
-     "SPEECH OUTPUT: '1. This is a short list item.'"]))
+     "SPEECH OUTPUT: '1. This is a short list item. '"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
@@ -69,7 +69,7 @@ sequence.append(utils.AssertPresentationAction(
     "8. Line Down",
     ["BRAILLE LINE:  '• This is a short list item.'",
      "     VISIBLE:  '• This is a short list item.', cursor=1",
-     "SPEECH OUTPUT: '• This is a short list item.'"]))
+     "SPEECH OUTPUT: '• This is a short list item. '"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
@@ -101,7 +101,7 @@ sequence.append(utils.AssertPresentationAction(
     "12. Line Up",
     ["BRAILLE LINE:  '• This is a short list item.'",
      "     VISIBLE:  '• This is a short list item.', cursor=1",
-     "SPEECH OUTPUT: '• This is a short list item.'"]))
+     "SPEECH OUTPUT: '• This is a short list item. '"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
@@ -141,7 +141,7 @@ sequence.append(utils.AssertPresentationAction(
     "17. Line Up",
     ["BRAILLE LINE:  '1. This is a short list item.'",
      "     VISIBLE:  '1. This is a short list item.', cursor=1",
-     "SPEECH OUTPUT: '1. This is a short list item.'"]))
+     "SPEECH OUTPUT: '1. This is a short list item. '"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
diff --git a/test/keystrokes/firefox/line_nav_bugzilla_search_down.py 
b/test/keystrokes/firefox/line_nav_bugzilla_search_down.py
index caaa1db..3b9e982 100644
--- a/test/keystrokes/firefox/line_nav_bugzilla_search_down.py
+++ b/test/keystrokes/firefox/line_nav_bugzilla_search_down.py
@@ -23,38 +23,29 @@ sequence.append(utils.AssertPresentationAction(
     "1. Line Down",
     ["BRAILLE LINE:  'New bug · Browse · Search · Reports · Account · Admin · Help Logged In joanmarie diggs 
gmail com | Log Out'",
      "     VISIBLE:  'New bug · Browse · Search · Repo', cursor=1",
-     "SPEECH OUTPUT: 'New bug'",
-     "SPEECH OUTPUT: 'link'",
+     "SPEECH OUTPUT: 'New bug link'",
      "SPEECH OUTPUT: '·'",
-     "SPEECH OUTPUT: 'Browse'",
-     "SPEECH OUTPUT: 'link'",
+     "SPEECH OUTPUT: 'Browse link'",
      "SPEECH OUTPUT: '·'",
-     "SPEECH OUTPUT: 'Search'",
-     "SPEECH OUTPUT: 'link'",
+     "SPEECH OUTPUT: 'Search link'",
      "SPEECH OUTPUT: '·'",
-     "SPEECH OUTPUT: 'Reports'",
-     "SPEECH OUTPUT: 'link'",
+     "SPEECH OUTPUT: 'Reports link'",
      "SPEECH OUTPUT: '·'",
-     "SPEECH OUTPUT: 'Account'",
-     "SPEECH OUTPUT: 'link'",
+     "SPEECH OUTPUT: 'Account link'",
      "SPEECH OUTPUT: '·'",
-     "SPEECH OUTPUT: 'Admin'",
-     "SPEECH OUTPUT: 'link'",
+     "SPEECH OUTPUT: 'Admin link'",
      "SPEECH OUTPUT: '·'",
-     "SPEECH OUTPUT: 'Help'",
-     "SPEECH OUTPUT: 'link'",
+     "SPEECH OUTPUT: 'Help link'",
      "SPEECH OUTPUT: 'Logged In joanmarie diggs gmail com |'",
-     "SPEECH OUTPUT: 'Log Out'",
-     "SPEECH OUTPUT: 'link'"]))
+     "SPEECH OUTPUT: 'Log Out link'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
 sequence.append(utils.AssertPresentationAction(
     "2. Line Down",
     ["BRAILLE LINE:  'Short Bug Search Form Complicated Bug Search Form'",
-     "     VISIBLE:  'Short Bug Search Form Complicate', cursor=0",
-     "SPEECH OUTPUT: 'Short Bug Search Form'",
-     "SPEECH OUTPUT: 'link'",
+     "     VISIBLE:  'Short Bug Search Form Complicate', cursor=1",
+     "SPEECH OUTPUT: 'Short Bug Search Form  link'",
      "SPEECH OUTPUT: 'Complicated Bug Search Form'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -63,8 +54,7 @@ sequence.append(utils.AssertPresentationAction(
     "3. Line Down",
     ["BRAILLE LINE:  'Give me some help (reloads page.)'",
      "     VISIBLE:  'Give me some help (reloads page.', cursor=1",
-     "SPEECH OUTPUT: 'Give me some help'",
-     "SPEECH OUTPUT: 'link'",
+     "SPEECH OUTPUT: 'Give me some help link'",
      "SPEECH OUTPUT: '(reloads page.)'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -73,7 +63,8 @@ sequence.append(utils.AssertPresentationAction(
     "4. Line Down",
     ["BRAILLE LINE:  'Summary: contains all of the words/strings combo box $l Search push button'",
      "     VISIBLE:  'Summary: contains all of the wor', cursor=1",
-     "SPEECH OUTPUT: 'Summary: contains all of the words/strings combo box'",
+     "SPEECH OUTPUT: 'Summary: row header'",
+     "SPEECH OUTPUT: 'contains all of the words/strings combo box'",
      "SPEECH OUTPUT: 'entry'",
      "SPEECH OUTPUT: 'Search push button'"]))
 
@@ -91,7 +82,7 @@ sequence.append(utils.AssertPresentationAction(
     "6. Line Down",
     ["BRAILLE LINE:  'Admin  list box'",
      "     VISIBLE:  'Admin  list box', cursor=1",
-     "SPEECH OUTPUT: 'Classification: Admin  multi-select List with 8 items'"]))
+     "SPEECH OUTPUT: 'Admin  multi-select List with 8 items'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
@@ -107,7 +98,7 @@ sequence.append(utils.AssertPresentationAction(
     "8. Line Down",
     ["BRAILLE LINE:  'accerciser list box'",
      "     VISIBLE:  'accerciser list box', cursor=1",
-     "SPEECH OUTPUT: 'Product: accerciser multi-select List with 379 items'"]))
+     "SPEECH OUTPUT: 'accerciser multi-select List with 379 items'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
@@ -115,9 +106,8 @@ sequence.append(utils.AssertPresentationAction(
     "9. Line Down",
     ["BRAILLE LINE:  'Component:'",
      "     VISIBLE:  'Component:', cursor=1",
-     "SPEECH OUTPUT: 'Component'",
-     "SPEECH OUTPUT: 'link'",
-     "SPEECH OUTPUT: 'Component : column header'"]))
+     "SPEECH OUTPUT: 'Component link'",
+     "SPEECH OUTPUT: ': column header'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
@@ -125,7 +115,7 @@ sequence.append(utils.AssertPresentationAction(
     "10. Line Down",
     ["BRAILLE LINE:  'abiscan list box'",
      "     VISIBLE:  'abiscan list box', cursor=1",
-     "SPEECH OUTPUT: 'Component: abiscan multi-select List with 1248 items'"]))
+     "SPEECH OUTPUT: 'abiscan multi-select List with 1248 items'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
@@ -141,7 +131,7 @@ sequence.append(utils.AssertPresentationAction(
     "12. Line Down",
     ["BRAILLE LINE:  '0.0.1 list box'",
      "     VISIBLE:  '0.0.1 list box', cursor=1",
-     "SPEECH OUTPUT: 'Version: 0.0.1 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"))
@@ -157,7 +147,7 @@ sequence.append(utils.AssertPresentationAction(
     "14. Line Down",
     ["BRAILLE LINE:  '--- list box'",
      "     VISIBLE:  '--- list box', cursor=1",
-     "SPEECH OUTPUT: 'Target Milestone: --- multi-select List with 555 items'"]))
+     "SPEECH OUTPUT: '--- multi-select List with 555 items'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
@@ -165,7 +155,8 @@ sequence.append(utils.AssertPresentationAction(
     "15. Line Down",
     ["BRAILLE LINE:  'A Comment: contains the string combo box $l'",
      "     VISIBLE:  'A Comment: contains the string c', cursor=1",
-     "SPEECH OUTPUT: 'A Comment: contains the string combo box'",
+     "SPEECH OUTPUT: 'A Comment: row header'",
+     "SPEECH OUTPUT: 'contains the string combo box'",
      "SPEECH OUTPUT: 'entry'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -174,7 +165,8 @@ sequence.append(utils.AssertPresentationAction(
     "16. Line Down",
     ["BRAILLE LINE:  'Whiteboard: contains all of the words/strings combo box $l'",
      "     VISIBLE:  'Whiteboard: contains all of the ', cursor=1",
-     "SPEECH OUTPUT: 'Whiteboard: contains all of the words/strings combo box'",
+     "SPEECH OUTPUT: 'Whiteboard: row header'",
+     "SPEECH OUTPUT: 'contains all of the words/strings combo box'",
      "SPEECH OUTPUT: 'entry'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -183,10 +175,9 @@ sequence.append(utils.AssertPresentationAction(
     "17. Line Down",
     ["BRAILLE LINE:  'Keywords: contains all of the keywords combo box $l'",
      "     VISIBLE:  'Keywords: contains all of the ke', cursor=1",
-     "SPEECH OUTPUT: 'Keywords'",
-     "SPEECH OUTPUT: 'link'",
-     "SPEECH OUTPUT: 'Keywords : row header'",
-     "SPEECH OUTPUT: 'Keywords: contains all of the keywords combo box'",
+     "SPEECH OUTPUT: 'Keywords link'",
+     "SPEECH OUTPUT: ': row header'",
+     "SPEECH OUTPUT: 'contains all of the keywords combo box'",
      "SPEECH OUTPUT: 'entry'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -212,7 +203,7 @@ sequence.append(utils.AssertPresentationAction(
     ["KNOWN ISSUE: Should we be doing a different presentation of these selected children?",
      "BRAILLE LINE:  'UNCONFIRMED NEW ASSIGNED REOPENED NEEDINFO list box'",
      "     VISIBLE:  'UNCONFIRMED NEW ASSIGNED REOPENE', cursor=1",
-     "SPEECH OUTPUT: 'Status: UNCONFIRMED NEW ASSIGNED REOPENED NEEDINFO multi-select List with 8 items'"]))
+     "SPEECH OUTPUT: 'UNCONFIRMED NEW ASSIGNED REOPENED NEEDINFO multi-select List with 8 items'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
@@ -220,7 +211,7 @@ sequence.append(utils.AssertPresentationAction(
     "21. Line Down",
     ["BRAILLE LINE:  'Resolution:'",
      "     VISIBLE:  'Resolution:', cursor=1",
-     "SPEECH OUTPUT: 'Resolution:  column header'"]))
+     "SPEECH OUTPUT: 'Resolution: column header'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
@@ -228,7 +219,7 @@ sequence.append(utils.AssertPresentationAction(
     "22. Line Down",
     ["BRAILLE LINE:  'FIXED list box'",
      "     VISIBLE:  'FIXED list box', cursor=1",
-     "SPEECH OUTPUT: 'Resolution: FIXED multi-select List with 12 items'"]))
+     "SPEECH OUTPUT: 'FIXED multi-select List with 12 items'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
@@ -244,7 +235,7 @@ sequence.append(utils.AssertPresentationAction(
     "24. Line Down",
     ["BRAILLE LINE:  'blocker list box'",
      "     VISIBLE:  'blocker list box', cursor=1",
-     "SPEECH OUTPUT: 'Severity: blocker multi-select List with 7 items'"]))
+     "SPEECH OUTPUT: 'blocker multi-select List with 7 items'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
@@ -260,7 +251,7 @@ sequence.append(utils.AssertPresentationAction(
     "26. Line Down",
     ["BRAILLE LINE:  'Immediate list box'",
      "     VISIBLE:  'Immediate list box', cursor=1",
-     "SPEECH OUTPUT: 'Priority: Immediate multi-select List with 5 items'"]))
+     "SPEECH OUTPUT: 'Immediate multi-select List with 5 items'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
@@ -276,7 +267,7 @@ sequence.append(utils.AssertPresentationAction(
     "28. Line Down",
     ["BRAILLE LINE:  'All list box'",
      "     VISIBLE:  'All list box', cursor=1",
-     "SPEECH OUTPUT: 'OS: All multi-select List with 21 items'"]))
+     "SPEECH OUTPUT: 'All multi-select List with 21 items'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
@@ -298,40 +289,40 @@ sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
 sequence.append(utils.AssertPresentationAction(
     "31. Line Down",
-    ["BRAILLE LINE:  '<x> check box the bug assignee'",
-     "     VISIBLE:  '<x> check box the bug assignee', cursor=1",
+    ["BRAILLE LINE:  '<x> the bug assignee check box'",
+     "     VISIBLE:  '<x> the bug assignee check box', cursor=1",
      "SPEECH OUTPUT: 'the bug assignee check box checked'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
 sequence.append(utils.AssertPresentationAction(
     "32. Line Down",
-    ["BRAILLE LINE:  '< > check box the reporter'",
-     "     VISIBLE:  '< > check box the reporter', cursor=1",
+    ["BRAILLE LINE:  '< > the reporter check box'",
+     "     VISIBLE:  '< > the reporter check box', cursor=1",
      "SPEECH OUTPUT: 'the reporter check box not checked'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
 sequence.append(utils.AssertPresentationAction(
     "33. Line Down",
-    ["BRAILLE LINE:  '< > check box the QA contact'",
-     "     VISIBLE:  '< > check box the QA contact', cursor=1",
+    ["BRAILLE LINE:  '< > the QA contact check box'",
+     "     VISIBLE:  '< > the QA contact check box', cursor=1",
      "SPEECH OUTPUT: 'the QA contact check box not checked'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
 sequence.append(utils.AssertPresentationAction(
     "34. Line Down",
-    ["BRAILLE LINE:  '< > check box a CC list member'",
-     "     VISIBLE:  '< > check box a CC list member', cursor=1",
+    ["BRAILLE LINE:  '< > a CC list member check box'",
+     "     VISIBLE:  '< > a CC list member check box', cursor=1",
      "SPEECH OUTPUT: 'a CC list member check box not checked'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
 sequence.append(utils.AssertPresentationAction(
     "35. Line Down",
-    ["BRAILLE LINE:  '< > check box a commenter'",
-     "     VISIBLE:  '< > check box a commenter', cursor=1",
+    ["BRAILLE LINE:  '< > a commenter check box'",
+     "     VISIBLE:  '< > a commenter check box', cursor=1",
      "SPEECH OUTPUT: 'a commenter check box not checked'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -362,40 +353,40 @@ sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
 sequence.append(utils.AssertPresentationAction(
     "39. Line Down",
-    ["BRAILLE LINE:  '<x> check box the bug assignee'",
-     "     VISIBLE:  '<x> check box the bug assignee', cursor=1",
+    ["BRAILLE LINE:  '<x> the bug assignee check box'",
+     "     VISIBLE:  '<x> the bug assignee check box', cursor=1",
      "SPEECH OUTPUT: 'the bug assignee check box checked'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
 sequence.append(utils.AssertPresentationAction(
     "40. Line Down",
-    ["BRAILLE LINE:  '<x> check box the reporter'",
-     "     VISIBLE:  '<x> check box the reporter', cursor=1",
+    ["BRAILLE LINE:  '<x> the reporter check box'",
+     "     VISIBLE:  '<x> the reporter check box', cursor=1",
      "SPEECH OUTPUT: 'the reporter check box checked'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
 sequence.append(utils.AssertPresentationAction(
     "41. Line Down",
-    ["BRAILLE LINE:  '<x> check box the QA contact'",
-     "     VISIBLE:  '<x> check box the QA contact', cursor=1",
+    ["BRAILLE LINE:  '<x> the QA contact check box'",
+     "     VISIBLE:  '<x> the QA contact check box', cursor=1",
      "SPEECH OUTPUT: 'the QA contact check box checked'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
 sequence.append(utils.AssertPresentationAction(
     "42. Line Down",
-    ["BRAILLE LINE:  '<x> check box a CC list member'",
-     "     VISIBLE:  '<x> check box a CC list member', cursor=1",
+    ["BRAILLE LINE:  '<x> a CC list member check box'",
+     "     VISIBLE:  '<x> a CC list member check box', cursor=1",
      "SPEECH OUTPUT: 'a CC list member check box checked'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
 sequence.append(utils.AssertPresentationAction(
     "43. Line Down",
-    ["BRAILLE LINE:  '< > check box a commenter'",
-     "     VISIBLE:  '< > check box a commenter', cursor=1",
+    ["BRAILLE LINE:  '< > a commenter check box'",
+     "     VISIBLE:  '< > a commenter check box', cursor=1",
      "SPEECH OUTPUT: 'a commenter check box not checked'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -430,14 +421,14 @@ sequence.append(utils.AssertPresentationAction(
      "     VISIBLE:  'Only include combo box bugs numb', cursor=1",
      "SPEECH OUTPUT: 'Only include combo box'",
      "SPEECH OUTPUT: 'bugs numbered:'",
-     "SPEECH OUTPUT: '(comma-separated list) entry'"]))
+     "SPEECH OUTPUT: 'entry'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
 sequence.append(utils.AssertPresentationAction(
     "48. Line Down",
     ["BRAILLE LINE:  '(comma-separated list)'",
-     "     VISIBLE:  '(comma-separated list)', cursor=0",
+     "     VISIBLE:  '(comma-separated list)', cursor=1",
      "SPEECH OUTPUT: '(comma-separated list)'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -462,8 +453,9 @@ sequence.append(utils.AssertPresentationAction(
     "51. Line Down",
     ["BRAILLE LINE:  ' $l and Now $l'",
      "     VISIBLE:  ' $l and Now $l', cursor=1",
-     "SPEECH OUTPUT: '(YYYY-MM-DD or relative dates) entry'",
-     "SPEECH OUTPUT: 'and entry Now'"]))
+     "SPEECH OUTPUT: 'entry'",
+     "SPEECH OUTPUT: 'and'",
+     "SPEECH OUTPUT: 'entry Now'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
@@ -519,7 +511,7 @@ sequence.append(utils.AssertPresentationAction(
     "58. Line Down",
     ["BRAILLE LINE:  'Unspecified list box'",
      "     VISIBLE:  'Unspecified list box', cursor=1",
-     "SPEECH OUTPUT: 'GNOME version: Unspecified multi-select List with 14 items'"]))
+     "SPEECH OUTPUT: 'Unspecified multi-select List with 14 items'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
@@ -535,7 +527,7 @@ sequence.append(utils.AssertPresentationAction(
     "60. Line Down",
     ["BRAILLE LINE:  'Unspecified list box'",
      "     VISIBLE:  'Unspecified list box', cursor=1",
-     "SPEECH OUTPUT: 'GNOME target: Unspecified multi-select List with 12 items'"]))
+     "SPEECH OUTPUT: 'Unspecified multi-select List with 12 items'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
@@ -543,7 +535,8 @@ sequence.append(utils.AssertPresentationAction(
     "61. Line Down",
     ["BRAILLE LINE:  'Sort results by: Reuse same sort as last time combo box'",
      "     VISIBLE:  'Sort results by: Reuse same sort', cursor=1",
-     "SPEECH OUTPUT: 'Sort results by: Reuse same sort as last time combo box'"]))
+     "SPEECH OUTPUT: 'Sort results by:'",
+     "SPEECH OUTPUT: 'Reuse same sort as last time combo box'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
@@ -557,8 +550,8 @@ sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
 sequence.append(utils.AssertPresentationAction(
     "63. Line Down",
-    ["BRAILLE LINE:  '< > check box and remember these as my default search options'",
-     "     VISIBLE:  '< > check box and remember these', cursor=0",
+    ["BRAILLE LINE:  '< > and remember these as my default search options check box'",
+     "     VISIBLE:  '< > and remember these as my def', cursor=0",
      "SPEECH OUTPUT: 'and remember these as my default search options check box not checked'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -581,8 +574,8 @@ sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
 sequence.append(utils.AssertPresentationAction(
     "66. Line Down",
-    ["BRAILLE LINE:  '< > check box Not (negate this whole chart)'",
-     "     VISIBLE:  '< > check box Not \(negate this w', cursor=1",
+    ["BRAILLE LINE:  '< > Not (negate this whole chart) check box'",
+     "     VISIBLE:  '< > Not \(negate this whole chart', cursor=1",
      "SPEECH OUTPUT: 'Not (negate this whole chart) check box not checked'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -620,20 +613,15 @@ sequence.append(utils.AssertPresentationAction(
     ["BRAILLE LINE:  'Saved Searches: My Bugs and Patches | All Orca | Firefox | open orca | Open RFEs'",
      "     VISIBLE:  'Saved Searches: My Bugs and Patc', cursor=1",
      "SPEECH OUTPUT: 'Saved Searches:'",
-     "SPEECH OUTPUT: 'My Bugs and Patches'",
-     "SPEECH OUTPUT: 'link'",
+     "SPEECH OUTPUT: 'My Bugs and Patches link'",
      "SPEECH OUTPUT: '|'",
-     "SPEECH OUTPUT: 'All Orca'",
-     "SPEECH OUTPUT: 'link'",
+     "SPEECH OUTPUT: 'All Orca link'",
      "SPEECH OUTPUT: '|'",
-     "SPEECH OUTPUT: 'Firefox'",
-     "SPEECH OUTPUT: 'link'",
+     "SPEECH OUTPUT: 'Firefox link'",
      "SPEECH OUTPUT: '|'",
-     "SPEECH OUTPUT: 'open orca'",
-     "SPEECH OUTPUT: 'link'",
+     "SPEECH OUTPUT: 'open orca link'",
      "SPEECH OUTPUT: '|'",
-     "SPEECH OUTPUT: 'Open RFEs'",
-     "SPEECH OUTPUT: 'link'"]))
+     "SPEECH OUTPUT: 'Open RFEs link'"]))
 
 sequence.append(utils.AssertionSummaryAction())
 sequence.start()
diff --git a/test/keystrokes/firefox/line_nav_bugzilla_search_up.py 
b/test/keystrokes/firefox/line_nav_bugzilla_search_up.py
index c43731f..4f240fa 100644
--- a/test/keystrokes/firefox/line_nav_bugzilla_search_up.py
+++ b/test/keystrokes/firefox/line_nav_bugzilla_search_up.py
@@ -16,6 +16,7 @@ sequence.append(KeyPressAction(0, None, "KP_Insert"))
 sequence.append(KeyComboAction("a"))
 sequence.append(KeyReleaseAction(0, None, "KP_Insert"))
 sequence.append(KeyComboAction("<Control>End"))
+sequence.append(KeyComboAction("Up"))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
@@ -49,8 +50,8 @@ sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
 sequence.append(utils.AssertPresentationAction(
     "4. Line Up",
-    ["BRAILLE LINE:  '< > check box Not (negate this whole chart)'",
-     "     VISIBLE:  '< > check box Not \(negate this w', cursor=1",
+    ["BRAILLE LINE:  '< > Not (negate this whole chart) check box'",
+     "     VISIBLE:  '< > Not \(negate this whole chart', cursor=1",
      "SPEECH OUTPUT: 'Not (negate this whole chart) check box not checked'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -73,8 +74,8 @@ sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
 sequence.append(utils.AssertPresentationAction(
     "7. Line Up",
-    ["BRAILLE LINE:  '< > check box and remember these as my default search options'",
-     "     VISIBLE:  '< > check box and remember these', cursor=0",
+    ["BRAILLE LINE:  '< > and remember these as my default search options check box'",
+     "     VISIBLE:  '< > and remember these as my def', cursor=0",
      "SPEECH OUTPUT: 'and remember these as my default search options check box not checked'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -91,7 +92,8 @@ sequence.append(utils.AssertPresentationAction(
     "9. Line Up",
     ["BRAILLE LINE:  'Sort results by: Reuse same sort as last time combo box'",
      "     VISIBLE:  'Sort results by: Reuse same sort', cursor=1",
-     "SPEECH OUTPUT: 'Sort results by: Reuse same sort as last time combo box'"]))
+     "SPEECH OUTPUT: 'Sort results by:'",
+     "SPEECH OUTPUT: 'Reuse same sort as last time combo box'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
@@ -99,7 +101,7 @@ sequence.append(utils.AssertPresentationAction(
     "10. Line Up",
     ["BRAILLE LINE:  'Unspecified list box'",
      "     VISIBLE:  'Unspecified list box', cursor=1",
-     "SPEECH OUTPUT: 'GNOME target: Unspecified multi-select List with 12 items'"]))
+     "SPEECH OUTPUT: 'Unspecified multi-select List with 12 items'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
@@ -115,7 +117,7 @@ sequence.append(utils.AssertPresentationAction(
     "12. Line Up",
     ["BRAILLE LINE:  'Unspecified list box'",
      "     VISIBLE:  'Unspecified list box', cursor=1",
-     "SPEECH OUTPUT: 'GNOME version: Unspecified multi-select List with 14 items'"]))
+     "SPEECH OUTPUT: 'Unspecified multi-select List with 14 items'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
@@ -171,8 +173,9 @@ sequence.append(utils.AssertPresentationAction(
     "19. Line Up",
     ["BRAILLE LINE:  ' $l and Now $l'",
      "     VISIBLE:  ' $l and Now $l', cursor=1",
-     "SPEECH OUTPUT: '(YYYY-MM-DD or relative dates) entry'",
-     "SPEECH OUTPUT: 'and entry Now'"]))
+     "SPEECH OUTPUT: 'entry'",
+     "SPEECH OUTPUT: 'and'",
+     "SPEECH OUTPUT: 'entry Now'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
@@ -195,7 +198,7 @@ sequence.append(KeyComboAction("Up"))
 sequence.append(utils.AssertPresentationAction(
     "22. Line Up",
     ["BRAILLE LINE:  '(comma-separated list)'",
-     "     VISIBLE:  '(comma-separated list)', cursor=0",
+     "     VISIBLE:  '(comma-separated list)', cursor=1",
      "SPEECH OUTPUT: '(comma-separated list)'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -206,7 +209,7 @@ sequence.append(utils.AssertPresentationAction(
      "     VISIBLE:  'Only include combo box bugs numb', cursor=1",
      "SPEECH OUTPUT: 'Only include combo box'",
      "SPEECH OUTPUT: 'bugs numbered:'",
-     "SPEECH OUTPUT: '(comma-separated list) entry'"]))
+     "SPEECH OUTPUT: 'entry'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
@@ -236,40 +239,40 @@ sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
 sequence.append(utils.AssertPresentationAction(
     "27. Line Up",
-    ["BRAILLE LINE:  '< > check box a commenter'",
-     "     VISIBLE:  '< > check box a commenter', cursor=1",
+    ["BRAILLE LINE:  '< > a commenter check box'",
+     "     VISIBLE:  '< > a commenter check box', cursor=1",
      "SPEECH OUTPUT: 'a commenter check box not checked'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
 sequence.append(utils.AssertPresentationAction(
     "28. Line Up",
-    ["BRAILLE LINE:  '<x> check box a CC list member'",
-     "     VISIBLE:  '<x> check box a CC list member', cursor=1",
+    ["BRAILLE LINE:  '<x> a CC list member check box'",
+     "     VISIBLE:  '<x> a CC list member check box', cursor=1",
      "SPEECH OUTPUT: 'a CC list member check box checked'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
 sequence.append(utils.AssertPresentationAction(
     "29. Line Up",
-    ["BRAILLE LINE:  '<x> check box the QA contact'",
-     "     VISIBLE:  '<x> check box the QA contact', cursor=1",
+    ["BRAILLE LINE:  '<x> the QA contact check box'",
+     "     VISIBLE:  '<x> the QA contact check box', cursor=1",
      "SPEECH OUTPUT: 'the QA contact check box checked'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
 sequence.append(utils.AssertPresentationAction(
     "30. Line Up",
-    ["BRAILLE LINE:  '<x> check box the reporter'",
-     "     VISIBLE:  '<x> check box the reporter', cursor=1",
+    ["BRAILLE LINE:  '<x> the reporter check box'",
+     "     VISIBLE:  '<x> the reporter check box', cursor=1",
      "SPEECH OUTPUT: 'the reporter check box checked'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
 sequence.append(utils.AssertPresentationAction(
     "31. Line Up",
-    ["BRAILLE LINE:  '<x> check box the bug assignee'",
-     "     VISIBLE:  '<x> check box the bug assignee', cursor=1",
+    ["BRAILLE LINE:  '<x> the bug assignee check box'",
+     "     VISIBLE:  '<x> the bug assignee check box', cursor=1",
      "SPEECH OUTPUT: 'the bug assignee check box checked'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -300,40 +303,40 @@ sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
 sequence.append(utils.AssertPresentationAction(
     "35. Line Up",
-    ["BRAILLE LINE:  '< > check box a commenter'",
-     "     VISIBLE:  '< > check box a commenter', cursor=1",
+    ["BRAILLE LINE:  '< > a commenter check box'",
+     "     VISIBLE:  '< > a commenter check box', cursor=1",
      "SPEECH OUTPUT: 'a commenter check box not checked'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
 sequence.append(utils.AssertPresentationAction(
     "36. Line Up",
-    ["BRAILLE LINE:  '< > check box a CC list member'",
-     "     VISIBLE:  '< > check box a CC list member', cursor=1",
+    ["BRAILLE LINE:  '< > a CC list member check box'",
+     "     VISIBLE:  '< > a CC list member check box', cursor=1",
      "SPEECH OUTPUT: 'a CC list member check box not checked'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
 sequence.append(utils.AssertPresentationAction(
     "37. Line Up",
-    ["BRAILLE LINE:  '< > check box the QA contact'",
-     "     VISIBLE:  '< > check box the QA contact', cursor=1",
+    ["BRAILLE LINE:  '< > the QA contact check box'",
+     "     VISIBLE:  '< > the QA contact check box', cursor=1",
      "SPEECH OUTPUT: 'the QA contact check box not checked'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
 sequence.append(utils.AssertPresentationAction(
     "38. Line Up",
-    ["BRAILLE LINE:  '< > check box the reporter'",
-     "     VISIBLE:  '< > check box the reporter', cursor=1",
+    ["BRAILLE LINE:  '< > the reporter check box'",
+     "     VISIBLE:  '< > the reporter check box', cursor=1",
      "SPEECH OUTPUT: 'the reporter check box not checked'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
 sequence.append(utils.AssertPresentationAction(
     "39. Line Up",
-    ["BRAILLE LINE:  '<x> check box the bug assignee'",
-     "     VISIBLE:  '<x> check box the bug assignee', cursor=1",
+    ["BRAILLE LINE:  '<x> the bug assignee check box'",
+     "     VISIBLE:  '<x> the bug assignee check box', cursor=1",
      "SPEECH OUTPUT: 'the bug assignee check box checked'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -358,7 +361,7 @@ sequence.append(utils.AssertPresentationAction(
     "42. Line Up",
     ["BRAILLE LINE:  'All list box'",
      "     VISIBLE:  'All list box', cursor=1",
-     "SPEECH OUTPUT: 'OS: All multi-select List with 21 items'"]))
+     "SPEECH OUTPUT: 'All multi-select List with 21 items'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
@@ -374,7 +377,7 @@ sequence.append(utils.AssertPresentationAction(
     "44. Line Up",
     ["BRAILLE LINE:  'Immediate list box'",
      "     VISIBLE:  'Immediate list box', cursor=1",
-     "SPEECH OUTPUT: 'Priority: Immediate multi-select List with 5 items'"]))
+     "SPEECH OUTPUT: 'Immediate multi-select List with 5 items'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
@@ -390,7 +393,7 @@ sequence.append(utils.AssertPresentationAction(
     "46. Line Up",
     ["BRAILLE LINE:  'blocker list box'",
      "     VISIBLE:  'blocker list box', cursor=1",
-     "SPEECH OUTPUT: 'Severity: blocker multi-select List with 7 items'"]))
+     "SPEECH OUTPUT: 'blocker multi-select List with 7 items'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
@@ -406,7 +409,7 @@ sequence.append(utils.AssertPresentationAction(
     "48. Line Up",
     ["BRAILLE LINE:  'FIXED list box'",
      "     VISIBLE:  'FIXED list box', cursor=1",
-     "SPEECH OUTPUT: 'Resolution: FIXED multi-select List with 12 items'"]))
+     "SPEECH OUTPUT: 'FIXED multi-select List with 12 items'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
@@ -414,7 +417,7 @@ sequence.append(utils.AssertPresentationAction(
     "49. Line Up",
     ["BRAILLE LINE:  'Resolution:'",
      "     VISIBLE:  'Resolution:', cursor=1",
-     "SPEECH OUTPUT: 'Resolution:  column header'"]))
+     "SPEECH OUTPUT: 'Resolution: column header'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
@@ -422,7 +425,7 @@ sequence.append(utils.AssertPresentationAction(
     "50. Line Up",
     ["BRAILLE LINE:  'UNCONFIRMED NEW ASSIGNED REOPENED NEEDINFO list box'",
      "     VISIBLE:  'UNCONFIRMED NEW ASSIGNED REOPENE', cursor=1",
-     "SPEECH OUTPUT: 'Status: UNCONFIRMED NEW ASSIGNED REOPENED NEEDINFO multi-select List with 8 items'"]))
+     "SPEECH OUTPUT: 'UNCONFIRMED NEW ASSIGNED REOPENED NEEDINFO multi-select List with 8 items'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
@@ -446,10 +449,9 @@ sequence.append(utils.AssertPresentationAction(
     "53. Line Up",
     ["BRAILLE LINE:  'Keywords: contains all of the keywords combo box $l'",
      "     VISIBLE:  'Keywords: contains all of the ke', cursor=1",
-     "SPEECH OUTPUT: 'Keywords'",
-     "SPEECH OUTPUT: 'link'",
-     "SPEECH OUTPUT: 'Keywords : row header'",
-     "SPEECH OUTPUT: 'Keywords: contains all of the keywords combo box'",
+     "SPEECH OUTPUT: 'Keywords link'",
+     "SPEECH OUTPUT: ': row header'",
+     "SPEECH OUTPUT: 'contains all of the keywords combo box'",
      "SPEECH OUTPUT: 'entry'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -458,7 +460,8 @@ sequence.append(utils.AssertPresentationAction(
     "54. Line Up",
     ["BRAILLE LINE:  'Whiteboard: contains all of the words/strings combo box $l'",
      "     VISIBLE:  'Whiteboard: contains all of the ', cursor=1",
-     "SPEECH OUTPUT: 'Whiteboard: contains all of the words/strings combo box'",
+     "SPEECH OUTPUT: 'Whiteboard: row header'",
+     "SPEECH OUTPUT: 'contains all of the words/strings combo box'",
      "SPEECH OUTPUT: 'entry'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -467,7 +470,8 @@ sequence.append(utils.AssertPresentationAction(
     "55. Line Up",
     ["BRAILLE LINE:  'A Comment: contains the string combo box $l'",
      "     VISIBLE:  'A Comment: contains the string c', cursor=1",
-     "SPEECH OUTPUT: 'A Comment: contains the string combo box'",
+     "SPEECH OUTPUT: 'A Comment: row header'",
+     "SPEECH OUTPUT: 'contains the string combo box'",
      "SPEECH OUTPUT: 'entry'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -476,7 +480,7 @@ sequence.append(utils.AssertPresentationAction(
     "56. Line Up",
     ["BRAILLE LINE:  '--- list box'",
      "     VISIBLE:  '--- list box', cursor=1",
-     "SPEECH OUTPUT: 'Target Milestone: --- multi-select List with 555 items'"]))
+     "SPEECH OUTPUT: '--- multi-select List with 555 items'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
@@ -492,7 +496,7 @@ sequence.append(utils.AssertPresentationAction(
     "58. Line Up",
     ["BRAILLE LINE:  '0.0.1 list box'",
      "     VISIBLE:  '0.0.1 list box', cursor=1",
-     "SPEECH OUTPUT: 'Version: 0.0.1 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"))
@@ -508,7 +512,7 @@ sequence.append(utils.AssertPresentationAction(
     "60. Line Up",
     ["BRAILLE LINE:  'abiscan list box'",
      "     VISIBLE:  'abiscan list box', cursor=1",
-     "SPEECH OUTPUT: 'Component: abiscan multi-select List with 1248 items'"]))
+     "SPEECH OUTPUT: 'abiscan multi-select List with 1248 items'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
@@ -516,9 +520,8 @@ sequence.append(utils.AssertPresentationAction(
     "61. Line Up",
     ["BRAILLE LINE:  'Component:'",
      "     VISIBLE:  'Component:', cursor=1",
-     "SPEECH OUTPUT: 'Component'",
-     "SPEECH OUTPUT: 'link'",
-     "SPEECH OUTPUT: 'Component : column header'"]))
+     "SPEECH OUTPUT: 'Component link'",
+     "SPEECH OUTPUT: ': column header'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
@@ -526,7 +529,7 @@ sequence.append(utils.AssertPresentationAction(
     "62. Line Up",
     ["BRAILLE LINE:  'accerciser list box'",
      "     VISIBLE:  'accerciser list box', cursor=1",
-     "SPEECH OUTPUT: 'Product: accerciser multi-select List with 379 items'"]))
+     "SPEECH OUTPUT: 'accerciser multi-select List with 379 items'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
@@ -542,7 +545,7 @@ sequence.append(utils.AssertPresentationAction(
     "64. Line Up",
     ["BRAILLE LINE:  'Admin  list box'",
      "     VISIBLE:  'Admin  list box', cursor=1",
-     "SPEECH OUTPUT: 'Classification: Admin  multi-select List with 8 items'"]))
+     "SPEECH OUTPUT: 'Admin  multi-select List with 8 items'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
@@ -558,7 +561,8 @@ sequence.append(utils.AssertPresentationAction(
     "66. Line Up",
     ["BRAILLE LINE:  'Summary: contains all of the words/strings combo box $l Search push button'",
      "     VISIBLE:  'Summary: contains all of the wor', cursor=1",
-     "SPEECH OUTPUT: 'Summary: contains all of the words/strings combo box'",
+     "SPEECH OUTPUT: 'Summary: row header'",
+     "SPEECH OUTPUT: 'contains all of the words/strings combo box'",
      "SPEECH OUTPUT: 'entry'",
      "SPEECH OUTPUT: 'Search push button'"]))
 
@@ -568,8 +572,7 @@ sequence.append(utils.AssertPresentationAction(
     "67. Line Up",
     ["BRAILLE LINE:  'Give me some help (reloads page.)'",
      "     VISIBLE:  'Give me some help (reloads page.', cursor=1",
-     "SPEECH OUTPUT: 'Give me some help'",
-     "SPEECH OUTPUT: 'link'",
+     "SPEECH OUTPUT: 'Give me some help link'",
      "SPEECH OUTPUT: '(reloads page.)'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -578,8 +581,7 @@ sequence.append(utils.AssertPresentationAction(
     "68. Line Up",
     ["BRAILLE LINE:  'Short Bug Search Form Complicated Bug Search Form'",
      "     VISIBLE:  'Short Bug Search Form Complicate', cursor=1",
-     "SPEECH OUTPUT: 'Short Bug Search Form'",
-     "SPEECH OUTPUT: 'link'",
+     "SPEECH OUTPUT: 'Short Bug Search Form  link'",
      "SPEECH OUTPUT: 'Complicated Bug Search Form'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -588,29 +590,21 @@ sequence.append(utils.AssertPresentationAction(
     "69. Line Up",
     ["BRAILLE LINE:  'New bug · Browse · Search · Reports · Account · Admin · Help Logged In joanmarie diggs 
gmail com | Log Out'",
      "     VISIBLE:  'New bug · Browse · Search · Repo', cursor=1",
-     "SPEECH OUTPUT: 'New bug'",
-     "SPEECH OUTPUT: 'link'",
+     "SPEECH OUTPUT: 'New bug link'",
      "SPEECH OUTPUT: '·'",
-     "SPEECH OUTPUT: 'Browse'",
-     "SPEECH OUTPUT: 'link'",
+     "SPEECH OUTPUT: 'Browse link'",
      "SPEECH OUTPUT: '·'",
-     "SPEECH OUTPUT: 'Search'",
-     "SPEECH OUTPUT: 'link'",
+     "SPEECH OUTPUT: 'Search link'",
      "SPEECH OUTPUT: '·'",
-     "SPEECH OUTPUT: 'Reports'",
-     "SPEECH OUTPUT: 'link'",
+     "SPEECH OUTPUT: 'Reports link'",
      "SPEECH OUTPUT: '·'",
-     "SPEECH OUTPUT: 'Account'",
-     "SPEECH OUTPUT: 'link'",
+     "SPEECH OUTPUT: 'Account link'",
      "SPEECH OUTPUT: '·'",
-     "SPEECH OUTPUT: 'Admin'",
-     "SPEECH OUTPUT: 'link'",
+     "SPEECH OUTPUT: 'Admin link'",
      "SPEECH OUTPUT: '·'",
-     "SPEECH OUTPUT: 'Help'",
-     "SPEECH OUTPUT: 'link'",
+     "SPEECH OUTPUT: 'Help link'",
      "SPEECH OUTPUT: 'Logged In joanmarie diggs gmail com |'",
-     "SPEECH OUTPUT: 'Log Out'",
-     "SPEECH OUTPUT: 'link'"]))
+     "SPEECH OUTPUT: 'Log Out link'"]))
 
 sequence.append(utils.AssertionSummaryAction())
 sequence.start()
diff --git a/test/keystrokes/firefox/line_nav_button_in_link_position_relative_on_focus.py 
b/test/keystrokes/firefox/line_nav_button_in_link_position_relative_on_focus.py
index afbc663..da184da 100644
--- a/test/keystrokes/firefox/line_nav_button_in_link_position_relative_on_focus.py
+++ b/test/keystrokes/firefox/line_nav_button_in_link_position_relative_on_focus.py
@@ -13,7 +13,7 @@ sequence.append(KeyComboAction("<Control>Home"))
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
 sequence.append(utils.AssertPresentationAction(
-    "1. Top of file",
+    "1. Line Down",
     ["BRAILLE LINE:  'Line 1'",
      "     VISIBLE:  'Line 1', cursor=1",
      "SPEECH OUTPUT: 'Line 1'"]))
@@ -22,9 +22,9 @@ sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
 sequence.append(utils.AssertPresentationAction(
     "2. Line Down",
-    ["BRAILLE LINE:  '  Line 2  '",
-     "     VISIBLE:  '  Line 2  ', cursor=1",
-     "SPEECH OUTPUT: 'Line 2'"]))
+    ["BRAILLE LINE:  '  Line 2   push button'",
+     "     VISIBLE:  '  Line 2   push button', cursor=1",
+     "SPEECH OUTPUT: '  Line 2   push button'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
@@ -38,9 +38,9 @@ sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
 sequence.append(utils.AssertPresentationAction(
     "4. Line Up",
-    ["BRAILLE LINE:  '  Line 2  '",
-     "     VISIBLE:  '  Line 2  ', cursor=1",
-     "SPEECH OUTPUT: 'Line 2'"]))
+    ["BRAILLE LINE:  '  Line 2   push button'",
+     "     VISIBLE:  '  Line 2   push button', cursor=1",
+     "SPEECH OUTPUT: '  Line 2   push button'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
diff --git a/test/keystrokes/firefox/line_nav_descriptions.py 
b/test/keystrokes/firefox/line_nav_descriptions.py
index fee615f..d7e2f59 100644
--- a/test/keystrokes/firefox/line_nav_descriptions.py
+++ b/test/keystrokes/firefox/line_nav_descriptions.py
@@ -18,14 +18,11 @@ sequence.append(utils.AssertPresentationAction(
     "1. Line Down",
     ["BRAILLE LINE:  'Foo, Bar, and Baz.'",
      "     VISIBLE:  'Foo, Bar, and Baz.', cursor=1",
-     "SPEECH OUTPUT: 'Foo'",
-     "SPEECH OUTPUT: 'link Title of the Foo link.'",
+     "SPEECH OUTPUT: 'Foo link Title of the Foo link.'",
      "SPEECH OUTPUT: ','",
-     "SPEECH OUTPUT: 'Bar'",
-     "SPEECH OUTPUT: 'link'",
+     "SPEECH OUTPUT: 'Bar link'",
      "SPEECH OUTPUT: ', and'",
-     "SPEECH OUTPUT: 'Baz'",
-     "SPEECH OUTPUT: 'link'",
+     "SPEECH OUTPUT: 'Baz link'",
      "SPEECH OUTPUT: '.'"]))
 
 sequence.append(KeyComboAction("Down"))
diff --git a/test/keystrokes/firefox/line_nav_empty_anchor.py 
b/test/keystrokes/firefox/line_nav_empty_anchor.py
index 93035e3..ecf5d84 100644
--- a/test/keystrokes/firefox/line_nav_empty_anchor.py
+++ b/test/keystrokes/firefox/line_nav_empty_anchor.py
@@ -34,8 +34,7 @@ sequence.append(utils.AssertPresentationAction(
     "3. Line Down",
     ["BRAILLE LINE:  'Q. What's a battery?'",
      "     VISIBLE:  'Q. What's a battery?', cursor=1",
-     "SPEECH OUTPUT: 'Q. What's a battery?'",
-     "SPEECH OUTPUT: 'link'"]))
+     "SPEECH OUTPUT: 'Q. What's a battery? link'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
@@ -43,8 +42,7 @@ sequence.append(utils.AssertPresentationAction(
     "4. Line Down",
     ["BRAILLE LINE:  'Q. Which way is up?'",
      "     VISIBLE:  'Q. Which way is up?', cursor=1",
-     "SPEECH OUTPUT: 'Q. Which way is up?'",
-     "SPEECH OUTPUT: 'link'"]))
+     "SPEECH OUTPUT: 'Q. Which way is up? link'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
@@ -52,8 +50,7 @@ sequence.append(utils.AssertPresentationAction(
     "5. Line Down",
     ["BRAILLE LINE:  'Q. Why did Orca used to get stuck on this page?'",
      "     VISIBLE:  'Q. Why did Orca used to get stuc', cursor=1",
-     "SPEECH OUTPUT: 'Q. Why did Orca used to get stuck on this page?'",
-     "SPEECH OUTPUT: 'link'"]))
+     "SPEECH OUTPUT: 'Q. Why did Orca used to get stuck on this page? link'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
@@ -70,8 +67,7 @@ sequence.append(utils.AssertPresentationAction(
     "7. Line Down",
     ["BRAILLE LINE:  'Q. Why would someone put a line break in a heading?'",
      "     VISIBLE:  'Q. Why would someone put a line ', cursor=1",
-     "SPEECH OUTPUT: 'Q. Why would someone put a line break in a heading?'",
-     "SPEECH OUTPUT: 'link'"]))
+     "SPEECH OUTPUT: 'Q. Why would someone put a line break in a heading? link'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
@@ -79,8 +75,7 @@ sequence.append(utils.AssertPresentationAction(
     "8. Line Down",
     ["BRAILLE LINE:  'Q. What is the airspeed velocity of an unladen swallow?'",
      "     VISIBLE:  'Q. What is the airspeed velocity', cursor=1",
-     "SPEECH OUTPUT: 'Q. What is the airspeed velocity of an unladen swallow?'",
-     "SPEECH OUTPUT: 'link'"]))
+     "SPEECH OUTPUT: 'Q. What is the airspeed velocity of an unladen swallow? link'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
@@ -192,8 +187,7 @@ sequence.append(utils.AssertPresentationAction(
     "22. Line Up",
     ["BRAILLE LINE:  'Q. What is the airspeed velocity of an unladen swallow?'",
      "     VISIBLE:  'Q. What is the airspeed velocity', cursor=1",
-     "SPEECH OUTPUT: 'Q. What is the airspeed velocity of an unladen swallow?'",
-     "SPEECH OUTPUT: 'link'"]))
+     "SPEECH OUTPUT: 'Q. What is the airspeed velocity of an unladen swallow? link'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
@@ -201,8 +195,7 @@ sequence.append(utils.AssertPresentationAction(
     "23. Line Up",
     ["BRAILLE LINE:  'Q. Why would someone put a line break in a heading?'",
      "     VISIBLE:  'Q. Why would someone put a line ', cursor=1",
-     "SPEECH OUTPUT: 'Q. Why would someone put a line break in a heading?'",
-     "SPEECH OUTPUT: 'link'"]))
+     "SPEECH OUTPUT: 'Q. Why would someone put a line break in a heading? link'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
@@ -219,8 +212,7 @@ sequence.append(utils.AssertPresentationAction(
     "25. Line Up",
     ["BRAILLE LINE:  'Q. Why did Orca used to get stuck on this page?'",
      "     VISIBLE:  'Q. Why did Orca used to get stuc', cursor=1",
-     "SPEECH OUTPUT: 'Q. Why did Orca used to get stuck on this page?'",
-     "SPEECH OUTPUT: 'link'"]))
+     "SPEECH OUTPUT: 'Q. Why did Orca used to get stuck on this page? link'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
@@ -228,8 +220,7 @@ sequence.append(utils.AssertPresentationAction(
     "26. Line Up",
     ["BRAILLE LINE:  'Q. Which way is up?'",
      "     VISIBLE:  'Q. Which way is up?', cursor=1",
-     "SPEECH OUTPUT: 'Q. Which way is up?'",
-     "SPEECH OUTPUT: 'link'"]))
+     "SPEECH OUTPUT: 'Q. Which way is up? link'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
@@ -237,8 +228,7 @@ sequence.append(utils.AssertPresentationAction(
     "27. Line Up",
     ["BRAILLE LINE:  'Q. What's a battery?'",
      "     VISIBLE:  'Q. What's a battery?', cursor=1",
-     "SPEECH OUTPUT: 'Q. What's a battery?'",
-     "SPEECH OUTPUT: 'link'"]))
+     "SPEECH OUTPUT: 'Q. What's a battery? link'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
diff --git a/test/keystrokes/firefox/line_nav_enter_bug.py b/test/keystrokes/firefox/line_nav_enter_bug.py
index b012ad1..56a9c21 100644
--- a/test/keystrokes/firefox/line_nav_enter_bug.py
+++ b/test/keystrokes/firefox/line_nav_enter_bug.py
@@ -24,29 +24,21 @@ sequence.append(utils.AssertPresentationAction(
     "2. Line Down",
     ["BRAILLE LINE:  'New bug · Browse · Search · Reports · Account · Admin · Help Logged In joanmarie diggs 
gmail com | Log Out'",
      "     VISIBLE:  'New bug · Browse · Search · Repo', cursor=1",
-     "SPEECH OUTPUT: 'New bug'",
-     "SPEECH OUTPUT: 'link'",
+     "SPEECH OUTPUT: 'New bug link'",
      "SPEECH OUTPUT: '·'",
-     "SPEECH OUTPUT: 'Browse'",
-     "SPEECH OUTPUT: 'link'",
+     "SPEECH OUTPUT: 'Browse link'",
      "SPEECH OUTPUT: '·'",
-     "SPEECH OUTPUT: 'Search'",
-     "SPEECH OUTPUT: 'link'",
+     "SPEECH OUTPUT: 'Search link'",
      "SPEECH OUTPUT: '·'",
-     "SPEECH OUTPUT: 'Reports'",
-     "SPEECH OUTPUT: 'link'",
+     "SPEECH OUTPUT: 'Reports link'",
      "SPEECH OUTPUT: '·'",
-     "SPEECH OUTPUT: 'Account'",
-     "SPEECH OUTPUT: 'link'",
+     "SPEECH OUTPUT: 'Account link'",
      "SPEECH OUTPUT: '·'",
-     "SPEECH OUTPUT: 'Admin'",
-     "SPEECH OUTPUT: 'link'",
+     "SPEECH OUTPUT: 'Admin link'",
      "SPEECH OUTPUT: '·'",
-     "SPEECH OUTPUT: 'Help'",
-     "SPEECH OUTPUT: 'link'",
+     "SPEECH OUTPUT: 'Help link'",
      "SPEECH OUTPUT: 'Logged In joanmarie diggs gmail com |'",
-     "SPEECH OUTPUT: 'Log Out'",
-     "SPEECH OUTPUT: 'link'"]))
+     "SPEECH OUTPUT: 'Log Out link'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
@@ -68,65 +60,37 @@ sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
 sequence.append(utils.AssertPresentationAction(
     "5. Line Down",
-    ["BRAILLE LINE:  ''",
-     "     VISIBLE:  '', cursor=1",
-     "SPEECH OUTPUT: 'blank'"]))
-
-sequence.append(utils.StartRecordingAction())
-sequence.append(KeyComboAction("Down"))
-sequence.append(utils.AssertPresentationAction(
-    "6. Line Down",
-    ["BRAILLE LINE:  ''",
-     "     VISIBLE:  '', cursor=1",
-     "SPEECH OUTPUT: 'blank'"]))
-
-sequence.append(utils.StartRecordingAction())
-sequence.append(KeyComboAction("Down"))
-sequence.append(utils.AssertPresentationAction(
-    "7. Line Down",
     ["BRAILLE LINE:  'Before reporting a bug, please read the bug writing guidelines,'",
      "     VISIBLE:  'Before reporting a bug, please r', cursor=1",
      "SPEECH OUTPUT: 'Before reporting a bug, please read the'",
-     "SPEECH OUTPUT: 'bug writing guidelines'",
-     "SPEECH OUTPUT: 'link'",
+     "SPEECH OUTPUT: 'bug writing guidelines link'",
      "SPEECH OUTPUT: ','"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
 sequence.append(utils.AssertPresentationAction(
-    "8. Line Down",
+    "6. Line Down",
     ["BRAILLE LINE:  'please look at the list of most frequently reported bugs, and please'",
      "     VISIBLE:  'please look at the list of most ', cursor=1",
      "SPEECH OUTPUT: 'please look at the list of'",
-     "SPEECH OUTPUT: 'most frequently reported bugs'",
-     "SPEECH OUTPUT: 'link'",
+     "SPEECH OUTPUT: 'most frequently reported bugs link'",
      "SPEECH OUTPUT: ', and please'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
 sequence.append(utils.AssertPresentationAction(
-    "9. Line Down",
+    "7. Line Down",
     ["BRAILLE LINE:  'search or browse for the bug.'",
      "     VISIBLE:  'search or browse for the bug.', cursor=1",
-     "SPEECH OUTPUT: 'search'",
-     "SPEECH OUTPUT: 'link'",
+     "SPEECH OUTPUT: 'search link'",
      "SPEECH OUTPUT: 'or'",
-     "SPEECH OUTPUT: 'browse'",
-     "SPEECH OUTPUT: 'link'",
+     "SPEECH OUTPUT: 'browse link'",
      "SPEECH OUTPUT: 'for the bug.'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
 sequence.append(utils.AssertPresentationAction(
-    "10. Line Down",
-    ["BRAILLE LINE:  ''",
-     "     VISIBLE:  '', cursor=1",
-     "SPEECH OUTPUT: 'blank'"]))
-
-sequence.append(utils.StartRecordingAction())
-sequence.append(KeyComboAction("Down"))
-sequence.append(utils.AssertPresentationAction(
-    "11. Line Down",
+    "8. Line Down",
     ["BRAILLE LINE:  'Reporter: joanmarie diggs gmail com Product: orca'",
      "     VISIBLE:  'Reporter: joanmarie diggs gmail ', cursor=1",
      "SPEECH OUTPUT: 'Reporter:'",
@@ -137,7 +101,7 @@ sequence.append(utils.AssertPresentationAction(
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
 sequence.append(utils.AssertPresentationAction(
-    "12. Line Down",
+    "9. Line Down",
     ["BRAILLE LINE:  'Version:'",
      "     VISIBLE:  'Version:', cursor=1",
      "SPEECH OUTPUT: 'Version:'"]))
@@ -145,41 +109,32 @@ sequence.append(utils.AssertPresentationAction(
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
 sequence.append(utils.AssertPresentationAction(
-    "13. Line Down",
+    "10. Line Down",
     ["BRAILLE LINE:  '2.21.x  list box'",
      "     VISIBLE:  '2.21.x  list box', cursor=1",
-     "SPEECH OUTPUT: 'Version: 2.21.x  List with 9 items'"]))
+     "SPEECH OUTPUT: '2.21.x  List with 9 items'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
 sequence.append(utils.AssertPresentationAction(
-    "14. Line Down",
+    "11. Line Down",
     ["BRAILLE LINE:  'Component:'",
      "     VISIBLE:  'Component:', cursor=1",
-     "SPEECH OUTPUT: 'Component'",
-     "SPEECH OUTPUT: 'link'",
+     "SPEECH OUTPUT: 'Component link'",
      "SPEECH OUTPUT: ':'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
 sequence.append(utils.AssertPresentationAction(
-    "15. Line Down",
+    "12. Line Down",
     ["BRAILLE LINE:  'braille  list box'",
      "     VISIBLE:  'braille  list box', cursor=1",
-     "SPEECH OUTPUT: 'Component: braille  List with 5 items'"]))
-
-sequence.append(utils.StartRecordingAction())
-sequence.append(KeyComboAction("Down"))
-sequence.append(utils.AssertPresentationAction(
-    "16. Line Down",
-    ["BRAILLE LINE:  ' '",
-     "     VISIBLE:  ' ', cursor=1",
-     "SPEECH OUTPUT: 'blank'"]))
+     "SPEECH OUTPUT: 'braille  List with 5 items'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
 sequence.append(utils.AssertPresentationAction(
-    "17. Line Down",
+    "13. Line Down",
     ["BRAILLE LINE:  'GNOME'",
      "     VISIBLE:  'GNOME', cursor=1",
      "SPEECH OUTPUT: 'GNOME'",
@@ -188,7 +143,7 @@ sequence.append(utils.AssertPresentationAction(
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
 sequence.append(utils.AssertPresentationAction(
-    "18. Line Down",
+    "14. Line Down",
     ["BRAILLE LINE:  'version:'",
      "     VISIBLE:  'version:', cursor=1",
      "SPEECH OUTPUT: 'version'",
@@ -198,53 +153,44 @@ sequence.append(utils.AssertPresentationAction(
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
 sequence.append(utils.AssertPresentationAction(
-    "19. Line Down",
+    "15. Line Down",
     ["BRAILLE LINE:  'Unspecified combo box'",
      "     VISIBLE:  'Unspecified combo box', cursor=1",
-     "SPEECH OUTPUT: 'GNOME version: Unspecified combo box'"]))
+     "SPEECH OUTPUT: 'Unspecified combo box'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
 sequence.append(utils.AssertPresentationAction(
-    "20. Line Down",
+    "16. Line Down",
     ["BRAILLE LINE:  'OS: Linux combo box'",
      "     VISIBLE:  'OS: Linux combo box', cursor=1",
-     "SPEECH OUTPUT: 'OS'",
-     "SPEECH OUTPUT: 'link'",
+     "SPEECH OUTPUT: 'OS link'",
      "SPEECH OUTPUT: ':'",
-     "SPEECH OUTPUT: 'OS: Linux combo box'"]))
+     "SPEECH OUTPUT: 'Linux combo box'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
 sequence.append(utils.AssertPresentationAction(
-    "21. Line Down",
+    "17. Line Down",
     ["BRAILLE LINE:  'Severity: normal combo box'",
      "     VISIBLE:  'Severity: normal combo box', cursor=1",
-     "SPEECH OUTPUT: 'Severity'",
-     "SPEECH OUTPUT: 'link'",
+     "SPEECH OUTPUT: 'Severity link'",
      "SPEECH OUTPUT: ':'",
-     "SPEECH OUTPUT: 'Severity: normal combo box'"]))
-
-sequence.append(utils.StartRecordingAction())
-sequence.append(KeyComboAction("Down"))
-sequence.append(utils.AssertPresentationAction(
-    "22. Line Down",
-    ["BRAILLE LINE:  ' '",
-     "     VISIBLE:  ' ', cursor=1",
-     "SPEECH OUTPUT: 'blank'"]))
+     "SPEECH OUTPUT: 'normal combo box'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
 sequence.append(utils.AssertPresentationAction(
-    "23. Line Down",
+    "18. Line Down",
     ["BRAILLE LINE:  'Summary: $l'",
      "     VISIBLE:  'Summary: $l', cursor=1",
-     "SPEECH OUTPUT: 'Summary: entry'"]))
+     "SPEECH OUTPUT: 'Summary:'",
+     "SPEECH OUTPUT: 'entry'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
 sequence.append(utils.AssertPresentationAction(
-    "24. Line Down",
+    "19. Line Down",
     ["BRAILLE LINE:  'Description:'",
      "     VISIBLE:  'Description:', cursor=1",
      "SPEECH OUTPUT: 'Description:'"]))
@@ -252,23 +198,15 @@ sequence.append(utils.AssertPresentationAction(
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
 sequence.append(utils.AssertPresentationAction(
-    "25. Line Down",
+    "20. Line Down",
     ["BRAILLE LINE:  ' $l'",
      "     VISIBLE:  ' $l', cursor=1",
-     "SPEECH OUTPUT: 'Description: entry'"]))
-
-sequence.append(utils.StartRecordingAction())
-sequence.append(KeyComboAction("Down"))
-sequence.append(utils.AssertPresentationAction(
-    "26. Line Down",
-    ["BRAILLE LINE:  ' '",
-     "     VISIBLE:  ' ', cursor=1",
-     "SPEECH OUTPUT: 'blank'"]))
+     "SPEECH OUTPUT: 'entry'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
 sequence.append(utils.AssertPresentationAction(
-    "27. Line Down",
+    "21. Line Down",
     ["BRAILLE LINE:  'Optional Fields'",
      "     VISIBLE:  'Optional Fields', cursor=1",
      "SPEECH OUTPUT: 'Optional Fields'"]))
@@ -276,26 +214,26 @@ sequence.append(utils.AssertPresentationAction(
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
 sequence.append(utils.AssertPresentationAction(
-    "28. Line Down",
+    "22. Line Down",
     ["BRAILLE LINE:  'Cc: $l'",
      "     VISIBLE:  'Cc: $l', cursor=1",
-     "SPEECH OUTPUT: 'Cc: entry'"]))
+     "SPEECH OUTPUT: 'Cc:'",
+     "SPEECH OUTPUT: 'entry'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
 sequence.append(utils.AssertPresentationAction(
-    "29. Line Down",
+    "23. Line Down",
     ["BRAILLE LINE:  'Keywords:  $l'",
      "     VISIBLE:  'Keywords:  $l', cursor=1",
-     "SPEECH OUTPUT: 'Keywords'",
-     "SPEECH OUTPUT: 'link'",
+     "SPEECH OUTPUT: 'Keywords link'",
      "SPEECH OUTPUT: ':'",
-     "SPEECH OUTPUT: 'Keywords: entry'"]))
+     "SPEECH OUTPUT: 'entry'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
 sequence.append(utils.AssertPresentationAction(
-    "30. Line Down",
+    "24. Line Down",
     ["BRAILLE LINE:  'Depends'",
      "     VISIBLE:  'Depends', cursor=1",
      "SPEECH OUTPUT: 'Depends'"]))
@@ -303,26 +241,26 @@ sequence.append(utils.AssertPresentationAction(
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
 sequence.append(utils.AssertPresentationAction(
-    "31. Line Up",
+    "25. Line Up",
     ["BRAILLE LINE:  'Keywords:  $l'",
      "     VISIBLE:  'Keywords:  $l', cursor=1",
-     "SPEECH OUTPUT: 'Keywords'",
-     "SPEECH OUTPUT: 'link'",
+     "SPEECH OUTPUT: 'Keywords link'",
      "SPEECH OUTPUT: ':'",
-     "SPEECH OUTPUT: 'Keywords: entry'"]))
+     "SPEECH OUTPUT: 'entry'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
 sequence.append(utils.AssertPresentationAction(
-    "32. Line Up",
+    "26. Line Up",
     ["BRAILLE LINE:  'Cc: $l'",
      "     VISIBLE:  'Cc: $l', cursor=1",
-     "SPEECH OUTPUT: 'Cc: entry'"]))
+     "SPEECH OUTPUT: 'Cc:'",
+     "SPEECH OUTPUT: 'entry'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
 sequence.append(utils.AssertPresentationAction(
-    "33. Line Up",
+    "27. Line Up",
     ["BRAILLE LINE:  'Optional Fields'",
      "     VISIBLE:  'Optional Fields', cursor=1",
      "SPEECH OUTPUT: 'Optional Fields'"]))
@@ -330,23 +268,15 @@ sequence.append(utils.AssertPresentationAction(
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
 sequence.append(utils.AssertPresentationAction(
-    "34. Line Up",
-    ["BRAILLE LINE:  ' '",
-     "     VISIBLE:  ' ', cursor=1",
-     "SPEECH OUTPUT: 'blank'"]))
-
-sequence.append(utils.StartRecordingAction())
-sequence.append(KeyComboAction("Up"))
-sequence.append(utils.AssertPresentationAction(
-    "35. Line Up",
+    "28. Line Up",
     ["BRAILLE LINE:  ' $l'",
      "     VISIBLE:  ' $l', cursor=1",
-     "SPEECH OUTPUT: 'Description: entry'"]))
+     "SPEECH OUTPUT: 'entry'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
 sequence.append(utils.AssertPresentationAction(
-    "36. Line Up",
+    "29. Line Up",
     ["BRAILLE LINE:  'Description:'",
      "     VISIBLE:  'Description:', cursor=1",
      "SPEECH OUTPUT: 'Description:'"]))
@@ -354,63 +284,54 @@ sequence.append(utils.AssertPresentationAction(
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
 sequence.append(utils.AssertPresentationAction(
-    "37. Line Up",
+    "30. Line Up",
     ["BRAILLE LINE:  'Summary: $l'",
      "     VISIBLE:  'Summary: $l', cursor=1",
-     "SPEECH OUTPUT: 'Summary: entry'"]))
+     "SPEECH OUTPUT: 'Summary:'",
+     "SPEECH OUTPUT: 'entry'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
 sequence.append(utils.AssertPresentationAction(
-    "38. Line Up",
-    ["BRAILLE LINE:  ' '",
-     "     VISIBLE:  ' ', cursor=1",
-     "SPEECH OUTPUT: 'blank'"]))
-
-sequence.append(utils.StartRecordingAction())
-sequence.append(KeyComboAction("Up"))
-sequence.append(utils.AssertPresentationAction(
-    "39. Line Up",
+    "31. Line Up",
     ["BRAILLE LINE:  'Severity: normal combo box'",
      "     VISIBLE:  'Severity: normal combo box', cursor=1",
-     "SPEECH OUTPUT: 'Severity'",
-     "SPEECH OUTPUT: 'link'",
+     "SPEECH OUTPUT: 'Severity link'",
      "SPEECH OUTPUT: ':'",
-     "SPEECH OUTPUT: 'Severity: normal combo box'"]))
+     "SPEECH OUTPUT: 'normal combo box'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
 sequence.append(utils.AssertPresentationAction(
-    "40. Line Up",
+    "32. Line Up",
     ["BRAILLE LINE:  'OS: Linux combo box'",
      "     VISIBLE:  'OS: Linux combo box', cursor=1",
-     "SPEECH OUTPUT: 'OS'",
-     "SPEECH OUTPUT: 'link'",
+     "SPEECH OUTPUT: 'OS link'",
      "SPEECH OUTPUT: ':'",
-     "SPEECH OUTPUT: 'OS: Linux combo box'"]))
+     "SPEECH OUTPUT: 'Linux combo box'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
 sequence.append(utils.AssertPresentationAction(
-    "41. Line Up",
+    "33. Line Up",
     ["BRAILLE LINE:  'Unspecified combo box'",
      "     VISIBLE:  'Unspecified combo box', cursor=1",
-     "SPEECH OUTPUT: 'GNOME version: Unspecified combo box'"]))
+     "SPEECH OUTPUT: 'Unspecified combo box'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
 sequence.append(utils.AssertPresentationAction(
-    "42. Line Up",
+    "34. Line Up",
     ["BRAILLE LINE:  'version:'",
      "     VISIBLE:  'version:', cursor=1",
-     "SPEECH OUTPUT: 'version'",
+     "SPEECH OUTPUT: 'version",
      "SPEECH OUTPUT: 'link'",
      "SPEECH OUTPUT: ':'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
 sequence.append(utils.AssertPresentationAction(
-    "43. Line Up",
+    "35. Line Up",
     ["BRAILLE LINE:  'GNOME'",
      "     VISIBLE:  'GNOME', cursor=1",
      "SPEECH OUTPUT: 'GNOME'",
@@ -419,41 +340,32 @@ sequence.append(utils.AssertPresentationAction(
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
 sequence.append(utils.AssertPresentationAction(
-    "44. Line Up",
-    ["BRAILLE LINE:  ' '",
-     "     VISIBLE:  ' ', cursor=1",
-     "SPEECH OUTPUT: 'blank'"]))
-
-sequence.append(utils.StartRecordingAction())
-sequence.append(KeyComboAction("Up"))
-sequence.append(utils.AssertPresentationAction(
-    "45. Line Up",
+    "36. Line Up",
     ["BRAILLE LINE:  'braille  list box'",
      "     VISIBLE:  'braille  list box', cursor=1",
-     "SPEECH OUTPUT: 'Component: braille  List with 5 items'"]))
+     "SPEECH OUTPUT: 'braille  List with 5 items'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
 sequence.append(utils.AssertPresentationAction(
-    "46. Line Up",
+    "37. Line Up",
     ["BRAILLE LINE:  'Component:'",
      "     VISIBLE:  'Component:', cursor=1",
-     "SPEECH OUTPUT: 'Component'",
-     "SPEECH OUTPUT: 'link'",
+     "SPEECH OUTPUT: 'Component link'",
      "SPEECH OUTPUT: ':'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
 sequence.append(utils.AssertPresentationAction(
-    "47. Line Up",
+    "38. Line Up",
     ["BRAILLE LINE:  '2.21.x  list box'",
      "     VISIBLE:  '2.21.x  list box', cursor=1",
-     "SPEECH OUTPUT: 'Version: 2.21.x  List with 9 items'"]))
+     "SPEECH OUTPUT: '2.21.x  List with 9 items'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
 sequence.append(utils.AssertPresentationAction(
-    "48. Line Up",
+    "39. Line Up",
     ["BRAILLE LINE:  'Version:'",
      "     VISIBLE:  'Version:', cursor=1",
      "SPEECH OUTPUT: 'Version:'"]))
@@ -461,7 +373,7 @@ sequence.append(utils.AssertPresentationAction(
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
 sequence.append(utils.AssertPresentationAction(
-    "49. Line Up",
+    "40. Line Up",
     ["BRAILLE LINE:  'Reporter: joanmarie diggs gmail com Product: orca'",
      "     VISIBLE:  'Reporter: joanmarie diggs gmail ', cursor=1",
      "SPEECH OUTPUT: 'Reporter:'",
@@ -472,66 +384,38 @@ sequence.append(utils.AssertPresentationAction(
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
 sequence.append(utils.AssertPresentationAction(
-    "50. Line Up",
-    ["BRAILLE LINE:  ''",
-     "     VISIBLE:  '', cursor=1",
-     "SPEECH OUTPUT: 'blank'"]))
-
-sequence.append(utils.StartRecordingAction())
-sequence.append(KeyComboAction("Up"))
-sequence.append(utils.AssertPresentationAction(
-    "51. Line Up",
+    "41. Line Up",
     ["BRAILLE LINE:  'search or browse for the bug.'",
      "     VISIBLE:  'search or browse for the bug.', cursor=1",
-     "SPEECH OUTPUT: 'search'",
-     "SPEECH OUTPUT: 'link'",
+     "SPEECH OUTPUT: 'search link'",
      "SPEECH OUTPUT: 'or'",
-     "SPEECH OUTPUT: 'browse'",
-     "SPEECH OUTPUT: 'link'",
+     "SPEECH OUTPUT: 'browse link'",
      "SPEECH OUTPUT: 'for the bug.'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
 sequence.append(utils.AssertPresentationAction(
-    "52. Line Up",
+    "42. Line Up",
     ["BRAILLE LINE:  'please look at the list of most frequently reported bugs, and please'",
      "     VISIBLE:  'please look at the list of most ', cursor=1",
      "SPEECH OUTPUT: 'please look at the list of'",
-     "SPEECH OUTPUT: 'most frequently reported bugs'",
-     "SPEECH OUTPUT: 'link'",
+     "SPEECH OUTPUT: 'most frequently reported bugs link'",
      "SPEECH OUTPUT: ', and please'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
 sequence.append(utils.AssertPresentationAction(
-    "53. Line Up",
+    "43. Line Up",
     ["BRAILLE LINE:  'Before reporting a bug, please read the bug writing guidelines,'",
      "     VISIBLE:  'Before reporting a bug, please r', cursor=1",
      "SPEECH OUTPUT: 'Before reporting a bug, please read the'",
-     "SPEECH OUTPUT: 'bug writing guidelines'",
-     "SPEECH OUTPUT: 'link'",
+     "SPEECH OUTPUT: 'bug writing guidelines link'",
      "SPEECH OUTPUT: ','"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
 sequence.append(utils.AssertPresentationAction(
-    "54. Line Up",
-    ["BRAILLE LINE:  ''",
-     "     VISIBLE:  '', cursor=1",
-     "SPEECH OUTPUT: 'blank'"]))
-
-sequence.append(utils.StartRecordingAction())
-sequence.append(KeyComboAction("Up"))
-sequence.append(utils.AssertPresentationAction(
-    "55. Line Up",
-    ["BRAILLE LINE:  ''",
-     "     VISIBLE:  '', cursor=1",
-     "SPEECH OUTPUT: 'blank'"]))
-
-sequence.append(utils.StartRecordingAction())
-sequence.append(KeyComboAction("Up"))
-sequence.append(utils.AssertPresentationAction(
-    "56. Line Up",
+    "44. Line Up",
     ["BRAILLE LINE:  'into Bugzilla. h1'",
      "     VISIBLE:  'into Bugzilla. h1', cursor=1",
      "SPEECH OUTPUT: 'into Bugzilla. heading level 1'"]))
@@ -539,7 +423,7 @@ sequence.append(utils.AssertPresentationAction(
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
 sequence.append(utils.AssertPresentationAction(
-    "57. Line Up",
+    "45. Line Up",
     ["BRAILLE LINE:  'Enter Bug: orca \u2013 This page lets you enter a new bug  h1'",
      "     VISIBLE:  'Enter Bug: orca – This page lets', cursor=1",
      "SPEECH OUTPUT: 'Enter Bug: orca \u2013 This page lets you enter a new bug heading level 1'"]))
@@ -547,37 +431,29 @@ sequence.append(utils.AssertPresentationAction(
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
 sequence.append(utils.AssertPresentationAction(
-    "58. Line Up",
+    "46. Line Up",
     ["BRAILLE LINE:  'New bug · Browse · Search · Reports · Account · Admin · Help Logged In joanmarie diggs 
gmail com | Log Out'",
      "     VISIBLE:  'New bug · Browse · Search · Repo', cursor=1",
-     "SPEECH OUTPUT: 'New bug'",
-     "SPEECH OUTPUT: 'link'",
+     "SPEECH OUTPUT: 'New bug link'",
      "SPEECH OUTPUT: '·'",
-     "SPEECH OUTPUT: 'Browse'",
-     "SPEECH OUTPUT: 'link'",
+     "SPEECH OUTPUT: 'Browse link'",
      "SPEECH OUTPUT: '·'",
-     "SPEECH OUTPUT: 'Search'",
-     "SPEECH OUTPUT: 'link'",
+     "SPEECH OUTPUT: 'Search link'",
      "SPEECH OUTPUT: '·'",
-     "SPEECH OUTPUT: 'Reports'",
-     "SPEECH OUTPUT: 'link'",
+     "SPEECH OUTPUT: 'Reports link'",
      "SPEECH OUTPUT: '·'",
-     "SPEECH OUTPUT: 'Account'",
-     "SPEECH OUTPUT: 'link'",
+     "SPEECH OUTPUT: 'Account link'",
      "SPEECH OUTPUT: '·'",
-     "SPEECH OUTPUT: 'Admin'",
-     "SPEECH OUTPUT: 'link'",
+     "SPEECH OUTPUT: 'Admin link'",
      "SPEECH OUTPUT: '·'",
-     "SPEECH OUTPUT: 'Help'",
-     "SPEECH OUTPUT: 'link'",
+     "SPEECH OUTPUT: 'Help link'",
      "SPEECH OUTPUT: 'Logged In joanmarie diggs gmail com |'",
-     "SPEECH OUTPUT: 'Log Out'",
-     "SPEECH OUTPUT: 'link'"]))
+     "SPEECH OUTPUT: 'Log Out link'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
 sequence.append(utils.AssertPresentationAction(
-    "59. Line Up",
+    "47. Line Up",
     ["BRAILLE LINE:  'Home Bugzilla'",
      "     VISIBLE:  'Home Bugzilla', cursor=1",
      "SPEECH OUTPUT: 'Home link Back to the Gnome Bugzilla home page'",
diff --git a/test/keystrokes/firefox/line_nav_entries.py b/test/keystrokes/firefox/line_nav_entries.py
index f70bc19..1cbdc89 100644
--- a/test/keystrokes/firefox/line_nav_entries.py
+++ b/test/keystrokes/firefox/line_nav_entries.py
@@ -23,17 +23,14 @@ sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
 sequence.append(utils.AssertPresentationAction(
     "2. Line Down",
-    ["KNOWN ISSUE: We need to filter out the multiple objects",
-     "BRAILLE LINE:  'Type something rather amusing here:  $l'",
+    ["BRAILLE LINE:  'Type something rather amusing here:  $l'",
      "     VISIBLE:  'Type something rather amusing he', cursor=1",
      "SPEECH OUTPUT: 'Type'",
-     "SPEECH OUTPUT: 'something'",
-     "SPEECH OUTPUT: 'link'",
+     "SPEECH OUTPUT: 'something link'",
      "SPEECH OUTPUT: 'rather'",
-     "SPEECH OUTPUT: 'amusing'",
-     "SPEECH OUTPUT: 'link'",
+     "SPEECH OUTPUT: 'amusing link'",
      "SPEECH OUTPUT: 'here:'",
-     "SPEECH OUTPUT: 'Type something rather amusing here: entry'"]))
+     "SPEECH OUTPUT: 'entry'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
@@ -41,8 +38,10 @@ sequence.append(utils.AssertPresentationAction(
     "3. Line Down",
     ["BRAILLE LINE:  'Amusing numbers fall between  $l and  $l.'",
      "     VISIBLE:  'Amusing numbers fall between  $l', cursor=1",
-     "SPEECH OUTPUT: 'Amusing numbers fall between entry'",
-     "SPEECH OUTPUT: 'and entry'",
+     "SPEECH OUTPUT: 'Amusing numbers fall between'",
+     "SPEECH OUTPUT: 'entry'",
+     "SPEECH OUTPUT: 'and'",
+     "SPEECH OUTPUT: 'entry'",
      "SPEECH OUTPUT: '.'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -51,7 +50,8 @@ sequence.append(utils.AssertPresentationAction(
     "4. Line Down",
     ["BRAILLE LINE:  ' $l I'm a label'",
      "     VISIBLE:  ' $l I'm a label', cursor=1",
-     "SPEECH OUTPUT: 'I'm a label entry'"]))
+     "SPEECH OUTPUT: 'entry'",
+     "SPEECH OUTPUT: 'I'm a label'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
@@ -84,7 +84,7 @@ sequence.append(utils.AssertPresentationAction(
     "8. Line Down",
     ["BRAILLE LINE:  ' $l Too far away to be a label.'",
      "     VISIBLE:  ' $l Too far away to be a label.', cursor=1",
-     "SPEECH OUTPUT: 'Looking at what follows visually, I'm not sure what I would type/i.e. what the labels 
are. entry'",
+     "SPEECH OUTPUT: 'entry'",
      "SPEECH OUTPUT: 'Too far away to be a label.'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -93,7 +93,8 @@ sequence.append(utils.AssertPresentationAction(
     "9. Line Down",
     ["BRAILLE LINE:  'Distance doesn't count on the left $l'",
      "     VISIBLE:  'Distance doesn't count on the le', cursor=1",
-     "SPEECH OUTPUT: 'Distance doesn't count on the left entry'"]))
+     "SPEECH OUTPUT: 'Distance doesn't count on the left'",
+     "SPEECH OUTPUT: 'entry'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
@@ -109,7 +110,7 @@ sequence.append(utils.AssertPresentationAction(
     "11. Line Down",
     ["BRAILLE LINE:  ' $l'",
      "     VISIBLE:  ' $l', cursor=1",
-     "SPEECH OUTPUT: 'First Name entry'"]))
+     "SPEECH OUTPUT: 'entry'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
@@ -125,7 +126,7 @@ sequence.append(utils.AssertPresentationAction(
     "13. Line Down",
     ["BRAILLE LINE:  ' $l'",
      "     VISIBLE:  ' $l', cursor=1",
-     "SPEECH OUTPUT: 'M.I. entry'"]))
+     "SPEECH OUTPUT: 'entry'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
@@ -141,7 +142,7 @@ sequence.append(utils.AssertPresentationAction(
     "15. Line Down",
     ["BRAILLE LINE:  ' $l'",
      "     VISIBLE:  ' $l', cursor=1",
-     "SPEECH OUTPUT: 'Last Name entry'"]))
+     "SPEECH OUTPUT: 'entry'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
@@ -165,9 +166,9 @@ sequence.append(utils.AssertPresentationAction(
     "18. Line Down",
     ["BRAILLE LINE:  ' $l $l $l'",
      "     VISIBLE:  ' $l $l $l', cursor=1",
-     "SPEECH OUTPUT: 'First name entry'",
-     "SPEECH OUTPUT: 'Middle initial entry'",
-     "SPEECH OUTPUT: 'Last name entry'"]))
+     "SPEECH OUTPUT: 'entry'",
+     "SPEECH OUTPUT: 'entry'",
+     "SPEECH OUTPUT: 'entry'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
@@ -200,8 +201,7 @@ sequence.append(utils.AssertPresentationAction(
     ["BRAILLE LINE:  'Last name'",
      "     VISIBLE:  'Last name', cursor=1",
      "SPEECH OUTPUT: 'Last'",
-     "SPEECH OUTPUT: 'name'",
-     "SPEECH OUTPUT: 'link'"]))
+     "SPEECH OUTPUT: 'name link'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
@@ -242,8 +242,7 @@ sequence.append(utils.AssertPresentationAction(
     ["BRAILLE LINE:  'Last name'",
      "     VISIBLE:  'Last name', cursor=1",
      "SPEECH OUTPUT: 'Last'",
-     "SPEECH OUTPUT: 'name'",
-     "SPEECH OUTPUT: 'link'"]))
+     "SPEECH OUTPUT: 'name link'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
@@ -251,9 +250,9 @@ sequence.append(utils.AssertPresentationAction(
     "28. Line Down",
     ["BRAILLE LINE:  ' $l $l $l'",
      "     VISIBLE:  ' $l $l $l', cursor=1",
-     "SPEECH OUTPUT: 'First Name entry'",
-     "SPEECH OUTPUT: 'Middle initial entry'",
-     "SPEECH OUTPUT: 'Last name entry'"]))
+     "SPEECH OUTPUT: 'entry'",
+     "SPEECH OUTPUT: 'entry'",
+     "SPEECH OUTPUT: 'entry'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
@@ -286,9 +285,9 @@ sequence.append(utils.AssertPresentationAction(
     "32. Line Up",
     ["BRAILLE LINE:  ' $l $l $l'",
      "     VISIBLE:  ' $l $l $l', cursor=1",
-     "SPEECH OUTPUT: 'First Name entry'",
-     "SPEECH OUTPUT: 'Middle initial entry'",
-     "SPEECH OUTPUT: 'Last name entry'"]))
+     "SPEECH OUTPUT: 'entry'",
+     "SPEECH OUTPUT: 'entry'",
+     "SPEECH OUTPUT: 'entry'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
@@ -297,8 +296,7 @@ sequence.append(utils.AssertPresentationAction(
     ["BRAILLE LINE:  'Last name'",
      "     VISIBLE:  'Last name', cursor=1",
      "SPEECH OUTPUT: 'Last'",
-     "SPEECH OUTPUT: 'name'",
-     "SPEECH OUTPUT: 'link'"]))
+     "SPEECH OUTPUT: 'name link'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
@@ -339,8 +337,7 @@ sequence.append(utils.AssertPresentationAction(
     ["BRAILLE LINE:  'Last name'",
      "     VISIBLE:  'Last name', cursor=1",
      "SPEECH OUTPUT: 'Last'",
-     "SPEECH OUTPUT: 'name'",
-     "SPEECH OUTPUT: 'link'"]))
+     "SPEECH OUTPUT: 'name link'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
@@ -372,9 +369,9 @@ sequence.append(utils.AssertPresentationAction(
     "42. Line Up",
     ["BRAILLE LINE:  ' $l $l $l'",
      "     VISIBLE:  ' $l $l $l', cursor=1",
-     "SPEECH OUTPUT: 'First name entry'",
-     "SPEECH OUTPUT: 'Middle initial entry'",
-     "SPEECH OUTPUT: 'Last name entry'"]))
+     "SPEECH OUTPUT: 'entry'",
+     "SPEECH OUTPUT: 'entry'",
+     "SPEECH OUTPUT: 'entry'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
@@ -398,7 +395,7 @@ sequence.append(utils.AssertPresentationAction(
     "45. Line Up",
     ["BRAILLE LINE:  ' $l'",
      "     VISIBLE:  ' $l', cursor=1",
-     "SPEECH OUTPUT: 'Last Name entry'"]))
+     "SPEECH OUTPUT: 'entry'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
@@ -414,7 +411,7 @@ sequence.append(utils.AssertPresentationAction(
     "47. Line Up",
     ["BRAILLE LINE:  ' $l'",
      "     VISIBLE:  ' $l', cursor=1",
-     "SPEECH OUTPUT: 'M.I. entry'"]))
+     "SPEECH OUTPUT: 'entry'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
@@ -430,7 +427,7 @@ sequence.append(utils.AssertPresentationAction(
     "49. Line Up",
     ["BRAILLE LINE:  ' $l'",
      "     VISIBLE:  ' $l', cursor=1",
-     "SPEECH OUTPUT: 'First Name entry'"]))
+     "SPEECH OUTPUT: 'entry'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
@@ -446,7 +443,8 @@ sequence.append(utils.AssertPresentationAction(
     "51. Line Up",
     ["BRAILLE LINE:  'Distance doesn't count on the left $l'",
      "     VISIBLE:  'Distance doesn't count on the le', cursor=1",
-     "SPEECH OUTPUT: 'Distance doesn't count on the left entry'"]))
+     "SPEECH OUTPUT: 'Distance doesn't count on the left'",
+     "SPEECH OUTPUT: 'entry'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
@@ -454,7 +452,7 @@ sequence.append(utils.AssertPresentationAction(
     "52. Line Up",
     ["BRAILLE LINE:  ' $l Too far away to be a label.'",
      "     VISIBLE:  ' $l Too far away to be a label.', cursor=1",
-     "SPEECH OUTPUT: 'Looking at what follows visually, I'm not sure what I would type/i.e. what the labels 
are. entry'",
+     "SPEECH OUTPUT: 'entry'",
      "SPEECH OUTPUT: 'Too far away to be a label.'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -488,7 +486,8 @@ sequence.append(utils.AssertPresentationAction(
     "56. Line Up",
     ["BRAILLE LINE:  ' $l I'm a label'",
      "     VISIBLE:  ' $l I'm a label', cursor=1",
-     "SPEECH OUTPUT: 'I'm a label entry'"]))
+     "SPEECH OUTPUT: 'entry'",
+     "SPEECH OUTPUT: 'I'm a label"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
@@ -496,25 +495,24 @@ sequence.append(utils.AssertPresentationAction(
     "57. Line Up",
     ["BRAILLE LINE:  'Amusing numbers fall between  $l and  $l.'",
      "     VISIBLE:  'Amusing numbers fall between  $l', cursor=1",
-     "SPEECH OUTPUT: 'Amusing numbers fall between entry'",
-     "SPEECH OUTPUT: 'and entry'",
+     "SPEECH OUTPUT: 'Amusing numbers fall between'",
+     "SPEECH OUTPUT: 'entry'",
+     "SPEECH OUTPUT: 'and'",
+     "SPEECH OUTPUT: 'entry'",
      "SPEECH OUTPUT: '.'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
 sequence.append(utils.AssertPresentationAction(
     "58. Line Up",
-    ["KNOWN ISSUE: We need to filter out the multiple objects",
-     "BRAILLE LINE:  'Type something rather amusing here:  $l'",
+    ["BRAILLE LINE:  'Type something rather amusing here:  $l'",
      "     VISIBLE:  'Type something rather amusing he', cursor=1",
      "SPEECH OUTPUT: 'Type'",
-     "SPEECH OUTPUT: 'something'",
-     "SPEECH OUTPUT: 'link'",
+     "SPEECH OUTPUT: 'something link'",
      "SPEECH OUTPUT: 'rather'",
-     "SPEECH OUTPUT: 'amusing'",
-     "SPEECH OUTPUT: 'link'",
+     "SPEECH OUTPUT: 'amusing link'",
      "SPEECH OUTPUT: 'here:'",
-     "SPEECH OUTPUT: 'Type something rather amusing here: entry'"]))
+     "SPEECH OUTPUT: 'entry'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
diff --git a/test/keystrokes/firefox/line_nav_focused_link.py 
b/test/keystrokes/firefox/line_nav_focused_link.py
index ae5d0e4..ed1dd09 100644
--- a/test/keystrokes/firefox/line_nav_focused_link.py
+++ b/test/keystrokes/firefox/line_nav_focused_link.py
@@ -11,10 +11,10 @@ sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Tab"))
 sequence.append(utils.AssertPresentationAction(
     "1. Tab to link",
-    ["BRAILLE LINE:  '[Line 2]'",
-     "     VISIBLE:  '[Line 2]', cursor=2",
-     "BRAILLE LINE:  '[Line 2]'",
-     "     VISIBLE:  '[Line 2]', cursor=2",
+    ["BRAILLE LINE:  'Line 2'",
+     "     VISIBLE:  'Line 2', cursor=1",
+     "BRAILLE LINE:  'Line 2'",
+     "     VISIBLE:  'Line 2', cursor=1",
      "SPEECH OUTPUT: 'Line 2 link'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -32,8 +32,7 @@ sequence.append(utils.AssertPresentationAction(
     ["BRAILLE LINE:  '[Line 2]'",
      "     VISIBLE:  '[Line 2]', cursor=1",
      "SPEECH OUTPUT: '['",
-     "SPEECH OUTPUT: 'Line 2'",
-     "SPEECH OUTPUT: 'link'",
+     "SPEECH OUTPUT: 'Line 2 link'",
      "SPEECH OUTPUT: ']'"]))
 
 sequence.append(utils.StartRecordingAction())
diff --git a/test/keystrokes/firefox/line_nav_follow_same_page_link.py 
b/test/keystrokes/firefox/line_nav_follow_same_page_link.py
index a85644a..1843857 100644
--- a/test/keystrokes/firefox/line_nav_follow_same_page_link.py
+++ b/test/keystrokes/firefox/line_nav_follow_same_page_link.py
@@ -19,20 +19,20 @@ sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Tab"))
 sequence.append(utils.AssertPresentationAction(
     "2. Tab",
-    ["BRAILLE LINE:  '• First item'",
-     "     VISIBLE:  '• First item', cursor=3",
-     "BRAILLE LINE:  '• First item'",
-     "     VISIBLE:  '• First item', cursor=3",
+    ["BRAILLE LINE:  'First item'",
+     "     VISIBLE:  'First item', cursor=1",
+     "BRAILLE LINE:  'First item'",
+     "     VISIBLE:  'First item', cursor=1",
      "SPEECH OUTPUT: 'First item link'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Tab"))
 sequence.append(utils.AssertPresentationAction(
     "3. Tab",
-    ["BRAILLE LINE:  '• Second item'",
-     "     VISIBLE:  '• Second item', cursor=3",
-     "BRAILLE LINE:  '• Second item'",
-     "     VISIBLE:  '• Second item', cursor=3",
+    ["BRAILLE LINE:  'Second item'",
+     "     VISIBLE:  'Second item', cursor=1",
+     "BRAILLE LINE:  'Second item'",
+     "     VISIBLE:  'Second item', cursor=1",
      "SPEECH OUTPUT: 'Second item link'"]))
 
 sequence.append(utils.StartRecordingAction())
diff --git a/test/keystrokes/firefox/line_nav_follow_same_page_link_2.py 
b/test/keystrokes/firefox/line_nav_follow_same_page_link_2.py
index 5a73f35..7ee01e8 100644
--- a/test/keystrokes/firefox/line_nav_follow_same_page_link_2.py
+++ b/test/keystrokes/firefox/line_nav_follow_same_page_link_2.py
@@ -19,8 +19,8 @@ sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Return"))
 sequence.append(utils.AssertPresentationAction(
     "Return to activate the same-page link for the About heading",
-    ["BRAILLE LINE:  '2. About'",
-     "     VISIBLE:  '2. About', cursor=4",
+    ["BRAILLE LINE:  'About h1'",
+     "     VISIBLE:  'About h1', cursor=1",
      "BRAILLE LINE:  'About h1'",
      "     VISIBLE:  'About h1', cursor=1",
      "SPEECH OUTPUT: 'About heading level 1'"]))
diff --git a/test/keystrokes/firefox/line_nav_hidden_buttons.py 
b/test/keystrokes/firefox/line_nav_hidden_buttons.py
index a7832b1..b03903e 100644
--- a/test/keystrokes/firefox/line_nav_hidden_buttons.py
+++ b/test/keystrokes/firefox/line_nav_hidden_buttons.py
@@ -19,23 +19,15 @@ sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
 sequence.append(utils.AssertPresentationAction(
     "2. Line Down",
-    ["KNOWN ISSUE: We're losing a space in the button name.",
-     "BRAILLE LINE:  'Button1 push button'",
-     "     VISIBLE:  'Button1 push button', cursor=1",
-     "SPEECH OUTPUT: 'Button1 push button'"]))
-
-sequence.append(utils.StartRecordingAction())
-sequence.append(KeyComboAction("Down"))
-sequence.append(utils.AssertPresentationAction(
-    "3. Line Down",
-    ["BRAILLE LINE:  'Button 2 push button'",
-     "     VISIBLE:  'Button 2 push button', cursor=1",
+    ["BRAILLE LINE:  'Button1 push button Button 2 push button'",
+     "     VISIBLE:  'Button1 push button Button 2 pus', cursor=1",
+     "SPEECH OUTPUT: 'Button1 push button'",
      "SPEECH OUTPUT: 'Button 2 push button'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
 sequence.append(utils.AssertPresentationAction(
-    "4. Line Down",
+    "3. Line Down",
     ["BRAILLE LINE:  'The end'",
      "     VISIBLE:  'The end', cursor=1",
      "SPEECH OUTPUT: 'The end'"]))
@@ -43,24 +35,16 @@ sequence.append(utils.AssertPresentationAction(
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
 sequence.append(utils.AssertPresentationAction(
-    "5. Line Up",
-    ["BRAILLE LINE:  'Button 2 push button'",
-     "     VISIBLE:  'Button 2 push button', cursor=1",
+    "4. Line Up",
+    ["BRAILLE LINE:  'Button1 push button Button 2 push button'",
+     "     VISIBLE:  'Button1 push button Button 2 pus', cursor=1",
+     "SPEECH OUTPUT: 'Button1 push button'",
      "SPEECH OUTPUT: 'Button 2 push button'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
 sequence.append(utils.AssertPresentationAction(
-    "6. Line Up",
-    ["KNOWN ISSUE: We're losing a space in the button name.",
-     "BRAILLE LINE:  'Button1 push button'",
-     "     VISIBLE:  'Button1 push button', cursor=1",
-     "SPEECH OUTPUT: 'Button1 push button'"]))
-
-sequence.append(utils.StartRecordingAction())
-sequence.append(KeyComboAction("Up"))
-sequence.append(utils.AssertPresentationAction(
-    "7. Line Up",
+    "5. Line Up",
     ["BRAILLE LINE:  'The start'",
      "     VISIBLE:  'The start', cursor=1",
      "SPEECH OUTPUT: 'The start'"]))
diff --git a/test/keystrokes/firefox/line_nav_hidden_float.py 
b/test/keystrokes/firefox/line_nav_hidden_float.py
index df25c87..943a08d 100644
--- a/test/keystrokes/firefox/line_nav_hidden_float.py
+++ b/test/keystrokes/firefox/line_nav_hidden_float.py
@@ -19,8 +19,8 @@ sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
 sequence.append(utils.AssertPresentationAction(
     "2. Line Down",
-    ["BRAILLE LINE:  ' 2'",
-     "     VISIBLE:  ' 2', cursor=1",
+    ["BRAILLE LINE:  '2'",
+     "     VISIBLE:  '2', cursor=1",
      "SPEECH OUTPUT: '2'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -35,8 +35,8 @@ sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
 sequence.append(utils.AssertPresentationAction(
     "4. Line Up",
-    ["BRAILLE LINE:  ' 2'",
-     "     VISIBLE:  ' 2', cursor=1",
+    ["BRAILLE LINE:  '2'",
+     "     VISIBLE:  '2', cursor=1",
      "SPEECH OUTPUT: '2'"]))
 
 sequence.append(utils.StartRecordingAction())
diff --git a/test/keystrokes/firefox/line_nav_hidden_label.py 
b/test/keystrokes/firefox/line_nav_hidden_label.py
index ba299b3..fba1c25 100644
--- a/test/keystrokes/firefox/line_nav_hidden_label.py
+++ b/test/keystrokes/firefox/line_nav_hidden_label.py
@@ -7,6 +7,10 @@ import utils
 
 sequence = MacroSequence()
 
+# Work around some new quirk in Gecko that causes this test to fail if
+# run via the test harness rather than manually.
+sequence.append(KeyComboAction("<Control>r"))
+
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("<Control>Home"))
 sequence.append(utils.AssertPresentationAction(
@@ -19,35 +23,14 @@ sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
 sequence.append(utils.AssertPresentationAction(
     "2. Line Down",
-    ["KNOWN ISSUE: It would be nice to not present the junk image",
-     "BRAILLE LINE:  '< > I am a hidden label!   Check me! check box image'",
+    ["BRAILLE LINE:  '< > I am a hidden label!   Check me! check box'",
      "     VISIBLE:  '< > I am a hidden label!   Check', cursor=1",
-     "SPEECH OUTPUT: 'I am a hidden label!   Check me! check box not checked'",
-     "SPEECH OUTPUT: 'image'"]))
+     "SPEECH OUTPUT: 'I am a hidden label!   Check me! check box not checked'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
 sequence.append(utils.AssertPresentationAction(
     "3. Line Down",
-    ["KNOWN ISSUE: We're double-presenting this. Might be due to a zombie.",
-     "BRAILLE LINE:  '< > I am a hidden label!   Check me! check box image'",
-     "     VISIBLE:  '< > I am a hidden label!   Check', cursor=1",
-     "SPEECH OUTPUT: 'I am a hidden label!   Check me! check box not checked'",
-     "SPEECH OUTPUT: 'image'"]))
-
-sequence.append(utils.StartRecordingAction())
-sequence.append(KeyComboAction("Down"))
-sequence.append(utils.AssertPresentationAction(
-    "4. Line Down",
-    ["KNOWN ISSUE: We're displaying part of the hidden label",
-     "BRAILLE LINE:  'I '",
-     "     VISIBLE:  'I ', cursor=1",
-     "SPEECH OUTPUT: 'blank'"]))
-
-sequence.append(utils.StartRecordingAction())
-sequence.append(KeyComboAction("Down"))
-sequence.append(utils.AssertPresentationAction(
-    "5. Line Down",
     ["BRAILLE LINE:  'End'",
      "     VISIBLE:  'End', cursor=1",
      "SPEECH OUTPUT: 'End'"]))
@@ -55,25 +38,15 @@ sequence.append(utils.AssertPresentationAction(
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
 sequence.append(utils.AssertPresentationAction(
-    "6. Line Up",
-    ["KNOWN ISSUE: We're displaying the hidden label",
-     "BRAILLE LINE:  'I am a hidden label!   Check me!'",
-     "     VISIBLE:  'I am a hidden label!   Check me!', cursor=1",
-     "SPEECH OUTPUT: 'blank'"]))
-
-sequence.append(utils.StartRecordingAction())
-sequence.append(KeyComboAction("Up"))
-sequence.append(utils.AssertPresentationAction(
-    "7. Line Up",
-    ["BRAILLE LINE:  '< > I am a hidden label!   Check me! check box image'",
+    "4. Line Up",
+    ["BRAILLE LINE:  '< > I am a hidden label!   Check me! check box'",
      "     VISIBLE:  '< > I am a hidden label!   Check', cursor=1",
-     "SPEECH OUTPUT: 'I am a hidden label!   Check me! check box not checked'",
-     "SPEECH OUTPUT: 'image'"]))
+     "SPEECH OUTPUT: 'I am a hidden label!   Check me! check box not checked'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
 sequence.append(utils.AssertPresentationAction(
-    "8. Line Up",
+    "5. Line Up",
     ["BRAILLE LINE:  'Start'",
      "     VISIBLE:  'Start', cursor=1",
      "SPEECH OUTPUT: 'Start'"]))
diff --git a/test/keystrokes/firefox/line_nav_hidden_links.py 
b/test/keystrokes/firefox/line_nav_hidden_links.py
index 5963cbe..a76d047 100644
--- a/test/keystrokes/firefox/line_nav_hidden_links.py
+++ b/test/keystrokes/firefox/line_nav_hidden_links.py
@@ -21,8 +21,7 @@ sequence.append(utils.AssertPresentationAction(
     "2. Line Down",
     ["BRAILLE LINE:  'up vote'",
      "     VISIBLE:  'up vote', cursor=1",
-     "SPEECH OUTPUT: 'up vote'",
-     "SPEECH OUTPUT: 'link'"]))
+     "SPEECH OUTPUT: 'up vote link'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
@@ -38,8 +37,7 @@ sequence.append(utils.AssertPresentationAction(
     "4. Line Down",
     ["BRAILLE LINE:  'down vote'",
      "     VISIBLE:  'down vote', cursor=1",
-     "SPEECH OUTPUT: 'down vote'",
-     "SPEECH OUTPUT: 'link'"]))
+     "SPEECH OUTPUT: 'down vote link'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
@@ -71,8 +69,7 @@ sequence.append(utils.AssertPresentationAction(
     "8. Line Up",
     ["BRAILLE LINE:  'down vote'",
      "     VISIBLE:  'down vote', cursor=1",
-     "SPEECH OUTPUT: 'down vote'",
-     "SPEECH OUTPUT: 'link'"]))
+     "SPEECH OUTPUT: 'down vote link'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
@@ -88,8 +85,7 @@ sequence.append(utils.AssertPresentationAction(
     "10. Line Up",
     ["BRAILLE LINE:  'up vote'",
      "     VISIBLE:  'up vote', cursor=1",
-     "SPEECH OUTPUT: 'up vote'",
-     "SPEECH OUTPUT: 'link'"]))
+     "SPEECH OUTPUT: 'up vote link'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
diff --git a/test/keystrokes/firefox/line_nav_iframes_in_inline_block.py 
b/test/keystrokes/firefox/line_nav_iframes_in_inline_block.py
index 1a3f4c6..83b496e 100644
--- a/test/keystrokes/firefox/line_nav_iframes_in_inline_block.py
+++ b/test/keystrokes/firefox/line_nav_iframes_in_inline_block.py
@@ -23,22 +23,6 @@ sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
 sequence.append(utils.AssertPresentationAction(
     "2. Line Down",
-    ["BRAILLE LINE:  ' $l'",
-     "     VISIBLE:  ' $l', cursor=0",
-     "SPEECH OUTPUT: 'blank'"]))
-
-sequence.append(utils.StartRecordingAction())
-sequence.append(KeyComboAction("Down"))
-sequence.append(utils.AssertPresentationAction(
-    "3. Line Down",
-    ["BRAILLE LINE:  ' $l'",
-     "     VISIBLE:  ' $l', cursor=0",
-     "SPEECH OUTPUT: 'blank'"]))
-
-sequence.append(utils.StartRecordingAction())
-sequence.append(KeyComboAction("Down"))
-sequence.append(utils.AssertPresentationAction(
-    "4. Line Down",
     ["BRAILLE LINE:  'Line 3'",
      "     VISIBLE:  'Line 3', cursor=1",
      "SPEECH OUTPUT: 'Line 3'"]))
@@ -46,15 +30,7 @@ sequence.append(utils.AssertPresentationAction(
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
 sequence.append(utils.AssertPresentationAction(
-    "5. Line Up",
-    ["BRAILLE LINE:  ' $l'",
-     "     VISIBLE:  ' $l', cursor=0",
-     "SPEECH OUTPUT: 'blank'"]))
-
-sequence.append(utils.StartRecordingAction())
-sequence.append(KeyComboAction("Up"))
-sequence.append(utils.AssertPresentationAction(
-    "6. Line Up",
+    "3. Line Up",
     ["BRAILLE LINE:  'Line 1'",
      "     VISIBLE:  'Line 1', cursor=1",
      "SPEECH OUTPUT: 'Line 1'"]))
diff --git a/test/keystrokes/firefox/line_nav_iframes_in_inline_block2.py 
b/test/keystrokes/firefox/line_nav_iframes_in_inline_block2.py
index 6e3c4ee..1d32d56 100644
--- a/test/keystrokes/firefox/line_nav_iframes_in_inline_block2.py
+++ b/test/keystrokes/firefox/line_nav_iframes_in_inline_block2.py
@@ -56,14 +56,6 @@ sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
 sequence.append(utils.AssertPresentationAction(
     "6. Line Down",
-    ["BRAILLE LINE:  '  $l'",
-     "     VISIBLE:  '  $l', cursor=1",
-     "SPEECH OUTPUT: 'blank'"]))
-
-sequence.append(utils.StartRecordingAction())
-sequence.append(KeyComboAction("Down"))
-sequence.append(utils.AssertPresentationAction(
-    "7. Line Down",
     ["BRAILLE LINE:  'Line 3'",
      "     VISIBLE:  'Line 3', cursor=1",
      "SPEECH OUTPUT: 'Line 3'"]))
@@ -71,15 +63,7 @@ sequence.append(utils.AssertPresentationAction(
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
 sequence.append(utils.AssertPresentationAction(
-    "8. Line Up",
-    ["BRAILLE LINE:  '  $l'",
-     "     VISIBLE:  '  $l', cursor=1",
-     "SPEECH OUTPUT: 'blank'"]))
-
-sequence.append(utils.StartRecordingAction())
-sequence.append(KeyComboAction("Up"))
-sequence.append(utils.AssertPresentationAction(
-    "9. Line Up",
+    "7. Line Up",
     ["BRAILLE LINE:  'No abbreviation here either.'",
      "     VISIBLE:  'No abbreviation here either.', cursor=1",
      "SPEECH OUTPUT: 'No abbreviation here either.'"]))
@@ -87,7 +71,7 @@ sequence.append(utils.AssertPresentationAction(
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
 sequence.append(utils.AssertPresentationAction(
-    "10. Line Up",
+    "8. Line Up",
     ["BRAILLE LINE:  'HTML5 in 2004.'",
      "     VISIBLE:  'HTML5 in 2004.', cursor=1",
      "SPEECH OUTPUT: 'HTML5 in 2004.'"]))
@@ -95,7 +79,7 @@ sequence.append(utils.AssertPresentationAction(
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
 sequence.append(utils.AssertPresentationAction(
-    "11. Line Up",
+    "9. Line Up",
     ["BRAILLE LINE:  'WHATWG started working on'",
      "     VISIBLE:  'WHATWG started working on', cursor=1",
      "SPEECH OUTPUT: 'WHATWG'",
@@ -104,7 +88,7 @@ sequence.append(utils.AssertPresentationAction(
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
 sequence.append(utils.AssertPresentationAction(
-    "12. Line Up",
+    "10. Line Up",
     ["BRAILLE LINE:  'No abbreviation here.'",
      "     VISIBLE:  'No abbreviation here.', cursor=1",
      "SPEECH OUTPUT: 'No abbreviation here.'"]))
@@ -112,7 +96,7 @@ sequence.append(utils.AssertPresentationAction(
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
 sequence.append(utils.AssertPresentationAction(
-    "13. Line Up",
+    "11. Line Up",
     ["BRAILLE LINE:  'Line 1'",
      "     VISIBLE:  'Line 1', cursor=1",
      "SPEECH OUTPUT: 'Line 1'"]))
diff --git a/test/keystrokes/firefox/line_nav_image_in_link.py 
b/test/keystrokes/firefox/line_nav_image_in_link.py
index 34d1819..29edf09 100644
--- a/test/keystrokes/firefox/line_nav_image_in_link.py
+++ b/test/keystrokes/firefox/line_nav_image_in_link.py
@@ -25,8 +25,7 @@ sequence.append(utils.AssertPresentationAction(
     "2. Line Down",
     ["BRAILLE LINE:  'foo image'",
      "     VISIBLE:  'foo image', cursor=1",
-     "SPEECH OUTPUT: 'foo'",
-     "SPEECH OUTPUT: 'image link'"]))
+     "SPEECH OUTPUT: 'foo image link'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
@@ -35,8 +34,7 @@ sequence.append(utils.AssertPresentationAction(
     ["BRAILLE LINE:  ' Before Line After'",
      "     VISIBLE:  ' Before Line After', cursor=1",
      "SPEECH OUTPUT: 'Before'",
-     "SPEECH OUTPUT: 'Line'",
-     "SPEECH OUTPUT: 'link'",
+     "SPEECH OUTPUT: 'Line link'",
      "SPEECH OUTPUT: 'After'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -51,19 +49,24 @@ sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
 sequence.append(utils.AssertPresentationAction(
     "5. Line Up",
-    ["BRAILLE LINE:  'foo image Before Line After'",
-     "     VISIBLE:  'foo image Before Line After', cursor=1",
-     "SPEECH OUTPUT: 'foo'",
-     "SPEECH OUTPUT: 'image link'",
+    ["BRAILLE LINE:  ' Before Line After'",
+     "     VISIBLE:  ' Before Line After', cursor=1",
      "SPEECH OUTPUT: 'Before'",
-     "SPEECH OUTPUT: 'Line'",
-     "SPEECH OUTPUT: 'link'",
+     "SPEECH OUTPUT: 'Line link'",
      "SPEECH OUTPUT: 'After'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
 sequence.append(utils.AssertPresentationAction(
     "6. Line Up",
+    ["BRAILLE LINE:  'foo image'",
+     "     VISIBLE:  'foo image', cursor=1",
+     "SPEECH OUTPUT: 'foo image link'"]))
+
+sequence.append(utils.StartRecordingAction())
+sequence.append(KeyComboAction("Up"))
+sequence.append(utils.AssertPresentationAction(
+    "7. Line Up",
     ["BRAILLE LINE:  'Start'",
      "     VISIBLE:  'Start', cursor=1",
      "SPEECH OUTPUT: 'Start'"]))
diff --git a/test/keystrokes/firefox/line_nav_images_in_links.py 
b/test/keystrokes/firefox/line_nav_images_in_links.py
index e0b79e9..4584b99 100644
--- a/test/keystrokes/firefox/line_nav_images_in_links.py
+++ b/test/keystrokes/firefox/line_nav_images_in_links.py
@@ -76,8 +76,7 @@ sequence.append(utils.AssertPresentationAction(
     "8. Line Down",
     ["BRAILLE LINE:  'foo image'",
      "     VISIBLE:  'foo image', cursor=1",
-     "SPEECH OUTPUT: 'foo'",
-     "SPEECH OUTPUT: 'image link'"]))
+     "SPEECH OUTPUT: 'foo image link'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
@@ -93,10 +92,8 @@ sequence.append(utils.AssertPresentationAction(
     "10. Line Down",
     ["BRAILLE LINE:  'foo image foo image'",
      "     VISIBLE:  'foo image foo image', cursor=1",
-     "SPEECH OUTPUT: 'foo'",
-     "SPEECH OUTPUT: 'image link'",
-     "SPEECH OUTPUT: 'foo'",
-     "SPEECH OUTPUT: 'image link'"]))
+     "SPEECH OUTPUT: 'foo image'",
+     "SPEECH OUTPUT: 'foo image link'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
@@ -112,10 +109,8 @@ sequence.append(utils.AssertPresentationAction(
     "12. Line Down",
     ["BRAILLE LINE:  'foo image foo image'",
      "     VISIBLE:  'foo image foo image', cursor=1",
-     "SPEECH OUTPUT: 'foo'",
-     "SPEECH OUTPUT: 'image link'",
-     "SPEECH OUTPUT: 'foo'",
-     "SPEECH OUTPUT: 'image link'"]))
+     "SPEECH OUTPUT: 'foo image'",
+     "SPEECH OUTPUT: 'foo image link'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
@@ -131,9 +126,8 @@ sequence.append(utils.AssertPresentationAction(
     "14. Line Down",
     ["BRAILLE LINE:  'Orca logo image foo image'",
      "     VISIBLE:  'Orca logo image foo image', cursor=1",
-     "SPEECH OUTPUT: 'Orca logo image link'",
-     "SPEECH OUTPUT: 'foo'",
-     "SPEECH OUTPUT: 'image link'"]))
+     "SPEECH OUTPUT: 'Orca logo image'",
+     "SPEECH OUTPUT: 'foo image link'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
@@ -149,8 +143,7 @@ sequence.append(utils.AssertPresentationAction(
     "16. Line Down",
     ["BRAILLE LINE:  'foo image'",
      "     VISIBLE:  'foo image', cursor=1",
-     "SPEECH OUTPUT: 'foo'",
-     "SPEECH OUTPUT: 'image link'"]))
+     "SPEECH OUTPUT: 'foo image link'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
@@ -158,8 +151,7 @@ sequence.append(utils.AssertPresentationAction(
     "17. Line Down",
     ["BRAILLE LINE:  'silly link'",
      "     VISIBLE:  'silly link', cursor=1",
-     "SPEECH OUTPUT: 'silly link'",
-     "SPEECH OUTPUT: 'link image'"]))
+     "SPEECH OUTPUT: 'silly link link'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
@@ -167,8 +159,7 @@ sequence.append(utils.AssertPresentationAction(
     "18. Line Down",
     ["BRAILLE LINE:  'foo image'",
      "     VISIBLE:  'foo image', cursor=1",
-     "SPEECH OUTPUT: 'foo'",
-     "SPEECH OUTPUT: 'image link'"]))
+     "SPEECH OUTPUT: 'foo image link'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
@@ -195,10 +186,8 @@ sequence.append(utils.AssertPresentationAction(
     "21. Line Down",
     ["BRAILLE LINE:  'foo image foo image'",
      "     VISIBLE:  'foo image foo image', cursor=1",
-     "SPEECH OUTPUT: 'foo'",
-     "SPEECH OUTPUT: 'image link'",
-     "SPEECH OUTPUT: 'foo'",
-     "SPEECH OUTPUT: 'image link'"]))
+     "SPEECH OUTPUT: 'foo image'",
+     "SPEECH OUTPUT: 'foo image link'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
@@ -206,8 +195,7 @@ sequence.append(utils.AssertPresentationAction(
     "22. Line Down",
     ["BRAILLE LINE:  'After the paragraph'",
      "     VISIBLE:  'After the paragraph', cursor=1",
-     "SPEECH OUTPUT: 'After the paragraph'",
-     "SPEECH OUTPUT: 'link'"]))
+     "SPEECH OUTPUT: 'After the paragraph link'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
@@ -224,8 +212,7 @@ sequence.append(utils.AssertPresentationAction(
     ["BRAILLE LINE:  'the paragraph: Before the paragraph'",
      "     VISIBLE:  'the paragraph: Before the paragr', cursor=1",
      "SPEECH OUTPUT: 'the paragraph:'",
-     "SPEECH OUTPUT: 'Before the paragraph'",
-     "SPEECH OUTPUT: 'link'"]))
+     "SPEECH OUTPUT: 'Before the paragraph link'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
@@ -233,8 +220,7 @@ sequence.append(utils.AssertPresentationAction(
     "25. Line Down",
     ["BRAILLE LINE:  'foo image'",
      "     VISIBLE:  'foo image', cursor=1",
-     "SPEECH OUTPUT: 'foo'",
-     "SPEECH OUTPUT: 'image link'"]))
+     "SPEECH OUTPUT: 'foo image link'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
@@ -242,8 +228,7 @@ sequence.append(utils.AssertPresentationAction(
     "26. Line Down",
     ["BRAILLE LINE:  'silly link'",
      "     VISIBLE:  'silly link', cursor=1",
-     "SPEECH OUTPUT: 'silly link'",
-     "SPEECH OUTPUT: 'link image'"]))
+     "SPEECH OUTPUT: 'silly link link'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
@@ -251,8 +236,7 @@ sequence.append(utils.AssertPresentationAction(
     "27. Line Down",
     ["BRAILLE LINE:  'foo image'",
      "     VISIBLE:  'foo image', cursor=1",
-     "SPEECH OUTPUT: 'foo'",
-     "SPEECH OUTPUT: 'image link'"]))
+     "SPEECH OUTPUT: 'foo image link'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
@@ -260,8 +244,7 @@ sequence.append(utils.AssertPresentationAction(
     "28. Line Down",
     ["BRAILLE LINE:  'After the paragraph'",
      "     VISIBLE:  'After the paragraph', cursor=1",
-     "SPEECH OUTPUT: 'After the paragraph'",
-     "SPEECH OUTPUT: 'link'"]))
+     "SPEECH OUTPUT: 'After the paragraph link'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
@@ -269,8 +252,7 @@ sequence.append(utils.AssertPresentationAction(
     "29. Line Up",
     ["BRAILLE LINE:  'foo image'",
      "     VISIBLE:  'foo image', cursor=1",
-     "SPEECH OUTPUT: 'foo'",
-     "SPEECH OUTPUT: 'image link'"]))
+     "SPEECH OUTPUT: 'foo image link'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
@@ -278,8 +260,7 @@ sequence.append(utils.AssertPresentationAction(
     "30. Line Up",
     ["BRAILLE LINE:  'silly link'",
      "     VISIBLE:  'silly link', cursor=1",
-     "SPEECH OUTPUT: 'silly link'",
-     "SPEECH OUTPUT: 'link image'"]))
+     "SPEECH OUTPUT: 'silly link link'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
@@ -287,8 +268,7 @@ sequence.append(utils.AssertPresentationAction(
     "31. Line Up",
     ["BRAILLE LINE:  'foo image'",
      "     VISIBLE:  'foo image', cursor=1",
-     "SPEECH OUTPUT: 'foo'",
-     "SPEECH OUTPUT: 'image link'"]))
+     "SPEECH OUTPUT: 'foo image link'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
@@ -297,8 +277,7 @@ sequence.append(utils.AssertPresentationAction(
     ["BRAILLE LINE:  'the paragraph: Before the paragraph'",
      "     VISIBLE:  'the paragraph: Before the paragr', cursor=1",
      "SPEECH OUTPUT: 'the paragraph:'",
-     "SPEECH OUTPUT: 'Before the paragraph'",
-     "SPEECH OUTPUT: 'link'"]))
+     "SPEECH OUTPUT: 'Before the paragraph link'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
@@ -314,8 +293,7 @@ sequence.append(utils.AssertPresentationAction(
     "34. Line Up",
     ["BRAILLE LINE:  'After the paragraph'",
      "     VISIBLE:  'After the paragraph', cursor=1",
-     "SPEECH OUTPUT: 'After the paragraph'",
-     "SPEECH OUTPUT: 'link'"]))
+     "SPEECH OUTPUT: 'After the paragraph link'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
@@ -323,10 +301,8 @@ sequence.append(utils.AssertPresentationAction(
     "35. Line Up",
     ["BRAILLE LINE:  'foo image foo image'",
      "     VISIBLE:  'foo image foo image', cursor=1",
-     "SPEECH OUTPUT: 'foo'",
-     "SPEECH OUTPUT: 'image link'",
-     "SPEECH OUTPUT: 'foo'",
-     "SPEECH OUTPUT: 'image link'"]))
+     "SPEECH OUTPUT: 'foo image'",
+     "SPEECH OUTPUT: 'foo image link'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
@@ -353,8 +329,7 @@ sequence.append(utils.AssertPresentationAction(
     "38. Line Up",
     ["BRAILLE LINE:  'foo image'",
      "     VISIBLE:  'foo image', cursor=1",
-     "SPEECH OUTPUT: 'foo'",
-     "SPEECH OUTPUT: 'image link'"]))
+     "SPEECH OUTPUT: 'foo image link'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
@@ -362,8 +337,7 @@ sequence.append(utils.AssertPresentationAction(
     "39. Line Up",
     ["BRAILLE LINE:  'silly link'",
      "     VISIBLE:  'silly link', cursor=1",
-     "SPEECH OUTPUT: 'silly link'",
-     "SPEECH OUTPUT: 'link image'"]))
+     "SPEECH OUTPUT: 'silly link link'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
@@ -371,8 +345,7 @@ sequence.append(utils.AssertPresentationAction(
     "40. Line Up",
     ["BRAILLE LINE:  'foo image'",
      "     VISIBLE:  'foo image', cursor=1",
-     "SPEECH OUTPUT: 'foo'",
-     "SPEECH OUTPUT: 'image link'"]))
+     "SPEECH OUTPUT: 'foo image link'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
@@ -388,9 +361,8 @@ sequence.append(utils.AssertPresentationAction(
     "42. Line Up",
     ["BRAILLE LINE:  'Orca logo image foo image'",
      "     VISIBLE:  'Orca logo image foo image', cursor=1",
-     "SPEECH OUTPUT: 'Orca logo image link'",
-     "SPEECH OUTPUT: 'foo'",
-     "SPEECH OUTPUT: 'image link'"]))
+     "SPEECH OUTPUT: 'Orca logo image'",
+     "SPEECH OUTPUT: 'foo image link'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
@@ -406,10 +378,8 @@ sequence.append(utils.AssertPresentationAction(
     "44. Line Up",
     ["BRAILLE LINE:  'foo image foo image'",
      "     VISIBLE:  'foo image foo image', cursor=1",
-     "SPEECH OUTPUT: 'foo'",
-     "SPEECH OUTPUT: 'image link'",
-     "SPEECH OUTPUT: 'foo'",
-     "SPEECH OUTPUT: 'image link'"]))
+     "SPEECH OUTPUT: 'foo image'",
+     "SPEECH OUTPUT: 'foo image link'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
@@ -425,10 +395,8 @@ sequence.append(utils.AssertPresentationAction(
     "46. Line Up",
     ["BRAILLE LINE:  'foo image foo image'",
      "     VISIBLE:  'foo image foo image', cursor=1",
-     "SPEECH OUTPUT: 'foo'",
-     "SPEECH OUTPUT: 'image link'",
-     "SPEECH OUTPUT: 'foo'",
-     "SPEECH OUTPUT: 'image link'"]))
+     "SPEECH OUTPUT: 'foo image'",
+     "SPEECH OUTPUT: 'foo image link'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
@@ -444,8 +412,7 @@ sequence.append(utils.AssertPresentationAction(
     "48. Line Up",
     ["BRAILLE LINE:  'foo image'",
      "     VISIBLE:  'foo image', cursor=1",
-     "SPEECH OUTPUT: 'foo'",
-     "SPEECH OUTPUT: 'image link'"]))
+     "SPEECH OUTPUT: 'foo image link'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
diff --git a/test/keystrokes/firefox/line_nav_inline_block_spans.params 
b/test/keystrokes/firefox/line_nav_inline_block_spans.params
new file mode 100644
index 0000000..b957448
--- /dev/null
+++ b/test/keystrokes/firefox/line_nav_inline_block_spans.params
@@ -0,0 +1 @@
+PARAMS=$TEST_DIR/../../html/inline-block-spans.html
diff --git a/test/keystrokes/firefox/line_nav_inline_block_spans.py 
b/test/keystrokes/firefox/line_nav_inline_block_spans.py
new file mode 100644
index 0000000..ceedc4b
--- /dev/null
+++ b/test/keystrokes/firefox/line_nav_inline_block_spans.py
@@ -0,0 +1,55 @@
+#!/usr/bin/python
+
+"""Test of line navigation output of Firefox."""
+
+from macaroon.playback import *
+import utils
+
+sequence = MacroSequence()
+
+# Work around some new quirk in Gecko that causes this test to fail if
+# run via the test harness rather than manually.
+sequence.append(KeyComboAction("<Control>r"))
+
+sequence.append(utils.StartRecordingAction())
+sequence.append(KeyComboAction("<Control>Home"))
+sequence.append(utils.AssertPresentationAction(
+    "1. Top of file",
+    ["BRAILLE LINE:  'Line 1'",
+     "     VISIBLE:  'Line 1', cursor=1",
+     "SPEECH OUTPUT: 'Line 1'"]))
+
+sequence.append(utils.StartRecordingAction())
+sequence.append(KeyComboAction("Down"))
+sequence.append(utils.AssertPresentationAction(
+    "2. Line Down",
+    ["BRAILLE LINE:  'Line 2'",
+     "     VISIBLE:  'Line 2', cursor=1",
+     "SPEECH OUTPUT: 'Line 2'"]))
+
+sequence.append(utils.StartRecordingAction())
+sequence.append(KeyComboAction("Down"))
+sequence.append(utils.AssertPresentationAction(
+    "3. Line Down",
+    ["BRAILLE LINE:  'Line 3'",
+     "     VISIBLE:  'Line 3', cursor=1",
+     "SPEECH OUTPUT: 'Line 3'"]))
+
+sequence.append(utils.StartRecordingAction())
+sequence.append(KeyComboAction("Up"))
+sequence.append(utils.AssertPresentationAction(
+    "4. Line Up",
+    ["BRAILLE LINE:  'Line 2'",
+     "     VISIBLE:  'Line 2', cursor=1",
+     "SPEECH OUTPUT: 'Line 2'"]))
+
+sequence.append(utils.StartRecordingAction())
+sequence.append(KeyComboAction("Up"))
+sequence.append(utils.AssertPresentationAction(
+    "5. Line Up",
+    ["BRAILLE LINE:  'Line 1'",
+     "     VISIBLE:  'Line 1', cursor=1",
+     "SPEECH OUTPUT: 'Line 1'"]))
+
+sequence.append(utils.AssertionSummaryAction())
+sequence.start()
diff --git a/test/keystrokes/firefox/line_nav_link_position_relative_on_focus.py 
b/test/keystrokes/firefox/line_nav_link_position_relative_on_focus.py
index 5d3320b..57d539b 100644
--- a/test/keystrokes/firefox/line_nav_link_position_relative_on_focus.py
+++ b/test/keystrokes/firefox/line_nav_link_position_relative_on_focus.py
@@ -23,8 +23,7 @@ sequence.append(utils.AssertPresentationAction(
     "2. Line Down",
     ["BRAILLE LINE:  'Line 2'",
      "     VISIBLE:  'Line 2', cursor=1",
-     "SPEECH OUTPUT: 'Line 2'",
-     "SPEECH OUTPUT: 'link'"]))
+     "SPEECH OUTPUT: 'Line 2 link'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
@@ -40,8 +39,7 @@ sequence.append(utils.AssertPresentationAction(
     "4. Line Up",
     ["BRAILLE LINE:  'Line 2'",
      "     VISIBLE:  'Line 2', cursor=1",
-     "SPEECH OUTPUT: 'Line 2'",
-     "SPEECH OUTPUT: 'link'"]))
+     "SPEECH OUTPUT: 'Line 2 link'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
diff --git a/test/keystrokes/firefox/line_nav_multi_line_text.py 
b/test/keystrokes/firefox/line_nav_multi_line_text.py
index 975b0b8..07fc515 100644
--- a/test/keystrokes/firefox/line_nav_multi_line_text.py
+++ b/test/keystrokes/firefox/line_nav_multi_line_text.py
@@ -75,8 +75,7 @@ sequence.append(utils.AssertPresentationAction(
     ["BRAILLE LINE:  '• This is a test that is not very interesting.'",
      "     VISIBLE:  '• This is a test that is not ver', cursor=1",
      "SPEECH OUTPUT: '•'",
-     "SPEECH OUTPUT: 'This is a test'",
-     "SPEECH OUTPUT: 'link'",
+     "SPEECH OUTPUT: 'This is a test link'",
      "SPEECH OUTPUT: 'that is not very interesting.'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -86,8 +85,7 @@ sequence.append(utils.AssertPresentationAction(
     ["BRAILLE LINE:  '• But it looks like a real-world example.'",
      "     VISIBLE:  '• But it looks like a real-world', cursor=1",
      "SPEECH OUTPUT: '•'",
-     "SPEECH OUTPUT: 'But it looks like'",
-     "SPEECH OUTPUT: 'link'",
+     "SPEECH OUTPUT: 'But it looks like link'",
      "SPEECH OUTPUT: 'a real-world example.'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -97,8 +95,7 @@ sequence.append(utils.AssertPresentationAction(
     ["BRAILLE LINE:  '• And that's why this silly test is here.'",
      "     VISIBLE:  '• And that's why this silly test', cursor=1",
      "SPEECH OUTPUT: '•'",
-     "SPEECH OUTPUT: 'And that's'",
-     "SPEECH OUTPUT: 'link'",
+     "SPEECH OUTPUT: 'And that's link'",
      "SPEECH OUTPUT: 'why this silly test is here.'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -108,8 +105,7 @@ sequence.append(utils.AssertPresentationAction(
     ["BRAILLE LINE:  'So it's far more interesting than it looks.'",
      "     VISIBLE:  'So it's far more interesting tha', cursor=1",
      "SPEECH OUTPUT: 'So it's'",
-     "SPEECH OUTPUT: 'far more interesting'",
-     "SPEECH OUTPUT: 'link'",
+     "SPEECH OUTPUT: 'far more interesting link'",
      "SPEECH OUTPUT: 'than it looks.'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -127,8 +123,7 @@ sequence.append(utils.AssertPresentationAction(
     ["BRAILLE LINE:  '• The thing is we can't copy content.'",
      "     VISIBLE:  '• The thing is we can't copy con', cursor=1",
      "SPEECH OUTPUT: '•'",
-     "SPEECH OUTPUT: 'The thing is'",
-     "SPEECH OUTPUT: 'link'",
+     "SPEECH OUTPUT: 'The thing is link'",
      "SPEECH OUTPUT: 'we can't copy content.'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -138,8 +133,7 @@ sequence.append(utils.AssertPresentationAction(
     ["BRAILLE LINE:  '• So we must create silly tests.'",
      "     VISIBLE:  '• So we must create silly tests.', cursor=1",
      "SPEECH OUTPUT: '•'",
-     "SPEECH OUTPUT: 'So we must'",
-     "SPEECH OUTPUT: 'link'",
+     "SPEECH OUTPUT: 'So we must link'",
      "SPEECH OUTPUT: 'create silly tests.'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -149,8 +143,7 @@ sequence.append(utils.AssertPresentationAction(
     ["BRAILLE LINE:  '• Oh well.'",
      "     VISIBLE:  '• Oh well.', cursor=1",
      "SPEECH OUTPUT: '•'",
-     "SPEECH OUTPUT: 'Oh'",
-     "SPEECH OUTPUT: 'link'",
+     "SPEECH OUTPUT: 'Oh link'",
      "SPEECH OUTPUT: 'well.'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -160,8 +153,7 @@ sequence.append(utils.AssertPresentationAction(
     ["BRAILLE LINE:  'At least it's over.'",
      "     VISIBLE:  'At least it's over.', cursor=1",
      "SPEECH OUTPUT: 'At least it's",
-     "SPEECH OUTPUT: 'over'",
-     "SPEECH OUTPUT: 'link'",
+     "SPEECH OUTPUT: 'over link'",
      "SPEECH OUTPUT: '.'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -171,8 +163,7 @@ sequence.append(utils.AssertPresentationAction(
     ["BRAILLE LINE:  '• Oh well.'",
      "     VISIBLE:  '• Oh well.', cursor=1",
      "SPEECH OUTPUT: '•'",
-     "SPEECH OUTPUT: 'Oh'",
-     "SPEECH OUTPUT: 'link'",
+     "SPEECH OUTPUT: 'Oh link'",
      "SPEECH OUTPUT: 'well.'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -182,8 +173,7 @@ sequence.append(utils.AssertPresentationAction(
     ["BRAILLE LINE:  '• So we must create silly tests.'",
      "     VISIBLE:  '• So we must create silly tests.', cursor=1",
      "SPEECH OUTPUT: '•'",
-     "SPEECH OUTPUT: 'So we must'",
-     "SPEECH OUTPUT: 'link'",
+     "SPEECH OUTPUT: 'So we must link'",
      "SPEECH OUTPUT: 'create silly tests.'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -193,8 +183,7 @@ sequence.append(utils.AssertPresentationAction(
     ["BRAILLE LINE:  '• The thing is we can't copy content.'",
      "     VISIBLE:  '• The thing is we can't copy con', cursor=1",
      "SPEECH OUTPUT: '•'",
-     "SPEECH OUTPUT: 'The thing is'",
-     "SPEECH OUTPUT: 'link'",
+     "SPEECH OUTPUT: 'The thing is link'",
      "SPEECH OUTPUT: 'we can't copy content.'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -212,8 +201,7 @@ sequence.append(utils.AssertPresentationAction(
     ["BRAILLE LINE:  'So it's far more interesting than it looks.'",
      "     VISIBLE:  'So it's far more interesting tha', cursor=1",
      "SPEECH OUTPUT: 'So it's'",
-     "SPEECH OUTPUT: 'far more interesting'",
-     "SPEECH OUTPUT: 'link'",
+     "SPEECH OUTPUT: 'far more interesting link'",
      "SPEECH OUTPUT: 'than it looks.'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -223,8 +211,7 @@ sequence.append(utils.AssertPresentationAction(
     ["BRAILLE LINE:  '• And that's why this silly test is here.'",
      "     VISIBLE:  '• And that's why this silly test', cursor=1",
      "SPEECH OUTPUT: '•'",
-     "SPEECH OUTPUT: 'And that's'",
-     "SPEECH OUTPUT: 'link'",
+     "SPEECH OUTPUT: 'And that's link'",
      "SPEECH OUTPUT: 'why this silly test is here.'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -234,8 +221,7 @@ sequence.append(utils.AssertPresentationAction(
     ["BRAILLE LINE:  '• But it looks like a real-world example.'",
      "     VISIBLE:  '• But it looks like a real-world', cursor=1",
      "SPEECH OUTPUT: '•'",
-     "SPEECH OUTPUT: 'But it looks like'",
-     "SPEECH OUTPUT: 'link'",
+     "SPEECH OUTPUT: 'But it looks like link'",
      "SPEECH OUTPUT: 'a real-world example.'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -245,8 +231,7 @@ sequence.append(utils.AssertPresentationAction(
     ["BRAILLE LINE:  '• This is a test that is not very interesting.'",
      "     VISIBLE:  '• This is a test that is not ver', cursor=1",
      "SPEECH OUTPUT: '•'",
-     "SPEECH OUTPUT: 'This is a test'",
-     "SPEECH OUTPUT: 'link'",
+     "SPEECH OUTPUT: 'This is a test link'",
      "SPEECH OUTPUT: 'that is not very interesting.'"]))
 
 sequence.append(utils.StartRecordingAction())
diff --git a/test/keystrokes/firefox/line_nav_nested_tables.py 
b/test/keystrokes/firefox/line_nav_nested_tables.py
index 1af17a0..cbbd06d 100644
--- a/test/keystrokes/firefox/line_nav_nested_tables.py
+++ b/test/keystrokes/firefox/line_nav_nested_tables.py
@@ -17,8 +17,7 @@ sequence.append(utils.AssertPresentationAction(
     "1. Top of file",
     ["BRAILLE LINE:  'nested-tables image'",
      "     VISIBLE:  'nested-tables image', cursor=1",
-     "SPEECH OUTPUT: 'nested-tables'",
-     "SPEECH OUTPUT: 'image link'"]))
+     "SPEECH OUTPUT: 'nested-tables image link'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
@@ -26,17 +25,13 @@ sequence.append(utils.AssertPresentationAction(
     "2. line Down",
     ["BRAILLE LINE:  'Campus  .  Classroom  .  Communicate  .  Reports'",
      "     VISIBLE:  'Campus  .  Classroom  .  Communi', cursor=1",
-     "SPEECH OUTPUT: 'Campus'",
-     "SPEECH OUTPUT: 'link'",
+     "SPEECH OUTPUT: 'Campus link'",
      "SPEECH OUTPUT: '.'",
-     "SPEECH OUTPUT: 'Classroom'",
-     "SPEECH OUTPUT: 'link'",
+     "SPEECH OUTPUT: 'Classroom link'",
      "SPEECH OUTPUT: '.'",
-     "SPEECH OUTPUT: 'Communicate'",
-     "SPEECH OUTPUT: 'link'",
+     "SPEECH OUTPUT: 'Communicate link'",
      "SPEECH OUTPUT: '.'",
-     "SPEECH OUTPUT: 'Reports'",
-     "SPEECH OUTPUT: 'link'"]))
+     "SPEECH OUTPUT: 'Reports link'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
@@ -66,39 +61,14 @@ sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
 sequence.append(utils.AssertPresentationAction(
     "6. line Down",
-    ["BRAILLE LINE:  ''",
-     "     VISIBLE:  '', cursor=1",
-     "SPEECH OUTPUT: 'blank'"]))
-
-sequence.append(utils.StartRecordingAction())
-sequence.append(KeyComboAction("Down"))
-sequence.append(utils.AssertPresentationAction(
-    "7. line Down",
     ["BRAILLE LINE:  'Take Course'",
      "     VISIBLE:  'Take Course', cursor=1",
-     "SPEECH OUTPUT: 'Take Course'",
-     "SPEECH OUTPUT: 'link'"]))
+     "SPEECH OUTPUT: 'Take Course link'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
 sequence.append(utils.AssertPresentationAction(
-    "8. line Down",
-    ["BRAILLE LINE:  ''",
-     "     VISIBLE:  '', cursor=1",
-     "SPEECH OUTPUT: 'blank'"]))
-
-sequence.append(utils.StartRecordingAction())
-sequence.append(KeyComboAction("Down"))
-sequence.append(utils.AssertPresentationAction(
-    "9. line Down",
-    ["BRAILLE LINE:  ''",
-     "     VISIBLE:  '', cursor=1",
-     "SPEECH OUTPUT: 'blank'"]))
-
-sequence.append(utils.StartRecordingAction())
-sequence.append(KeyComboAction("Down"))
-sequence.append(utils.AssertPresentationAction(
-    "10. line Down",
+    "7. line Down",
     ["BRAILLE LINE:  'You have completed 87 of the 87 modules in this course.'",
      "     VISIBLE:  'You have completed 87 of the 87 ', cursor=1",
      "SPEECH OUTPUT: 'You have completed 87 of the 87 modules in this course.'"]))
@@ -106,7 +76,7 @@ sequence.append(utils.AssertPresentationAction(
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
 sequence.append(utils.AssertPresentationAction(
-    "11. line Down",
+    "8. line Down",
     ["BRAILLE LINE:  'separator'",
      "     VISIBLE:  'separator', cursor=1",
      "SPEECH OUTPUT: 'separator'"]))
@@ -114,7 +84,7 @@ sequence.append(utils.AssertPresentationAction(
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
 sequence.append(utils.AssertPresentationAction(
-    "12. line Down",
+    "9. line Down",
     ["BRAILLE LINE:  'SQL Plus'",
      "     VISIBLE:  'SQL Plus', cursor=1",
      "SPEECH OUTPUT: 'SQL Plus'"]))
@@ -122,40 +92,15 @@ sequence.append(utils.AssertPresentationAction(
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
 sequence.append(utils.AssertPresentationAction(
-    "13. line Down",
-    ["BRAILLE LINE:  ''",
-     "     VISIBLE:  '', cursor=1",
-     "SPEECH OUTPUT: 'blank'"]))
-
-sequence.append(utils.StartRecordingAction())
-sequence.append(KeyComboAction("Down"))
-sequence.append(utils.AssertPresentationAction(
-    "14. line Down",
+    "10. line Down",
     ["BRAILLE LINE:  'Take Course'",
      "     VISIBLE:  'Take Course', cursor=1",
-     "SPEECH OUTPUT: 'Take Course'",
-     "SPEECH OUTPUT: 'link'"]))
-
-sequence.append(utils.StartRecordingAction())
-sequence.append(KeyComboAction("Down"))
-sequence.append(utils.AssertPresentationAction(
-    "15. line Down",
-    ["BRAILLE LINE:  ''",
-     "     VISIBLE:  '', cursor=1",
-     "SPEECH OUTPUT: 'blank'"]))
-
-sequence.append(utils.StartRecordingAction())
-sequence.append(KeyComboAction("Down"))
-sequence.append(utils.AssertPresentationAction(
-    "16. line Down",
-    ["BRAILLE LINE:  ''",
-     "     VISIBLE:  '', cursor=1",
-     "SPEECH OUTPUT: 'blank'"]))
+     "SPEECH OUTPUT: 'Take Course link'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
 sequence.append(utils.AssertPresentationAction(
-    "17. line Down",
+    "11. line Down",
     ["BRAILLE LINE:  'You have completed 59 of the 184 modules in this course.'",
      "     VISIBLE:  'You have completed 59 of the 184', cursor=1",
      "SPEECH OUTPUT: 'You have completed 59 of the 184 modules in this course.'"]))
@@ -163,7 +108,7 @@ sequence.append(utils.AssertPresentationAction(
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
 sequence.append(utils.AssertPresentationAction(
-    "18. line Down",
+    "12. line Down",
     ["BRAILLE LINE:  'separator'",
      "     VISIBLE:  'separator', cursor=1",
      "SPEECH OUTPUT: 'separator'"]))
@@ -171,7 +116,7 @@ sequence.append(utils.AssertPresentationAction(
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
 sequence.append(utils.AssertPresentationAction(
-    "19. line Up",
+    "13. line Up",
     ["BRAILLE LINE:  'You have completed 59 of the 184 modules in this course.'",
      "     VISIBLE:  'You have completed 59 of the 184', cursor=1",
      "SPEECH OUTPUT: 'You have completed 59 of the 184 modules in this course.'"]))
@@ -179,48 +124,15 @@ sequence.append(utils.AssertPresentationAction(
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
 sequence.append(utils.AssertPresentationAction(
-    "20. line Up",
-    ["BRAILLE LINE:  ''",
-     "     VISIBLE:  '', cursor=1",
-     "SPEECH OUTPUT: 'blank'"]))
-
-sequence.append(utils.StartRecordingAction())
-sequence.append(KeyComboAction("Up"))
-sequence.append(utils.AssertPresentationAction(
-    "21. line Up",
-    ["BRAILLE LINE:  ''",
-     "     VISIBLE:  '', cursor=1",
-     "SPEECH OUTPUT: 'blank'"]))
-
-sequence.append(utils.StartRecordingAction())
-sequence.append(KeyComboAction("Up"))
-sequence.append(utils.AssertPresentationAction(
-    "22. line Up",
+    "14. line Up",
     ["BRAILLE LINE:  'Take Course'",
      "     VISIBLE:  'Take Course', cursor=1",
-     "SPEECH OUTPUT: 'Take Course'",
-     "SPEECH OUTPUT: 'link'"]))
+     "SPEECH OUTPUT: 'Take Course link'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
 sequence.append(utils.AssertPresentationAction(
-    "23. line Up",
-    ["BRAILLE LINE:  ''",
-     "     VISIBLE:  '', cursor=1",
-     "SPEECH OUTPUT: 'blank'"]))
-
-sequence.append(utils.StartRecordingAction())
-sequence.append(KeyComboAction("Up"))
-sequence.append(utils.AssertPresentationAction(
-    "24. line Up",
-    ["BRAILLE LINE:  ' '",
-     "     VISIBLE:  ' ', cursor=1",
-     "SPEECH OUTPUT: 'blank'"]))
-
-sequence.append(utils.StartRecordingAction())
-sequence.append(KeyComboAction("Up"))
-sequence.append(utils.AssertPresentationAction(
-    "25. line Up",
+    "15. line Up",
     ["BRAILLE LINE:  'SQL Plus'",
      "     VISIBLE:  'SQL Plus', cursor=1",
      "SPEECH OUTPUT: 'SQL Plus'"]))
@@ -228,7 +140,7 @@ sequence.append(utils.AssertPresentationAction(
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
 sequence.append(utils.AssertPresentationAction(
-    "26. line Up",
+    "16. line Up",
     ["BRAILLE LINE:  'separator'",
      "     VISIBLE:  'separator', cursor=1",
      "SPEECH OUTPUT: 'separator'"]))
@@ -236,7 +148,7 @@ sequence.append(utils.AssertPresentationAction(
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
 sequence.append(utils.AssertPresentationAction(
-    "27. line Up",
+    "17. line Up",
     ["BRAILLE LINE:  'You have completed 87 of the 87 modules in this course.'",
      "     VISIBLE:  'You have completed 87 of the 87 ', cursor=1",
      "SPEECH OUTPUT: 'You have completed 87 of the 87 modules in this course.'"]))
@@ -244,48 +156,15 @@ sequence.append(utils.AssertPresentationAction(
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
 sequence.append(utils.AssertPresentationAction(
-    "28. line Up",
-    ["BRAILLE LINE:  ''",
-     "     VISIBLE:  '', cursor=1",
-     "SPEECH OUTPUT: 'blank'"]))
-
-sequence.append(utils.StartRecordingAction())
-sequence.append(KeyComboAction("Up"))
-sequence.append(utils.AssertPresentationAction(
-    "29. line Up",
-    ["BRAILLE LINE:  ''",
-     "     VISIBLE:  '', cursor=1",
-     "SPEECH OUTPUT: 'blank'"]))
-
-sequence.append(utils.StartRecordingAction())
-sequence.append(KeyComboAction("Up"))
-sequence.append(utils.AssertPresentationAction(
-    "30. line Up",
+    "18. line Up",
     ["BRAILLE LINE:  'Take Course'",
      "     VISIBLE:  'Take Course', cursor=1",
-     "SPEECH OUTPUT: 'Take Course'",
-     "SPEECH OUTPUT: 'link'"]))
-
-sequence.append(utils.StartRecordingAction())
-sequence.append(KeyComboAction("Up"))
-sequence.append(utils.AssertPresentationAction(
-    "31. line Up",
-    ["BRAILLE LINE:  ''",
-     "     VISIBLE:  '', cursor=1",
-     "SPEECH OUTPUT: 'blank'"]))
-
-sequence.append(utils.StartRecordingAction())
-sequence.append(KeyComboAction("Up"))
-sequence.append(utils.AssertPresentationAction(
-    "32. line Up",
-    ["BRAILLE LINE:  ' '",
-     "     VISIBLE:  ' ', cursor=1",
-     "SPEECH OUTPUT: 'blank'"]))
+     "SPEECH OUTPUT: 'Take Course link'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
 sequence.append(utils.AssertPresentationAction(
-    "33. line Up",
+    "19. line Up",
     ["BRAILLE LINE:  'UNIX 2007'",
      "     VISIBLE:  'UNIX 2007', cursor=1",
      "SPEECH OUTPUT: 'UNIX 2007'"]))
@@ -293,15 +172,7 @@ sequence.append(utils.AssertPresentationAction(
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
 sequence.append(utils.AssertPresentationAction(
-    "34. line Up",
-    ["BRAILLE LINE:  '   $l'",
-     "     VISIBLE:  '   $l', cursor=1",
-     "SPEECH OUTPUT: 'blank'"]))
-
-sequence.append(utils.StartRecordingAction())
-sequence.append(KeyComboAction("Up"))
-sequence.append(utils.AssertPresentationAction(
-    "35. line Up",
+    "20. line Up",
     ["BRAILLE LINE:  'Below is a list of the courses that make up your learning plan.'",
      "     VISIBLE:  'Below is a list of the courses t', cursor=1",
      "SPEECH OUTPUT: 'Below is a list of the courses that make up your learning plan.'"]))
@@ -309,7 +180,7 @@ sequence.append(utils.AssertPresentationAction(
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
 sequence.append(utils.AssertPresentationAction(
-    "36. line Up",
+    "21. line Up",
     ["BRAILLE LINE:  'Your Learning Plan'",
      "     VISIBLE:  'Your Learning Plan', cursor=1",
      "SPEECH OUTPUT: 'Your Learning Plan'"]))
@@ -317,29 +188,24 @@ sequence.append(utils.AssertPresentationAction(
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
 sequence.append(utils.AssertPresentationAction(
-    "37. line Up",
+    "22. line Up",
     ["BRAILLE LINE:  'Campus  .  Classroom  .  Communicate  .  Reports'",
      "     VISIBLE:  'Campus  .  Classroom  .  Communi', cursor=1",
-     "SPEECH OUTPUT: 'Campus'",
-     "SPEECH OUTPUT: 'link'",
+     "SPEECH OUTPUT: 'Campus link'",
      "SPEECH OUTPUT: '.'",
-     "SPEECH OUTPUT: 'Classroom'",
-     "SPEECH OUTPUT: 'link'",
+     "SPEECH OUTPUT: 'Classroom link'",
      "SPEECH OUTPUT: '.'",
-     "SPEECH OUTPUT: 'Communicate'",
-     "SPEECH OUTPUT: 'link'",
+     "SPEECH OUTPUT: 'Communicate link'",
      "SPEECH OUTPUT: '.'",
-     "SPEECH OUTPUT: 'Reports'",
-     "SPEECH OUTPUT: 'link'"]))
+     "SPEECH OUTPUT: 'Reports link'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
 sequence.append(utils.AssertPresentationAction(
-    "38. line Up",
+    "23. line Up",
     ["BRAILLE LINE:  'nested-tables image'",
      "     VISIBLE:  'nested-tables image', cursor=1",
-     "SPEECH OUTPUT: 'nested-tables'",
-     "SPEECH OUTPUT: 'image link'"]))
+     "SPEECH OUTPUT: 'nested-tables image link'"]))
 
 sequence.append(utils.AssertionSummaryAction())
 sequence.start()
diff --git a/test/keystrokes/firefox/line_nav_paragraphs_in_links.params 
b/test/keystrokes/firefox/line_nav_paragraphs_in_links.params
new file mode 100644
index 0000000..b70796f
--- /dev/null
+++ b/test/keystrokes/firefox/line_nav_paragraphs_in_links.params
@@ -0,0 +1 @@
+PARAMS=$TEST_DIR/../../html/paragraphs-in-links.html
diff --git a/test/keystrokes/firefox/line_nav_paragraphs_in_links.py 
b/test/keystrokes/firefox/line_nav_paragraphs_in_links.py
new file mode 100644
index 0000000..d552c04
--- /dev/null
+++ b/test/keystrokes/firefox/line_nav_paragraphs_in_links.py
@@ -0,0 +1,71 @@
+#!/usr/bin/python
+
+"""Test of line navigation."""
+
+from macaroon.playback import *
+import utils
+
+sequence = MacroSequence()
+
+# Work around some new quirk in Gecko that causes this test to fail if
+# run via the test harness rather than manually.
+sequence.append(KeyComboAction("<Control>r"))
+
+sequence.append(utils.StartRecordingAction())
+sequence.append(KeyComboAction("<Control>Home"))
+sequence.append(utils.AssertPresentationAction(
+    "1. Top of file",
+    ["BRAILLE LINE:  'Hello world'",
+     "     VISIBLE:  'Hello world', cursor=1",
+     "SPEECH OUTPUT: 'Hello world'"]))
+
+sequence.append(utils.StartRecordingAction())
+sequence.append(KeyComboAction("Down"))
+sequence.append(utils.AssertPresentationAction(
+    "2. Line Down",
+    ["BRAILLE LINE:  'Paragraph 1'",
+     "     VISIBLE:  'Paragraph 1', cursor=1",
+     "SPEECH OUTPUT: 'link Paragraph 1'"]))
+
+sequence.append(utils.StartRecordingAction())
+sequence.append(KeyComboAction("Down"))
+sequence.append(utils.AssertPresentationAction(
+    "3. Line Down",
+    ["BRAILLE LINE:  'Paragraph 2'",
+     "     VISIBLE:  'Paragraph 2', cursor=1",
+     "SPEECH OUTPUT: 'link Paragraph 2'"]))
+
+sequence.append(utils.StartRecordingAction())
+sequence.append(KeyComboAction("Down"))
+sequence.append(utils.AssertPresentationAction(
+    "4. Line Down",
+    ["BRAILLE LINE:  'Goodbye world'",
+     "     VISIBLE:  'Goodbye world', cursor=1",
+     "SPEECH OUTPUT: 'Goodbye world'"]))
+
+sequence.append(utils.StartRecordingAction())
+sequence.append(KeyComboAction("Up"))
+sequence.append(utils.AssertPresentationAction(
+    "5. Line Up",
+    ["BRAILLE LINE:  'Paragraph 2'",
+     "     VISIBLE:  'Paragraph 2', cursor=1",
+     "SPEECH OUTPUT: 'link Paragraph 2'"]))
+
+sequence.append(utils.StartRecordingAction())
+sequence.append(KeyComboAction("Up"))
+sequence.append(utils.AssertPresentationAction(
+    "6. Line Up",
+    ["BRAILLE LINE:  'Paragraph 1'",
+     "     VISIBLE:  'Paragraph 1', cursor=1",
+     "SPEECH OUTPUT: 'link Paragraph 1'"]))
+
+sequence.append(utils.StartRecordingAction())
+sequence.append(KeyComboAction("Up"))
+sequence.append(utils.AssertPresentationAction(
+    "7. Line Up",
+    ["BRAILLE LINE:  'Hello world'",
+     "     VISIBLE:  'Hello world', cursor=1",
+     "SPEECH OUTPUT: 'Hello world'"]))
+
+sequence.append(utils.AssertionSummaryAction())
+sequence.start()
diff --git a/test/keystrokes/firefox/line_nav_pre_lines.py b/test/keystrokes/firefox/line_nav_pre_lines.py
index eee861e..e4c5296 100644
--- a/test/keystrokes/firefox/line_nav_pre_lines.py
+++ b/test/keystrokes/firefox/line_nav_pre_lines.py
@@ -23,22 +23,6 @@ sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
 sequence.append(utils.AssertPresentationAction(
     "2. Line Down",
-    ["BRAILLE LINE:  ' $l'",
-     "     VISIBLE:  ' $l', cursor=1",
-     "SPEECH OUTPUT: 'blank'"]))
-
-sequence.append(utils.StartRecordingAction())
-sequence.append(KeyComboAction("Down"))
-sequence.append(utils.AssertPresentationAction(
-    "3. Line Down",
-    ["BRAILLE LINE:  ' $l'",
-     "     VISIBLE:  ' $l', cursor=1",
-     "SPEECH OUTPUT: 'blank'"]))
-
-sequence.append(utils.StartRecordingAction())
-sequence.append(KeyComboAction("Down"))
-sequence.append(utils.AssertPresentationAction(
-    "4. Line Down",
     ["BRAILLE LINE:  'line 1'",
      "     VISIBLE:  'line 1', cursor=1",
      "SPEECH OUTPUT: 'line 1'"]))
@@ -46,7 +30,7 @@ sequence.append(utils.AssertPresentationAction(
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
 sequence.append(utils.AssertPresentationAction(
-    "5. Line Down",
+    "3. Line Down",
     ["BRAILLE LINE:  'line 2'",
      "     VISIBLE:  'line 2', cursor=1",
      "SPEECH OUTPUT: 'line 2'"]))
@@ -54,7 +38,7 @@ sequence.append(utils.AssertPresentationAction(
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
 sequence.append(utils.AssertPresentationAction(
-    "6. Line Down",
+    "4. Line Down",
     ["BRAILLE LINE:  'line 3'",
      "     VISIBLE:  'line 3', cursor=1",
      "SPEECH OUTPUT: 'line 3'"]))
@@ -62,7 +46,7 @@ sequence.append(utils.AssertPresentationAction(
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
 sequence.append(utils.AssertPresentationAction(
-    "7. Line Down",
+    "5. Line Down",
     ["BRAILLE LINE:  'line 4'",
      "     VISIBLE:  'line 4', cursor=1",
      "SPEECH OUTPUT: 'line 4'"]))
@@ -70,15 +54,7 @@ sequence.append(utils.AssertPresentationAction(
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
 sequence.append(utils.AssertPresentationAction(
-    "8. Line Down",
-    ["BRAILLE LINE:  ' $l'",
-     "     VISIBLE:  ' $l', cursor=1",
-     "SPEECH OUTPUT: 'blank'"]))
-
-sequence.append(utils.StartRecordingAction())
-sequence.append(KeyComboAction("Down"))
-sequence.append(utils.AssertPresentationAction(
-    "9. Line Down",
+    "6. Line Down",
     ["BRAILLE LINE:  'End'",
      "     VISIBLE:  'End', cursor=1",
      "SPEECH OUTPUT: 'End'"]))
@@ -86,23 +62,7 @@ sequence.append(utils.AssertPresentationAction(
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
 sequence.append(utils.AssertPresentationAction(
-    "10. Line Up",
-    ["BRAILLE LINE:  ' $l'",
-     "     VISIBLE:  ' $l', cursor=1",
-     "SPEECH OUTPUT: 'blank'"]))
-
-sequence.append(utils.StartRecordingAction())
-sequence.append(KeyComboAction("Up"))
-sequence.append(utils.AssertPresentationAction(
-    "11. Line Up",
-    ["BRAILLE LINE:  ' $l'",
-     "     VISIBLE:  ' $l', cursor=1",
-     "SPEECH OUTPUT: 'blank'"]))
-
-sequence.append(utils.StartRecordingAction())
-sequence.append(KeyComboAction("Up"))
-sequence.append(utils.AssertPresentationAction(
-    "12. Line Up",
+    "7. Line Up",
     ["BRAILLE LINE:  'line 4'",
      "     VISIBLE:  'line 4', cursor=1",
      "SPEECH OUTPUT: 'line 4'"]))
@@ -110,7 +70,7 @@ sequence.append(utils.AssertPresentationAction(
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
 sequence.append(utils.AssertPresentationAction(
-    "13. Line Up",
+    "8. Line Up",
     ["BRAILLE LINE:  'line 3'",
      "     VISIBLE:  'line 3', cursor=1",
      "SPEECH OUTPUT: 'line 3'"]))
@@ -118,7 +78,7 @@ sequence.append(utils.AssertPresentationAction(
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
 sequence.append(utils.AssertPresentationAction(
-    "14. Line Up",
+    "9. Line Up",
     ["BRAILLE LINE:  'line 2'",
      "     VISIBLE:  'line 2', cursor=1",
      "SPEECH OUTPUT: 'line 2'"]))
@@ -126,7 +86,7 @@ sequence.append(utils.AssertPresentationAction(
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
 sequence.append(utils.AssertPresentationAction(
-    "15. Line Up",
+    "10. Line Up",
     ["BRAILLE LINE:  'line 1'",
      "     VISIBLE:  'line 1', cursor=1",
      "SPEECH OUTPUT: 'line 1'"]))
@@ -134,23 +94,7 @@ sequence.append(utils.AssertPresentationAction(
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
 sequence.append(utils.AssertPresentationAction(
-    "16. Line Up",
-    ["BRAILLE LINE:  ' $l'",
-     "     VISIBLE:  ' $l', cursor=1",
-     "SPEECH OUTPUT: 'blank'"]))
-
-sequence.append(utils.StartRecordingAction())
-sequence.append(KeyComboAction("Up"))
-sequence.append(utils.AssertPresentationAction(
-    "17. Line Up",
-    ["BRAILLE LINE:  ' $l'",
-     "     VISIBLE:  ' $l', cursor=1",
-     "SPEECH OUTPUT: 'blank'"]))
-
-sequence.append(utils.StartRecordingAction())
-sequence.append(KeyComboAction("Up"))
-sequence.append(utils.AssertPresentationAction(
-    "18. Line Up",
+    "11. Line Up",
     ["BRAILLE LINE:  'Start'",
      "     VISIBLE:  'Start', cursor=1",
      "SPEECH OUTPUT: 'Start'"]))
diff --git a/test/keystrokes/firefox/line_nav_pre_links.py b/test/keystrokes/firefox/line_nav_pre_links.py
index edc038e..b863b44 100644
--- a/test/keystrokes/firefox/line_nav_pre_links.py
+++ b/test/keystrokes/firefox/line_nav_pre_links.py
@@ -25,8 +25,7 @@ sequence.append(utils.AssertPresentationAction(
     "2. Line Down",
     ["BRAILLE LINE:  'Line 2'",
      "     VISIBLE:  'Line 2', cursor=1",
-     "SPEECH OUTPUT: 'Line 2'",
-     "SPEECH OUTPUT: 'link'"]))
+     "SPEECH OUTPUT: 'Line 2 link'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
@@ -42,8 +41,7 @@ sequence.append(utils.AssertPresentationAction(
     "4. Line Down",
     ["BRAILLE LINE:  'Line 4'",
      "     VISIBLE:  'Line 4', cursor=1",
-     "SPEECH OUTPUT: 'Line 4'",
-     "SPEECH OUTPUT: 'link'"]))
+     "SPEECH OUTPUT: 'Line 4 link'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
@@ -57,23 +55,14 @@ sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
 sequence.append(utils.AssertPresentationAction(
     "6. Line Up",
-    ["BRAILLE LINE:  ' $l'",
-     "     VISIBLE:  ' $l', cursor=1",
-     "SPEECH OUTPUT: 'blank'"]))
-
-sequence.append(utils.StartRecordingAction())
-sequence.append(KeyComboAction("Up"))
-sequence.append(utils.AssertPresentationAction(
-    "7. Line Up",
     ["BRAILLE LINE:  'Line 4'",
      "     VISIBLE:  'Line 4', cursor=1",
-     "SPEECH OUTPUT: 'Line 4'",
-     "SPEECH OUTPUT: 'link'"]))
+     "SPEECH OUTPUT: 'Line 4 link'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
 sequence.append(utils.AssertPresentationAction(
-    "8. Line Up",
+    "7. Line Up",
     ["BRAILLE LINE:  'Line 3'",
      "     VISIBLE:  'Line 3', cursor=1",
      "SPEECH OUTPUT: 'Line 3'"]))
@@ -81,24 +70,15 @@ sequence.append(utils.AssertPresentationAction(
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
 sequence.append(utils.AssertPresentationAction(
-    "9. Line Up",
-    ["BRAILLE LINE:  ' $l'",
-     "     VISIBLE:  ' $l', cursor=1",
-     "SPEECH OUTPUT: 'blank'"]))
-
-sequence.append(utils.StartRecordingAction())
-sequence.append(KeyComboAction("Up"))
-sequence.append(utils.AssertPresentationAction(
-    "10. Line Up",
+    "8. Line Up",
     ["BRAILLE LINE:  'Line 2'",
      "     VISIBLE:  'Line 2', cursor=1",
-     "SPEECH OUTPUT: 'Line 2'",
-     "SPEECH OUTPUT: 'link'"]))
+     "SPEECH OUTPUT: 'Line 2 link'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
 sequence.append(utils.AssertPresentationAction(
-    "11. Line Up",
+    "9. Line Up",
     ["BRAILLE LINE:  'Line 1'",
      "     VISIBLE:  'Line 1', cursor=1",
      "SPEECH OUTPUT: 'Line 1'"]))
diff --git a/test/keystrokes/firefox/line_nav_simple_form.py b/test/keystrokes/firefox/line_nav_simple_form.py
index a6e5caf..aa8b1dc 100644
--- a/test/keystrokes/firefox/line_nav_simple_form.py
+++ b/test/keystrokes/firefox/line_nav_simple_form.py
@@ -19,7 +19,8 @@ sequence.append(utils.AssertPresentationAction(
     "1. line Down",
     ["BRAILLE LINE:  'Magic disappearing text trick: tab to me and I disappear $l'",
      "     VISIBLE:  'Magic disappearing text trick: t', cursor=1",
-     "SPEECH OUTPUT: 'Magic disappearing text trick: entry tab to me and I disappear'"]))
+     "SPEECH OUTPUT: 'Magic disappearing text trick:'",
+     "SPEECH OUTPUT: 'entry tab to me and I disappear'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
@@ -27,7 +28,8 @@ sequence.append(utils.AssertPresentationAction(
     "2. line Down",
     ["BRAILLE LINE:  'Tell me a secret:  $l'",
      "     VISIBLE:  'Tell me a secret:  $l', cursor=1",
-     "SPEECH OUTPUT: 'Tell me a secret: password text'"]))
+     "SPEECH OUTPUT: 'Tell me a secret:'",
+     "SPEECH OUTPUT: 'password text'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
@@ -43,7 +45,7 @@ sequence.append(utils.AssertPresentationAction(
     "4. line Down",
     ["BRAILLE LINE:  'I am a monkey with a long tail.  I like  $l'",
      "     VISIBLE:  'I am a monkey with a long tail. ', cursor=1",
-     "SPEECH OUTPUT: 'Tell me a little more about yourself: entry I am a monkey with a long tail.  I like 
'"]))
+     "SPEECH OUTPUT: 'entry I am a monkey with a long tail.  I like '"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
@@ -74,14 +76,6 @@ sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
 sequence.append(utils.AssertPresentationAction(
     "8. line Down",
-    ["BRAILLE LINE:  '      $l'",
-     "     VISIBLE:  '      $l', cursor=1",
-     "SPEECH OUTPUT: '     '"]))
-
-sequence.append(utils.StartRecordingAction())
-sequence.append(KeyComboAction("Down"))
-sequence.append(utils.AssertPresentationAction(
-    "9. line Down",
     ["BRAILLE LINE:  'Check one or more: < > Red check box < > Blue check box < > Green check box'",
      "     VISIBLE:  'Check one or more: < > Red check', cursor=1",
      "SPEECH OUTPUT: 'Check one or more:'",
@@ -92,15 +86,16 @@ sequence.append(utils.AssertPresentationAction(
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
 sequence.append(utils.AssertPresentationAction(
-    "10. line Down",
+    "9. line Down",
     ["BRAILLE LINE:  'Make a selection: Water combo box'",
      "     VISIBLE:  'Make a selection: Water combo bo', cursor=1",
-     "SPEECH OUTPUT: 'Make a selection: Water combo box'"]))
+     "SPEECH OUTPUT: 'Make a selection:'",
+     "SPEECH OUTPUT: 'Water combo box'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
 sequence.append(utils.AssertPresentationAction(
-    "11. line Down",
+    "10. line Down",
     ["BRAILLE LINE:  'Which sports do you like?'",
      "     VISIBLE:  'Which sports do you like?', cursor=1",
      "SPEECH OUTPUT: 'Which sports do you like?'"]))
@@ -108,15 +103,15 @@ sequence.append(utils.AssertPresentationAction(
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
 sequence.append(utils.AssertPresentationAction(
-    "12. line Down",
+    "11. line Down",
     ["BRAILLE LINE:  'Hockey list box'",
      "     VISIBLE:  'Hockey list box', cursor=1",
-     "SPEECH OUTPUT: 'Which sports do you like? Hockey multi-select List with 4 items'"]))
+     "SPEECH OUTPUT: 'Hockey multi-select List with 4 items'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
 sequence.append(utils.AssertPresentationAction(
-    "13. line Down",
+    "12. line Down",
     ["BRAILLE LINE:  'Dashing picture of Willie Walker image'",
      "     VISIBLE:  'Dashing picture of Willie Walker', cursor=1",
      "SPEECH OUTPUT: 'Dashing picture of Willie Walker image'"]))
@@ -124,8 +119,8 @@ sequence.append(utils.AssertPresentationAction(
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
 sequence.append(utils.AssertPresentationAction(
-    "14. line Down",
-    ["BRAILLE LINE:  'Ain't he handsome (please say yes)? & y radio button Yes & y radio button No'",
+    "13. line Down",
+    ["BRAILLE LINE:  'Ain't he handsome (please say yes)? & y Yes radio button & y No radio button'",
      "     VISIBLE:  'Ain't he handsome (please say ye', cursor=1",
      "SPEECH OUTPUT: 'Ain't he handsome (please say yes)?'",
      "SPEECH OUTPUT: 'Yes not selected radio button'",
@@ -134,7 +129,7 @@ sequence.append(utils.AssertPresentationAction(
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
 sequence.append(utils.AssertPresentationAction(
-    "15. line Up",
+    "14. line Up",
     ["BRAILLE LINE:  'Dashing picture of Willie Walker image'",
      "     VISIBLE:  'Dashing picture of Willie Walker', cursor=1",
      "SPEECH OUTPUT: 'Dashing picture of Willie Walker image'"]))
@@ -142,15 +137,15 @@ sequence.append(utils.AssertPresentationAction(
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
 sequence.append(utils.AssertPresentationAction(
-    "16. line Up",
+    "15. line Up",
     ["BRAILLE LINE:  'Hockey list box'",
      "     VISIBLE:  'Hockey list box', cursor=1",
-     "SPEECH OUTPUT: 'Which sports do you like? Hockey multi-select List with 4 items'"]))
+     "SPEECH OUTPUT: 'Hockey multi-select List with 4 items'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
 sequence.append(utils.AssertPresentationAction(
-    "17. line Up",
+    "16. line Up",
     ["BRAILLE LINE:  'Which sports do you like?'",
      "     VISIBLE:  'Which sports do you like?', cursor=1",
      "SPEECH OUTPUT: 'Which sports do you like?'"]))
@@ -158,15 +153,16 @@ sequence.append(utils.AssertPresentationAction(
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
 sequence.append(utils.AssertPresentationAction(
-    "18. line Up",
+    "17. line Up",
     ["BRAILLE LINE:  'Make a selection: Water combo box'",
      "     VISIBLE:  'Make a selection: Water combo bo', cursor=1",
-     "SPEECH OUTPUT: 'Make a selection: Water combo box'"]))
+     "SPEECH OUTPUT: 'Make a selection:'",
+     "SPEECH OUTPUT: 'Water combo box'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
 sequence.append(utils.AssertPresentationAction(
-    "19. line Up",
+    "18. line Up",
     ["BRAILLE LINE:  'Check one or more: < > Red check box < > Blue check box < > Green check box'",
      "     VISIBLE:  'Check one or more: < > Red check', cursor=1",
      "SPEECH OUTPUT: 'Check one or more:'",
@@ -177,15 +173,7 @@ sequence.append(utils.AssertPresentationAction(
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
 sequence.append(utils.AssertPresentationAction(
-    "20. line Up",
-    ["BRAILLE LINE:  '      $l'",
-     "     VISIBLE:  '      $l', cursor=1",
-     "SPEECH OUTPUT: 'Tell me a little more about yourself: entry      '"]))
-
-sequence.append(utils.StartRecordingAction())
-sequence.append(KeyComboAction("Up"))
-sequence.append(utils.AssertPresentationAction(
-    "21. line Up",
+    "19. line Up",
     ["BRAILLE LINE:  'write my memoirs. $l'",
      "     VISIBLE:  'write my memoirs. $l', cursor=1",
      "SPEECH OUTPUT: 'write my memoirs.",
@@ -194,7 +182,7 @@ sequence.append(utils.AssertPresentationAction(
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
 sequence.append(utils.AssertPresentationAction(
-    "22. line Up",
+    "20. line Up",
     ["BRAILLE LINE:  'I've recently taken up typing and plan to  $l'",
      "     VISIBLE:  'I've recently taken up typing an', cursor=1",
      "SPEECH OUTPUT: 'I've recently taken up typing and plan to '"]))
@@ -202,7 +190,7 @@ sequence.append(utils.AssertPresentationAction(
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
 sequence.append(utils.AssertPresentationAction(
-    "23. line Up",
+    "21. line Up",
     ["BRAILLE LINE:  'to swing from trees and eat bananas.   $l'",
      "     VISIBLE:  'to swing from trees and eat bana', cursor=1",
      "SPEECH OUTPUT: 'to swing from trees and eat bananas.  '"]))
@@ -210,7 +198,7 @@ sequence.append(utils.AssertPresentationAction(
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
 sequence.append(utils.AssertPresentationAction(
-    "24. line Up",
+    "22. line Up",
     ["BRAILLE LINE:  'I am a monkey with a long tail.  I like  $l'",
      "     VISIBLE:  'I am a monkey with a long tail. ', cursor=1",
      "SPEECH OUTPUT: 'I am a monkey with a long tail.  I like '"]))
@@ -218,7 +206,7 @@ sequence.append(utils.AssertPresentationAction(
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
 sequence.append(utils.AssertPresentationAction(
-    "25. line Up",
+    "23. line Up",
     ["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:'"]))
@@ -226,26 +214,29 @@ sequence.append(utils.AssertPresentationAction(
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
 sequence.append(utils.AssertPresentationAction(
-    "26. line Up",
+    "24. line Up",
     ["BRAILLE LINE:  'Tell me a secret:  $l'",
      "     VISIBLE:  'Tell me a secret:  $l', cursor=1",
-     "SPEECH OUTPUT: 'Tell me a secret: password text'"]))
+     "SPEECH OUTPUT: 'Tell me a secret:'",
+     "SPEECH OUTPUT: 'password text'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
 sequence.append(utils.AssertPresentationAction(
-    "27. line Up",
+    "25. line Up",
     ["BRAILLE LINE:  'Magic disappearing text trick: tab to me and I disappear $l'",
      "     VISIBLE:  'Magic disappearing text trick: t', cursor=1",
-     "SPEECH OUTPUT: 'Magic disappearing text trick: entry tab to me and I disappear'"]))
+     "SPEECH OUTPUT: 'Magic disappearing text trick:'",
+     "SPEECH OUTPUT: 'entry tab to me and I disappear'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
 sequence.append(utils.AssertPresentationAction(
-    "28. line Up",
+    "26. line Up",
     ["BRAILLE LINE:  'Type something here:  $l'",
      "     VISIBLE:  'Type something here:  $l', cursor=1",
-     "SPEECH OUTPUT: 'Type something here: entry'"]))
+     "SPEECH OUTPUT: 'Type something here:'",
+     "SPEECH OUTPUT: 'entry'"]))
 
 sequence.append(utils.AssertionSummaryAction())
 sequence.start()
diff --git a/test/keystrokes/firefox/line_nav_slash_test.py b/test/keystrokes/firefox/line_nav_slash_test.py
index 12680ec..d1772c3 100644
--- a/test/keystrokes/firefox/line_nav_slash_test.py
+++ b/test/keystrokes/firefox/line_nav_slash_test.py
@@ -35,9 +35,7 @@ sequence.append(utils.AssertPresentationAction(
     "3. Line Down",
     ["BRAILLE LINE:  'Science h4'",
      "     VISIBLE:  'Science h4', cursor=1",
-     "SPEECH OUTPUT: 'Science'",
-     "SPEECH OUTPUT: 'link'",
-     "SPEECH OUTPUT: 'heading level 4'"]))
+     "SPEECH OUTPUT: 'Science link heading level 4'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
@@ -45,9 +43,7 @@ sequence.append(utils.AssertPresentationAction(
     "4. Line Down",
     ["BRAILLE LINE:  'Recent Tags h4'",
      "     VISIBLE:  'Recent Tags h4', cursor=1",
-     "SPEECH OUTPUT: 'Recent Tags'",
-     "SPEECH OUTPUT: 'link'",
-     "SPEECH OUTPUT: 'heading level 4'"]))
+     "SPEECH OUTPUT: 'Recent Tags link heading level 4'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
@@ -63,8 +59,10 @@ sequence.append(utils.AssertPresentationAction(
     "6. Line Down",
     ["BRAILLE LINE:  'Nickname $l Password $l Log in push button'",
      "     VISIBLE:  'Nickname $l Password $l Log in p', cursor=1",
-     "SPEECH OUTPUT: 'Nickname entry'",
-     "SPEECH OUTPUT: 'Password password text'",
+     "SPEECH OUTPUT: 'Nickname'",
+     "SPEECH OUTPUT: 'entry'",
+     "SPEECH OUTPUT: 'Password'",
+     "SPEECH OUTPUT: 'password text'",
      "SPEECH OUTPUT: 'Log in push button'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -87,8 +85,8 @@ sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
 sequence.append(utils.AssertPresentationAction(
     "9. Line Down",
-    ["BRAILLE LINE:  '& y radio button Some polls'",
-     "     VISIBLE:  '& y radio button Some polls', cursor=1",
+    ["BRAILLE LINE:  '& y Some polls radio button'",
+     "     VISIBLE:  '& y Some polls radio button', cursor=1",
      "SPEECH OUTPUT: 'Some polls not selected radio button'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -97,16 +95,14 @@ sequence.append(utils.AssertPresentationAction(
     "10. Line Down",
     ["BRAILLE LINE:  'Book Reviews h4'",
      "     VISIBLE:  'Book Reviews h4', cursor=1",
-     "SPEECH OUTPUT: 'Book Reviews'",
-     "SPEECH OUTPUT: 'link'",
-     "SPEECH OUTPUT: 'heading level 4'"]))
+     "SPEECH OUTPUT: 'Book Reviews link heading level 4'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
 sequence.append(utils.AssertPresentationAction(
     "11. Line Up",
-    ["BRAILLE LINE:  '& y radio button Some polls'",
-     "     VISIBLE:  '& y radio button Some polls', cursor=1",
+    ["BRAILLE LINE:  '& y Some polls radio button'",
+     "     VISIBLE:  '& y Some polls radio button', cursor=1",
      "SPEECH OUTPUT: 'Some polls not selected radio button'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -131,8 +127,10 @@ sequence.append(utils.AssertPresentationAction(
     "14. Line Up",
     ["BRAILLE LINE:  'Nickname $l Password $l Log in push button'",
      "     VISIBLE:  'Nickname $l Password $l Log in p', cursor=1",
-     "SPEECH OUTPUT: 'Nickname entry'",
-     "SPEECH OUTPUT: 'Password password text'",
+     "SPEECH OUTPUT: 'Nickname'",
+     "SPEECH OUTPUT: 'entry'",
+     "SPEECH OUTPUT: 'Password'",
+     "SPEECH OUTPUT: 'password text'",
      "SPEECH OUTPUT: 'Log in push button'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -149,9 +147,7 @@ sequence.append(utils.AssertPresentationAction(
     "16. Line Up",
     ["BRAILLE LINE:  'Recent Tags h4'",
      "     VISIBLE:  'Recent Tags h4', cursor=1",
-     "SPEECH OUTPUT: 'Recent Tags'",
-     "SPEECH OUTPUT: 'link'",
-     "SPEECH OUTPUT: 'heading level 4'"]))
+     "SPEECH OUTPUT: 'Recent Tags link heading level 4'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
@@ -159,9 +155,7 @@ sequence.append(utils.AssertPresentationAction(
     "17. Line Up",
     ["BRAILLE LINE:  'Science h4'",
      "     VISIBLE:  'Science h4', cursor=1",
-     "SPEECH OUTPUT: 'Science'",
-     "SPEECH OUTPUT: 'link'",
-     "SPEECH OUTPUT: 'heading level 4'"]))
+     "SPEECH OUTPUT: 'Science link heading level 4'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
diff --git a/test/keystrokes/firefox/line_nav_sun_java.py b/test/keystrokes/firefox/line_nav_sun_java.py
index 4993308..ff62667 100644
--- a/test/keystrokes/firefox/line_nav_sun_java.py
+++ b/test/keystrokes/firefox/line_nav_sun_java.py
@@ -18,12 +18,11 @@ sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
 sequence.append(utils.AssertPresentationAction(
     "1. Line Down",
-    ["BRAILLE LINE:  '\xbb\xa0search tips Search $l Submit Search push button'",
-     "     VISIBLE:  '\xbb\xa0search tips Search $l Submit S', cursor=1",
-     "SPEECH OUTPUT: '\xbb'",
-     "SPEECH OUTPUT: 'search tips'",
-     "SPEECH OUTPUT: 'link'",
-     "SPEECH OUTPUT: '\xbb\xa0search tips entry Search'",
+    ["BRAILLE LINE:  '» search tips Search $l Submit Search push button'",
+     "     VISIBLE:  '» search tips Search $l Submit S', cursor=1",
+     "SPEECH OUTPUT: '»'",
+     "SPEECH OUTPUT: 'search tips link'",
+     "SPEECH OUTPUT: 'entry Search'",
      "SPEECH OUTPUT: 'Submit Search push button'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -33,7 +32,7 @@ sequence.append(utils.AssertPresentationAction(
     ["BRAILLE LINE:  'Home Page Sun Developer Network'",
      "     VISIBLE:  'Home Page Sun Developer Network', cursor=1",
      "SPEECH OUTPUT: 'Home Page link'",
-     "SPEECH OUTPUT: 'Sun Developer Network'"]))
+     "SPEECH OUTPUT: 'link Sun Developer Network'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
@@ -41,31 +40,17 @@ sequence.append(utils.AssertPresentationAction(
     "3. Line Down",
     ["BRAILLE LINE:  'APIs Downloads Products Support Training Participate'",
      "     VISIBLE:  'APIs Downloads Products Support ', cursor=1",
-     "SPEECH OUTPUT: 'APIs'",
-     "SPEECH OUTPUT: 'link See All APIs'",
-     "SPEECH OUTPUT: 'Downloads'",
-     "SPEECH OUTPUT: 'link'",
-     "SPEECH OUTPUT: 'Products'",
-     "SPEECH OUTPUT: 'link'",
-     "SPEECH OUTPUT: 'Support'",
-     "SPEECH OUTPUT: 'link'",
-     "SPEECH OUTPUT: 'Training'",
-     "SPEECH OUTPUT: 'link'",
-     "SPEECH OUTPUT: 'Participate'",
-     "SPEECH OUTPUT: 'link'"]))
+     "SPEECH OUTPUT: 'APIs link See All APIs'",
+     "SPEECH OUTPUT: 'Downloads link'",
+     "SPEECH OUTPUT: 'Products link'",
+     "SPEECH OUTPUT: 'Support link'",
+     "SPEECH OUTPUT: 'Training link'",
+     "SPEECH OUTPUT: 'Participate link'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
 sequence.append(utils.AssertPresentationAction(
     "4. Line Down",
-    ["BRAILLE LINE:  ' $l'",
-     "     VISIBLE:  ' $l', cursor=0",
-     "SPEECH OUTPUT: 'blank'"]))
-
-sequence.append(utils.StartRecordingAction())
-sequence.append(KeyComboAction("Down"))
-sequence.append(utils.AssertPresentationAction(
-    "5. Line Down",
     ["BRAILLE LINE:  'JavaTM SE 6 Release Notes'",
      "     VISIBLE:  'JavaTM SE 6 Release Notes', cursor=1",
      "SPEECH OUTPUT: 'JavaTM SE 6 Release Notes'"]))
@@ -73,7 +58,7 @@ sequence.append(utils.AssertPresentationAction(
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
 sequence.append(utils.AssertPresentationAction(
-    "6. Line Down",
+    "5. Line Down",
     ["BRAILLE LINE:  'Linux Installation (32-bit) h1'",
      "     VISIBLE:  'Linux Installation (32-bit) h1', cursor=1",
      "SPEECH OUTPUT: 'Linux Installation (32-bit) heading level 1'"]))
@@ -81,7 +66,7 @@ sequence.append(utils.AssertPresentationAction(
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
 sequence.append(utils.AssertPresentationAction(
-    "7. Line Down",
+    "6. Line Down",
     ["BRAILLE LINE:  'separator'",
      "     VISIBLE:  'separator', cursor=1",
      "SPEECH OUTPUT: 'separator'"]))
@@ -89,16 +74,15 @@ sequence.append(utils.AssertPresentationAction(
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
 sequence.append(utils.AssertPresentationAction(
-    "8. Line Down",
+    "7. Line Down",
     ["BRAILLE LINE:  'JDK Documentation'",
      "     VISIBLE:  'JDK Documentation', cursor=1",
-     "SPEECH OUTPUT: 'JDK Documentation'",
-     "SPEECH OUTPUT: 'link'"]))
+     "SPEECH OUTPUT: 'JDK Documentation link'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
 sequence.append(utils.AssertPresentationAction(
-    "9. Line Down",
+    "8. Line Down",
     ["BRAILLE LINE:  'Contents h2'",
      "     VISIBLE:  'Contents h2', cursor=1",
      "SPEECH OUTPUT: 'Contents heading level 2'"]))
@@ -106,70 +90,63 @@ sequence.append(utils.AssertPresentationAction(
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
 sequence.append(utils.AssertPresentationAction(
-    "10. Line Down",
+    "9. Line Down",
     ["BRAILLE LINE:  'System Requirements'",
      "     VISIBLE:  'System Requirements', cursor=1",
-     "SPEECH OUTPUT: 'System Requirements'",
-     "SPEECH OUTPUT: 'link'"]))
+     "SPEECH OUTPUT: 'System Requirements link'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
 sequence.append(utils.AssertPresentationAction(
-    "11. Line Down",
+    "10. Line Down",
     ["BRAILLE LINE:  'JDK Installation Instructions'",
      "     VISIBLE:  'JDK Installation Instructions', cursor=1",
-     "SPEECH OUTPUT: 'JDK Installation Instructions'",
-     "SPEECH OUTPUT: 'link'"]))
+     "SPEECH OUTPUT: 'JDK Installation Instructions link'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
 sequence.append(utils.AssertPresentationAction(
-    "12. Line Down",
+    "11. Line Down",
     ["BRAILLE LINE:  'Installation of Self-Extracting Binary'",
      "     VISIBLE:  'Installation of Self-Extracting ', cursor=0",
-     "SPEECH OUTPUT: 'Installation of Self-Extracting Binary'",
-     "SPEECH OUTPUT: 'link'"]))
+     "SPEECH OUTPUT: 'Installation of Self-Extracting Binary link'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
 sequence.append(utils.AssertPresentationAction(
-    "13. Line Down",
+    "12. Line Down",
     ["BRAILLE LINE:  'Installation of RPM File'",
      "     VISIBLE:  'Installation of RPM File', cursor=0",
-     "SPEECH OUTPUT: 'Installation of RPM File'",
-     "SPEECH OUTPUT: 'link'"]))
+     "SPEECH OUTPUT: 'Installation of RPM File link'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
 sequence.append(utils.AssertPresentationAction(
-    "14. Line Down",
+    "13. Line Down",
     ["BRAILLE LINE:  'Java Plugin Browser Registration Instructions'",
      "     VISIBLE:  'Java Plugin Browser Registration', cursor=1",
-     "SPEECH OUTPUT: 'Java Plugin Browser Registration Instructions'",
-     "SPEECH OUTPUT: 'link'"]))
+     "SPEECH OUTPUT: 'Java Plugin Browser Registration Instructions link'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
 sequence.append(utils.AssertPresentationAction(
-    "15. Line Down",
+    "14. Line Down",
     ["BRAILLE LINE:  'Java Web Start Installation Notes'",
      "     VISIBLE:  'Java Web Start Installation Note', cursor=1",
-     "SPEECH OUTPUT: 'Java Web Start Installation Notes'",
-     "SPEECH OUTPUT: 'link'"]))
+     "SPEECH OUTPUT: 'Java Web Start Installation Notes link'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
 sequence.append(utils.AssertPresentationAction(
-    "16. Line Down",
+    "15. Line Down",
     ["BRAILLE LINE:  'Troubleshooting'",
      "     VISIBLE:  'Troubleshooting', cursor=1",
-     "SPEECH OUTPUT: 'Troubleshooting'",
-     "SPEECH OUTPUT: 'link'"]))
+     "SPEECH OUTPUT: 'Troubleshooting link'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
 sequence.append(utils.AssertPresentationAction(
-    "17. Line Down",
+    "16. Line Down",
     ["BRAILLE LINE:  'System Requirements h2'",
      "     VISIBLE:  'System Requirements h2', cursor=1",
      "SPEECH OUTPUT: 'System Requirements heading level 2'"]))
@@ -177,29 +154,27 @@ sequence.append(utils.AssertPresentationAction(
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
 sequence.append(utils.AssertPresentationAction(
-    "18. Line Down",
+    "17. Line Down",
     ["BRAILLE LINE:  'See supported System Configurations for information about supported platforms, 
operating systems, desktop managers, and browsers.'",
      "     VISIBLE:  'See supported System Configurati', cursor=1",
      "SPEECH OUTPUT: 'See supported'",
-     "SPEECH OUTPUT: 'System Configurations'",
-     "SPEECH OUTPUT: 'link'",
+     "SPEECH OUTPUT: 'System Configurations link'",
      "SPEECH OUTPUT: 'for information about supported platforms, operating systems, desktop managers, and 
browsers.'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
 sequence.append(utils.AssertPresentationAction(
-    "19. Line Down",
+    "18. Line Down",
     ["BRAILLE LINE:  'For issues, see the Troubleshooting section below.'",
      "     VISIBLE:  'For issues, see the Troubleshoot', cursor=1",
      "SPEECH OUTPUT: 'For issues, see the'",
-     "SPEECH OUTPUT: 'Troubleshooting'",
-     "SPEECH OUTPUT: 'link'",
+     "SPEECH OUTPUT: 'Troubleshooting link'",
      "SPEECH OUTPUT: 'section below.'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
 sequence.append(utils.AssertPresentationAction(
-    "20. Line Down",
+    "19. Line Down",
     ["BRAILLE LINE:  'Installation Instructions h2'",
      "     VISIBLE:  'Installation Instructions h2', cursor=1",
      "SPEECH OUTPUT: 'Installation Instructions heading level 2'"]))
@@ -207,7 +182,7 @@ sequence.append(utils.AssertPresentationAction(
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
 sequence.append(utils.AssertPresentationAction(
-    "21. Line Down",
+    "20. Line Down",
     ["BRAILLE LINE:  'Installing the JDK automatically installs the Java Plugin and Java Web Start. Note 
that the Java Plugin needs to be registered with the browser. After installing the JDK, refer to:'",
      "     VISIBLE:  'Installing the JDK automatically', cursor=1",
      "SPEECH OUTPUT: 'Installing the JDK automatically installs the Java Plugin and Java Web Start. Note 
that the Java Plugin needs to be registered with the browser. After installing the JDK, refer to:'"]))
@@ -215,27 +190,25 @@ sequence.append(utils.AssertPresentationAction(
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
 sequence.append(utils.AssertPresentationAction(
-    "22. Line Down",
+    "21. Line Down",
     ["BRAILLE LINE:  '• Java Plugin Browser Registration Instructions'",
      "     VISIBLE:  '• Java Plugin Browser Registrati', cursor=1",
      "SPEECH OUTPUT: '•'",
-     "SPEECH OUTPUT: 'Java Plugin Browser Registration Instructions'",
-     "SPEECH OUTPUT: 'link'"]))
+     "SPEECH OUTPUT: 'Java Plugin Browser Registration Instructions link'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
 sequence.append(utils.AssertPresentationAction(
-    "23. Line Down",
+    "22. Line Down",
     ["BRAILLE LINE:  '• Java Web Start Installation Notes'",
      "     VISIBLE:  '• Java Web Start Installation No', cursor=1",
      "SPEECH OUTPUT: '•'",
-     "SPEECH OUTPUT: 'Java Web Start Installation Notes'",
-     "SPEECH OUTPUT: 'link'"]))
+     "SPEECH OUTPUT: 'Java Web Start Installation Notes link'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
 sequence.append(utils.AssertPresentationAction(
-    "24. Line Down",
+    "23. Line Down",
     ["BRAILLE LINE:  'Install formats - This version of the JDK is available in two installation formats.'",
      "     VISIBLE:  'Install formats - This version o', cursor=1",
      "SPEECH OUTPUT: 'Install formats - This version of the JDK is available in two installation 
formats.'"]))
@@ -243,7 +216,7 @@ sequence.append(utils.AssertPresentationAction(
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
 sequence.append(utils.AssertPresentationAction(
-    "25. Line Down",
+    "24. Line Down",
     ["BRAILLE LINE:  '• Self-extracting Binary File - This file can be used to install the JDK in a location 
chosen by the user. This one can be installed by anyone (not only root users), and it can'",
      "     VISIBLE:  '• Self-extracting Binary File - ', cursor=1",
      "SPEECH OUTPUT: '• Self-extracting Binary File - This file can be used to install the JDK in a location 
chosen by the user. This one can be installed by anyone (not only root users), and it can'"]))
@@ -251,7 +224,7 @@ sequence.append(utils.AssertPresentationAction(
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
 sequence.append(utils.AssertPresentationAction(
-    "26. Line Down",
+    "25. Line Down",
     ["BRAILLE LINE:  'easily be installed in any location. As long as you are not root user, it cannot 
displace the system version of the Java platform suppled by Linux. To use this file, see'",
      "     VISIBLE:  'easily be installed in any locat', cursor=1",
      "SPEECH OUTPUT: 'easily be installed in any location. As long as you are not root user, it cannot 
displace the system version of the Java platform suppled by Linux. To use this file, see'"]))
@@ -259,17 +232,16 @@ sequence.append(utils.AssertPresentationAction(
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
 sequence.append(utils.AssertPresentationAction(
-    "27. Line Down",
+    "26. Line Down",
     ["BRAILLE LINE:  'Installation of Self-Extracting Binary below.'",
      "     VISIBLE:  'Installation of Self-Extracting ', cursor=1",
-     "SPEECH OUTPUT: 'Installation of Self-Extracting Binary'",
-     "SPEECH OUTPUT: 'link'",
+     "SPEECH OUTPUT: 'Installation of Self-Extracting Binary link'",
      "SPEECH OUTPUT: 'below.'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
 sequence.append(utils.AssertPresentationAction(
-    "28. Line Down",
+    "27. Line Down",
     ["BRAILLE LINE:  '• RPM Packages - A rpm.bin file containing RPM packages, installed with the rpm 
utility. Requires root access to install. RPM packages are the recommended method for'",
      "     VISIBLE:  '• RPM Packages - A rpm.bin file ', cursor=1",
      "SPEECH OUTPUT: '• RPM Packages - A rpm.bin file containing RPM packages, installed with the rpm 
utility. Requires root access to install. RPM packages are the recommended method for'"]))
@@ -277,18 +249,17 @@ sequence.append(utils.AssertPresentationAction(
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
 sequence.append(utils.AssertPresentationAction(
-    "29. Line Down",
+    "28. Line Down",
     ["BRAILLE LINE:  'installation on Linux. To use this bundle, see Installation of RPM File below.'",
      "     VISIBLE:  'installation on Linux. To use th', cursor=1",
      "SPEECH OUTPUT: 'installation on Linux. To use this bundle, see'",
-     "SPEECH OUTPUT: 'Installation of RPM File'",
-     "SPEECH OUTPUT: 'link'",
+     "SPEECH OUTPUT: 'Installation of RPM File link'",
      "SPEECH OUTPUT: 'below.'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
 sequence.append(utils.AssertPresentationAction(
-    "30. Line Down",
+    "29. Line Down",
     ["BRAILLE LINE:  'Choose the install format that is most suitable to your needs.'",
      "     VISIBLE:  'Choose the install format that i', cursor=1",
      "SPEECH OUTPUT: 'Choose the install format that is most suitable to your needs.'"]))
@@ -296,7 +267,7 @@ sequence.append(utils.AssertPresentationAction(
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
 sequence.append(utils.AssertPresentationAction(
-    "31. Line Down",
+    "30. Line Down",
     ["BRAILLE LINE:  'Note: For any text on this page containing the following notation, you must substitute 
the appropriate JDK update version number for the notation.'",
      "     VISIBLE:  'Note: For any text on this page ', cursor=1",
      "SPEECH OUTPUT: 'Note: For any text on this page containing the following notation, you must substitute 
the appropriate JDK update version number for the notation.'"]))
@@ -304,7 +275,7 @@ sequence.append(utils.AssertPresentationAction(
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
 sequence.append(utils.AssertPresentationAction(
-    "32. Line Down",
+    "31. Line Down",
     ["BRAILLE LINE:  '<version>'",
      "     VISIBLE:  '<version>', cursor=1",
      "SPEECH OUTPUT: '<version>'"]))
@@ -312,15 +283,7 @@ sequence.append(utils.AssertPresentationAction(
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
 sequence.append(utils.AssertPresentationAction(
-    "33. Line Down",
-    ["BRAILLE LINE:  '           $l'",
-     "     VISIBLE:  '           $l', cursor=1",
-     "SPEECH OUTPUT: 'blank'"]))
-
-sequence.append(utils.StartRecordingAction())
-sequence.append(KeyComboAction("Down"))
-sequence.append(utils.AssertPresentationAction(
-    "34. Line Down",
+    "32. Line Down",
     ["BRAILLE LINE:  'For example, if you were downloading update 6_01, the following command:'",
      "     VISIBLE:  'For example, if you were downloa', cursor=1",
      "SPEECH OUTPUT: 'For example, if you were downloading update 6_01, the following command:'"]))
@@ -328,7 +291,7 @@ sequence.append(utils.AssertPresentationAction(
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
 sequence.append(utils.AssertPresentationAction(
-    "35. Line Down",
+    "33. Line Down",
     ["BRAILLE LINE:  './jdk-6<version>-linux-i586.bin'",
      "     VISIBLE:  './jdk-6<version>-linux-i586.bin', cursor=1",
      "SPEECH OUTPUT: './jdk-6<version>-linux-i586.bin'"]))
@@ -336,15 +299,7 @@ sequence.append(utils.AssertPresentationAction(
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
 sequence.append(utils.AssertPresentationAction(
-    "36. Line Down",
-    ["BRAILLE LINE:  '           $l'",
-     "     VISIBLE:  '           $l', cursor=1",
-     "SPEECH OUTPUT: 'blank'"]))
-
-sequence.append(utils.StartRecordingAction())
-sequence.append(KeyComboAction("Down"))
-sequence.append(utils.AssertPresentationAction(
-    "37. Line Down",
+    "34. Line Down",
     ["BRAILLE LINE:  'would become:'",
      "     VISIBLE:  'would become:', cursor=1",
      "SPEECH OUTPUT: 'would become:'"]))
@@ -352,7 +307,7 @@ sequence.append(utils.AssertPresentationAction(
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
 sequence.append(utils.AssertPresentationAction(
-    "38. Line Down",
+    "35. Line Down",
     ["BRAILLE LINE:  './jdk-6u1-linux-i586.bin'",
      "     VISIBLE:  './jdk-6u1-linux-i586.bin', cursor=1",
      "SPEECH OUTPUT: './jdk-6u1-linux-i586.bin'"]))
@@ -360,15 +315,7 @@ sequence.append(utils.AssertPresentationAction(
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
 sequence.append(utils.AssertPresentationAction(
-    "39. Line Down",
-    ["BRAILLE LINE:  '           $l'",
-     "     VISIBLE:  '           $l', cursor=1",
-     "SPEECH OUTPUT: 'blank'"]))
-
-sequence.append(utils.StartRecordingAction())
-sequence.append(KeyComboAction("Down"))
-sequence.append(utils.AssertPresentationAction(
-    "40. Line Down",
+    "36. Line Down",
     ["BRAILLE LINE:  'Installation of Self-Extracting Binary h3'",
      "     VISIBLE:  'Installation of Self-Extracting ', cursor=1",
      "SPEECH OUTPUT: 'Installation of Self-Extracting Binary heading level 3'"]))
@@ -376,18 +323,17 @@ sequence.append(utils.AssertPresentationAction(
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
 sequence.append(utils.AssertPresentationAction(
-    "41. Line Down",
+    "37. Line Down",
     ["BRAILLE LINE:  'Use these instructions if you want to use the self-extracting binary file to install 
the JDK. If you want to install RPM packages instead, see Installation of RPM File.'",
      "     VISIBLE:  'Use these instructions if you wa', cursor=1",
      "SPEECH OUTPUT: 'Use these instructions if you want to use the self-extracting binary file to install 
the JDK. If you want to install RPM packages instead, see'",
-     "SPEECH OUTPUT: 'Installation of RPM File'",
-     "SPEECH OUTPUT: 'link'",
+     "SPEECH OUTPUT: 'Installation of RPM File link'",
      "SPEECH OUTPUT: '.'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
 sequence.append(utils.AssertPresentationAction(
-    "42. Line Down",
+    "38. Line Down",
     ["BRAILLE LINE:  '1. Download and check the download file size to ensure that you have downloaded the 
full, uncorrupted software bundle.'",
      "     VISIBLE:  '1. Download and check the downlo', cursor=1",
      "SPEECH OUTPUT: '1. Download and check the download file size to ensure that you have downloaded the 
full, uncorrupted software bundle.'"]))
@@ -395,7 +341,7 @@ sequence.append(utils.AssertPresentationAction(
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
 sequence.append(utils.AssertPresentationAction(
-    "43. Line Down",
+    "39. Line Down",
     ["BRAILLE LINE:  'You can download to any directory you choose; it does not have to be the directory 
where you want to install the JDK.'",
      "     VISIBLE:  'You can download to any director', cursor=1",
      "SPEECH OUTPUT: 'You can download to any directory you choose; it does not have to be the directory 
where you want to install the JDK.'"]))
@@ -403,7 +349,7 @@ sequence.append(utils.AssertPresentationAction(
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
 sequence.append(utils.AssertPresentationAction(
-    "44. Line Down",
+    "40. Line Down",
     ["BRAILLE LINE:  'Before you download the file, notice its byte size provided on the download page on 
the web site. Once the download has completed, compare that file size to the'",
      "     VISIBLE:  'Before you download the file, no', cursor=1",
      "SPEECH OUTPUT: 'Before you download the file, notice its byte size provided on the download page on 
the web site. Once the download has completed, compare that file size to the'"]))
@@ -411,7 +357,7 @@ sequence.append(utils.AssertPresentationAction(
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
 sequence.append(utils.AssertPresentationAction(
-    "45. Line Down",
+    "41. Line Down",
     ["BRAILLE LINE:  'size of the downloaded file to make sure they are equal.'",
      "     VISIBLE:  'size of the downloaded file to m', cursor=1",
      "SPEECH OUTPUT: 'size of the downloaded file to make sure they are equal.'"]))
@@ -419,7 +365,7 @@ sequence.append(utils.AssertPresentationAction(
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
 sequence.append(utils.AssertPresentationAction(
-    "46. Line Down",
+    "42. Line Down",
     ["BRAILLE LINE:  '2. Make sure that execute permissions are set on the self-extracting binary.'",
      "     VISIBLE:  '2. Make sure that execute permis', cursor=1",
      "SPEECH OUTPUT: '2. Make sure that execute permissions are set on the self-extracting binary.'"]))
diff --git a/test/keystrokes/firefox/line_nav_table_cell_links.py 
b/test/keystrokes/firefox/line_nav_table_cell_links.py
index acd9d0e..15c8228 100644
--- a/test/keystrokes/firefox/line_nav_table_cell_links.py
+++ b/test/keystrokes/firefox/line_nav_table_cell_links.py
@@ -33,8 +33,7 @@ sequence.append(utils.AssertPresentationAction(
     "3. Line Down",
     ["BRAILLE LINE:  '<!-->'",
      "     VISIBLE:  '<!-->', cursor=1",
-     "SPEECH OUTPUT: '<!-->'",
-     "SPEECH OUTPUT: 'link'"]))
+     "SPEECH OUTPUT: '<!--> link'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
@@ -42,8 +41,7 @@ sequence.append(utils.AssertPresentationAction(
     "4. Line Down",
     ["BRAILLE LINE:  '<!DOCTYPE>'",
      "     VISIBLE:  '<!DOCTYPE>', cursor=1",
-     "SPEECH OUTPUT: '<!DOCTYPE>'",
-     "SPEECH OUTPUT: 'link'"]))
+     "SPEECH OUTPUT: '<!DOCTYPE> link'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
@@ -51,8 +49,7 @@ sequence.append(utils.AssertPresentationAction(
     "5. Line Down",
     ["BRAILLE LINE:  '<a>'",
      "     VISIBLE:  '<a>', cursor=1",
-     "SPEECH OUTPUT: '<a>'",
-     "SPEECH OUTPUT: 'link'"]))
+     "SPEECH OUTPUT: '<a> link'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
@@ -60,8 +57,7 @@ sequence.append(utils.AssertPresentationAction(
     "6. Line Down",
     ["BRAILLE LINE:  '<abbr>'",
      "     VISIBLE:  '<abbr>', cursor=1",
-     "SPEECH OUTPUT: '<abbr>'",
-     "SPEECH OUTPUT: 'link'"]))
+     "SPEECH OUTPUT: '<abbr> link'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
@@ -69,8 +65,7 @@ sequence.append(utils.AssertPresentationAction(
     "7. Line Down",
     ["BRAILLE LINE:  '<acronym>'",
      "     VISIBLE:  '<acronym>', cursor=1",
-     "SPEECH OUTPUT: '<acronym>'",
-     "SPEECH OUTPUT: 'link'"]))
+     "SPEECH OUTPUT: '<acronym> link'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
@@ -78,8 +73,7 @@ sequence.append(utils.AssertPresentationAction(
     "8. Line Up",
     ["BRAILLE LINE:  '<abbr>'",
      "     VISIBLE:  '<abbr>', cursor=1",
-     "SPEECH OUTPUT: '<abbr>'",
-     "SPEECH OUTPUT: 'link'"]))
+     "SPEECH OUTPUT: '<abbr> link'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
@@ -87,8 +81,7 @@ sequence.append(utils.AssertPresentationAction(
     "9. Line Up",
     ["BRAILLE LINE:  '<a>'",
      "     VISIBLE:  '<a>', cursor=1",
-     "SPEECH OUTPUT: '<a>'",
-     "SPEECH OUTPUT: 'link'"]))
+     "SPEECH OUTPUT: '<a> link'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
@@ -96,8 +89,7 @@ sequence.append(utils.AssertPresentationAction(
     "10. Line Up",
     ["BRAILLE LINE:  '<!DOCTYPE>'",
      "     VISIBLE:  '<!DOCTYPE>', cursor=1",
-     "SPEECH OUTPUT: '<!DOCTYPE>'",
-     "SPEECH OUTPUT: 'link'"]))
+     "SPEECH OUTPUT: '<!DOCTYPE> link'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
@@ -105,21 +97,12 @@ sequence.append(utils.AssertPresentationAction(
     "11. Line Up",
     ["BRAILLE LINE:  '<!-->'",
      "     VISIBLE:  '<!-->', cursor=1",
-     "SPEECH OUTPUT: '<!-->'",
-     "SPEECH OUTPUT: 'link'"]))
+     "SPEECH OUTPUT: '<!--> link'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
 sequence.append(utils.AssertPresentationAction(
     "12. Line Up",
-    ["BRAILLE LINE:  ''",
-     "     VISIBLE:  '', cursor=1",
-     "SPEECH OUTPUT: 'blank'"]))
-
-sequence.append(utils.StartRecordingAction())
-sequence.append(KeyComboAction("Up"))
-sequence.append(utils.AssertPresentationAction(
-    "13. Line Up",
     ["BRAILLE LINE:  'HTML Tags'",
      "     VISIBLE:  'HTML Tags', cursor=1",
      "SPEECH OUTPUT: 'HTML Tags'"]))
@@ -127,7 +110,7 @@ sequence.append(utils.AssertPresentationAction(
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
 sequence.append(utils.AssertPresentationAction(
-    "14. Line Up",
+    "13. Line Up",
     ["BRAILLE LINE:  'Here are some links'",
      "     VISIBLE:  'Here are some links', cursor=1",
      "SPEECH OUTPUT: 'Here are some links'"]))
diff --git a/test/keystrokes/firefox/line_nav_twitter_bug.py b/test/keystrokes/firefox/line_nav_twitter_bug.py
index 601d9b0..8096a63 100644
--- a/test/keystrokes/firefox/line_nav_twitter_bug.py
+++ b/test/keystrokes/firefox/line_nav_twitter_bug.py
@@ -21,9 +21,7 @@ sequence.append(utils.AssertPresentationAction(
     "2. Line Down",
     ["BRAILLE LINE:  'foo image h2'",
      "     VISIBLE:  'foo image h2', cursor=1",
-     "SPEECH OUTPUT: 'foo'",
-     "SPEECH OUTPUT: 'image link'",
-     "SPEECH OUTPUT: 'heading level 2'"]))
+     "SPEECH OUTPUT: 'foo image link heading level 2'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
@@ -55,9 +53,7 @@ sequence.append(utils.AssertPresentationAction(
     "6. Line Up",
     ["BRAILLE LINE:  'foo image h2'",
      "     VISIBLE:  'foo image h2', cursor=1",
-     "SPEECH OUTPUT: 'foo'",
-     "SPEECH OUTPUT: 'image link'",
-     "SPEECH OUTPUT: 'heading level 2'"]))
+     "SPEECH OUTPUT: 'foo image link heading level 2'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
diff --git a/test/keystrokes/firefox/line_nav_wiki_down.py b/test/keystrokes/firefox/line_nav_wiki_down.py
index 12c2c09..2cc3a2f 100644
--- a/test/keystrokes/firefox/line_nav_wiki_down.py
+++ b/test/keystrokes/firefox/line_nav_wiki_down.py
@@ -20,20 +20,13 @@ sequence.append(utils.AssertPresentationAction(
     "1. Top of file",
     ["BRAILLE LINE:  'Home News Projects Art Support Development Community'",
      "     VISIBLE:  'Home News Projects Art Support D', cursor=1",
-     "SPEECH OUTPUT: 'Home'",
-     "SPEECH OUTPUT: 'link'",
-     "SPEECH OUTPUT: 'News'",
-     "SPEECH OUTPUT: 'link'",
-     "SPEECH OUTPUT: 'Projects'",
-     "SPEECH OUTPUT: 'link'",
-     "SPEECH OUTPUT: 'Art'",
-     "SPEECH OUTPUT: 'link'",
-     "SPEECH OUTPUT: 'Support'",
-     "SPEECH OUTPUT: 'link'",
-     "SPEECH OUTPUT: 'Development'",
-     "SPEECH OUTPUT: 'link'",
-     "SPEECH OUTPUT: 'Community'",
-     "SPEECH OUTPUT: 'link'"]))
+     "SPEECH OUTPUT: 'Home link'",
+     "SPEECH OUTPUT: 'News link'",
+     "SPEECH OUTPUT: 'Projects link'",
+     "SPEECH OUTPUT: 'Art link'",
+     "SPEECH OUTPUT: 'Support link'",
+     "SPEECH OUTPUT: 'Development link'",
+     "SPEECH OUTPUT: 'Community link'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
@@ -43,8 +36,8 @@ sequence.append(utils.AssertPresentationAction(
      "     VISIBLE:  'live.gnome.org  h1 Search $l Tit', cursor=1",
      "SPEECH OUTPUT: 'live.gnome.org heading level 1'",
      "SPEECH OUTPUT: 'entry Search'",
-     "SPEECH OUTPUT: 'Titles push button grayed'",
-     "SPEECH OUTPUT: 'Text push button grayed'"]))
+     "SPEECH OUTPUT: 'Titles push button'",
+     "SPEECH OUTPUT: 'Text push button'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
@@ -52,16 +45,11 @@ sequence.append(utils.AssertPresentationAction(
     "3. Line Down",
     ["BRAILLE LINE:  'Home RecentChanges FindPage HelpContents Orca'",
      "     VISIBLE:  'Home RecentChanges FindPage Help', cursor=1",
-     "SPEECH OUTPUT: 'Home'",
-     "SPEECH OUTPUT: 'link'",
-     "SPEECH OUTPUT: 'RecentChanges'",
-     "SPEECH OUTPUT: 'link'",
-     "SPEECH OUTPUT: 'FindPage'",
-     "SPEECH OUTPUT: 'link'",
-     "SPEECH OUTPUT: 'HelpContents'",
-     "SPEECH OUTPUT: 'link'",
-     "SPEECH OUTPUT: 'Orca'",
-     "SPEECH OUTPUT: 'link'"]))
+     "SPEECH OUTPUT: 'Home link'",
+     "SPEECH OUTPUT: 'RecentChanges link'",
+     "SPEECH OUTPUT: 'FindPage link'",
+     "SPEECH OUTPUT: 'HelpContents link'",
+     "SPEECH OUTPUT: 'Orca link'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
@@ -69,8 +57,7 @@ sequence.append(utils.AssertPresentationAction(
     "4. Line Down",
     ["BRAILLE LINE:  'en Español'",
      "     VISIBLE:  'en Español', cursor=1",
-     "SPEECH OUTPUT: 'en Español'",
-     "SPEECH OUTPUT: 'link image'"]))
+     "SPEECH OUTPUT: 'en Español link'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
@@ -78,20 +65,15 @@ sequence.append(utils.AssertPresentationAction(
     "5. Line Down",
     ["BRAILLE LINE:  'Home | Download/Installation | Configuration/Use | Accessible Applications | Mailing 
List \('",
      "     VISIBLE:  'Home | Download/Installation | C', cursor=1",
-     "SPEECH OUTPUT: 'Home'",
-     "SPEECH OUTPUT: 'link'",
+     "SPEECH OUTPUT: 'Home link'",
      "SPEECH OUTPUT: '|'",
-     "SPEECH OUTPUT: 'Download/Installation'",
-     "SPEECH OUTPUT: 'link'",
+     "SPEECH OUTPUT: 'Download/Installation link'",
      "SPEECH OUTPUT: '|'",
-     "SPEECH OUTPUT: 'Configuration/Use'",
-     "SPEECH OUTPUT: 'link'",
+     "SPEECH OUTPUT: 'Configuration/Use link'",
      "SPEECH OUTPUT: '|'",
-     "SPEECH OUTPUT: 'Accessible Applications'",
-     "SPEECH OUTPUT: 'link'",
+     "SPEECH OUTPUT: 'Accessible Applications link'",
      "SPEECH OUTPUT: '|'",
-     "SPEECH OUTPUT: 'Mailing List'",
-     "SPEECH OUTPUT: 'link image'",
+     "SPEECH OUTPUT: 'Mailing List link'",
      "SPEECH OUTPUT: '('"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -100,14 +82,11 @@ sequence.append(utils.AssertPresentationAction(
     "6. Line Down",
     ["BRAILLE LINE:  'Archives\) | FAQ | DocIndex'",
      "     VISIBLE:  'Archives\) | FAQ | DocIndex', cursor=1",
-     "SPEECH OUTPUT: 'Archives'",
-     "SPEECH OUTPUT: 'link image'",
+     "SPEECH OUTPUT: 'Archives link'",
      "SPEECH OUTPUT: ') |'",
-     "SPEECH OUTPUT: 'FAQ'",
-     "SPEECH OUTPUT: 'link'",
+     "SPEECH OUTPUT: 'FAQ link'",
      "SPEECH OUTPUT: '|'",
-     "SPEECH OUTPUT: 'DocIndex'",
-     "SPEECH OUTPUT: 'link'"]))
+     "SPEECH OUTPUT: 'DocIndex link'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
@@ -132,8 +111,7 @@ sequence.append(utils.AssertPresentationAction(
     ["BRAILLE LINE:  'HOT HOT HOT: Notes on access to Firefox 3.0'",
      "     VISIBLE:  'HOT HOT HOT: Notes on access to ', cursor=1",
      "SPEECH OUTPUT: 'HOT HOT HOT: Notes on'",
-     "SPEECH OUTPUT: 'access to Firefox 3.0'",
-     "SPEECH OUTPUT: 'link'"]))
+     "SPEECH OUTPUT: 'access to Firefox 3.0 link'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
@@ -150,8 +128,7 @@ sequence.append(utils.AssertPresentationAction(
     ["BRAILLE LINE:  '1. Welcome to Orca!'",
      "     VISIBLE:  '1. Welcome to Orca!', cursor=1",
      "SPEECH OUTPUT: '1.'",
-     "SPEECH OUTPUT: 'Welcome to Orca!'",
-     "SPEECH OUTPUT: 'link'"]))
+     "SPEECH OUTPUT: 'Welcome to Orca! link'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
@@ -160,8 +137,7 @@ sequence.append(utils.AssertPresentationAction(
     ["BRAILLE LINE:  '2. About'",
      "     VISIBLE:  '2. About', cursor=1",
      "SPEECH OUTPUT: '2.'",
-     "SPEECH OUTPUT: 'About'",
-     "SPEECH OUTPUT: 'link'"]))
+     "SPEECH OUTPUT: 'About link'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
@@ -170,8 +146,7 @@ sequence.append(utils.AssertPresentationAction(
     ["BRAILLE LINE:  '3. Audio Guides'",
      "     VISIBLE:  '3. Audio Guides', cursor=1",
      "SPEECH OUTPUT: '3.'",
-     "SPEECH OUTPUT: 'Audio Guides'",
-     "SPEECH OUTPUT: 'link'"]))
+     "SPEECH OUTPUT: 'Audio Guides link'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
@@ -180,8 +155,7 @@ sequence.append(utils.AssertPresentationAction(
     ["BRAILLE LINE:  '4. Download/Installation'",
      "     VISIBLE:  '4. Download/Installation', cursor=1",
      "SPEECH OUTPUT: '4.'",
-     "SPEECH OUTPUT: 'Download/Installation'",
-     "SPEECH OUTPUT: 'link'"]))
+     "SPEECH OUTPUT: 'Download/Installation link'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
@@ -190,8 +164,7 @@ sequence.append(utils.AssertPresentationAction(
     ["BRAILLE LINE:  '5. Configuration/Use'",
      "     VISIBLE:  '5. Configuration/Use', cursor=1",
      "SPEECH OUTPUT: '5.'",
-     "SPEECH OUTPUT: 'Configuration/Use'",
-     "SPEECH OUTPUT: 'link'"]))
+     "SPEECH OUTPUT: 'Configuration/Use link'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
@@ -200,8 +173,7 @@ sequence.append(utils.AssertPresentationAction(
     ["BRAILLE LINE:  '6. Accessible Applications'",
      "     VISIBLE:  '6. Accessible Applications', cursor=1",
      "SPEECH OUTPUT: '6.'",
-     "SPEECH OUTPUT: 'Accessible Applications'",
-     "SPEECH OUTPUT: 'link'"]))
+     "SPEECH OUTPUT: 'Accessible Applications link'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
@@ -210,8 +182,7 @@ sequence.append(utils.AssertPresentationAction(
     ["BRAILLE LINE:  '7. How Can I Help?'",
      "     VISIBLE:  '7. How Can I Help?', cursor=1",
      "SPEECH OUTPUT: '7.'",
-     "SPEECH OUTPUT: 'How Can I Help?'",
-     "SPEECH OUTPUT: 'link'"]))
+     "SPEECH OUTPUT: 'How Can I Help? link'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
@@ -220,8 +191,7 @@ sequence.append(utils.AssertPresentationAction(
     ["BRAILLE LINE:  '8. More Information'",
      "     VISIBLE:  '8. More Information', cursor=1",
      "SPEECH OUTPUT: '8.'",
-     "SPEECH OUTPUT: 'More Information'",
-     "SPEECH OUTPUT: 'link'"]))
+     "SPEECH OUTPUT: 'More Information link'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
@@ -287,7 +257,7 @@ sequence.append(utils.AssertPresentationAction(
      "     VISIBLE:  'been led by the Accessibility Pr', cursor=1",
      "SPEECH OUTPUT: 'been led by the'",
      "SPEECH OUTPUT: 'Accessibility Program Office of Sun'",
-     "SPEECH OUTPUT: 'link image'"]))
+     "SPEECH OUTPUT: 'link'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
@@ -296,7 +266,7 @@ sequence.append(utils.AssertPresentationAction(
     ["BRAILLE LINE:  'Microsystems, Inc. with contributions from many'",
      "     VISIBLE:  'Microsystems, Inc. with contribu', cursor=1",
      "SPEECH OUTPUT: 'Microsystems, Inc.'",
-     "SPEECH OUTPUT: 'link image'",
+     "SPEECH OUTPUT: 'link'",
      "SPEECH OUTPUT: 'with'",
      "SPEECH OUTPUT: 'contributions from many'",
      "SPEECH OUTPUT: 'link'"]))
@@ -326,8 +296,7 @@ sequence.append(utils.AssertPresentationAction(
     ["BRAILLE LINE:  'problems in other components, is maintained in Bugzilla \(please see our notes on how 
we'",
      "     VISIBLE:  'problems in other components, is', cursor=1",
      "SPEECH OUTPUT: 'problems in other components, is maintained in'",
-     "SPEECH OUTPUT: 'Bugzilla'",
-     "SPEECH OUTPUT: 'link image'",
+     "SPEECH OUTPUT: 'Bugzilla link'",
      "SPEECH OUTPUT: '\(please see our'",
      "SPEECH OUTPUT: 'notes on how we'",
      "SPEECH OUTPUT: 'link'"]))
@@ -349,11 +318,9 @@ sequence.append(utils.AssertPresentationAction(
     ["BRAILLE LINE:  'Please join and participate on the Orca mailing list (archives): it's a helpful, kind, 
and'",
      "     VISIBLE:  'Please join and participate on t', cursor=1",
      "SPEECH OUTPUT: 'Please join and participate on the'",
-     "SPEECH OUTPUT: 'Orca mailing list'",
-     "SPEECH OUTPUT: 'link image'",
+     "SPEECH OUTPUT: 'Orca mailing list link'",
      "SPEECH OUTPUT: '('",
-     "SPEECH OUTPUT: 'archives'",
-     "SPEECH OUTPUT: 'link image'",
+     "SPEECH OUTPUT: 'archives link'",
      "SPEECH OUTPUT: '): it's a helpful, kind, and'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -378,8 +345,7 @@ sequence.append(utils.AssertPresentationAction(
     "35. Line Down",
     ["BRAILLE LINE:  'Darragh Ó Héiligh has created several audio guides for Orca. This is a fantastic'",
      "     VISIBLE:  'Darragh Ó Héiligh has created se', cursor=1",
-     "SPEECH OUTPUT: 'Darragh Ó Héiligh'",
-     "SPEECH OUTPUT: 'link image'",
+     "SPEECH OUTPUT: 'Darragh Ó Héiligh link'",
      "SPEECH OUTPUT: 'has created several audio guides for Orca. This is a fantastic'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -390,7 +356,7 @@ sequence.append(utils.AssertPresentationAction(
      "     VISIBLE:  'contribution (THANKS!)!!! The au', cursor=1",
      "SPEECH OUTPUT: 'contribution (THANKS!)!!! The audio guides can be found at'",
      "SPEECH OUTPUT: 'http://www.digitaldarragh.com'",
-     "SPEECH OUTPUT: 'link image'"]))
+     "SPEECH OUTPUT: 'link'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
@@ -399,7 +365,7 @@ sequence.append(utils.AssertPresentationAction(
     ["BRAILLE LINE:  '/linuxat.asp and include the following:'",
      "     VISIBLE:  '/linuxat.asp and include the fol', cursor=1",
      "SPEECH OUTPUT: '/linuxat.asp'",
-     "SPEECH OUTPUT: 'link image'",
+     "SPEECH OUTPUT: 'link'",
      "SPEECH OUTPUT: 'and include the following:'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -409,8 +375,7 @@ sequence.append(utils.AssertPresentationAction(
     ["BRAILLE LINE:  '• Walk through of the installation of Ubuntu 7.4. Very helpful tutorial'",
      "     VISIBLE:  '• Walk through of the installati', cursor=1",
      "SPEECH OUTPUT: '•'",
-     "SPEECH OUTPUT: 'Walk through of the installation of Ubuntu 7.4. Very helpful tutorial'",
-     "SPEECH OUTPUT: 'link image'"]))
+     "SPEECH OUTPUT: 'Walk through of the installation of Ubuntu 7.4. Very helpful tutorial link'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
@@ -419,8 +384,7 @@ sequence.append(utils.AssertPresentationAction(
     ["BRAILLE LINE:  '• Review of Fedora 7 and the Orca screen reader for the Gnome graphical desktop'",
      "     VISIBLE:  '• Review of Fedora 7 and the Orc', cursor=1",
      "SPEECH OUTPUT: '•'",
-     "SPEECH OUTPUT: 'Review of Fedora 7 and the Orca screen reader for the Gnome graphical desktop'",
-     "SPEECH OUTPUT: 'link image'"]))
+     "SPEECH OUTPUT: 'Review of Fedora 7 and the Orca screen reader for the Gnome graphical desktop link'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
@@ -429,8 +393,7 @@ sequence.append(utils.AssertPresentationAction(
     ["BRAILLE LINE:  '• Guide to installing the latest versions of Firefox and Orca'",
      "     VISIBLE:  '• Guide to installing the latest', cursor=1",
      "SPEECH OUTPUT: '•'",
-     "SPEECH OUTPUT: 'Guide to installing the latest versions of Firefox and Orca'",
-     "SPEECH OUTPUT: 'link image'"]))
+     "SPEECH OUTPUT: 'Guide to installing the latest versions of Firefox and Orca link'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
@@ -455,8 +418,7 @@ sequence.append(utils.AssertPresentationAction(
     ["BRAILLE LINE:  'provided by default on a number of operating system distributions, including Open 
Solaris'",
      "     VISIBLE:  'provided by default on a number ', cursor=1",
      "SPEECH OUTPUT: 'provided by default on a number of operating system distributions, including'",
-     "SPEECH OUTPUT: 'Open Solaris'",
-     "SPEECH OUTPUT: 'link image'"]))
+     "SPEECH OUTPUT: 'Open Solaris link'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
@@ -465,8 +427,7 @@ sequence.append(utils.AssertPresentationAction(
     ["BRAILLE LINE:  'and Ubuntu.'",
      "     VISIBLE:  'and Ubuntu.', cursor=1",
      "SPEECH OUTPUT: 'and'",
-     "SPEECH OUTPUT: 'Ubuntu'",
-     "SPEECH OUTPUT: 'link image'",
+     "SPEECH OUTPUT: 'Ubuntu link'",
      "SPEECH OUTPUT: '.'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -476,8 +437,7 @@ sequence.append(utils.AssertPresentationAction(
     ["BRAILLE LINE:  'Please also refer to the Download/Installation page for detailed information on 
various'",
      "     VISIBLE:  'Please also refer to the Downloa', cursor=1",
      "SPEECH OUTPUT: 'Please also refer to the'",
-     "SPEECH OUTPUT: 'Download/Installation page'",
-     "SPEECH OUTPUT: 'link'",
+     "SPEECH OUTPUT: 'Download/Installation page link'",
      "SPEECH OUTPUT: 'for detailed information on various'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -520,7 +480,7 @@ sequence.append(utils.AssertPresentationAction(
      "     VISIBLE:  'designed to present information ', cursor=1",
      "SPEECH OUTPUT: 'designed to present information as you navigate the desktop using the'",
      "SPEECH OUTPUT: 'built-in navigation'",
-     "SPEECH OUTPUT: 'link image'"]))
+     "SPEECH OUTPUT: 'link'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
@@ -529,7 +489,7 @@ sequence.append(utils.AssertPresentationAction(
     ["BRAILLE LINE:  'mechanisms of GNOME. These navigation mechanisms are consistent across most'",
      "     VISIBLE:  'mechanisms of GNOME. These navig', cursor=1",
      "SPEECH OUTPUT: 'mechanisms of GNOME'",
-     "SPEECH OUTPUT: 'link image'",
+     "SPEECH OUTPUT: 'link'",
      "SPEECH OUTPUT: '. These navigation mechanisms are consistent across most'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -567,10 +527,8 @@ sequence.append(utils.AssertPresentationAction(
     ["BRAILLE LINE:  'mode to examine a window. Refer to Orca Keyboard Commands (Laptop Layout) for more'",
      "     VISIBLE:  'mode to examine a window. Refer ', cursor=1",
      "SPEECH OUTPUT: 'mode to examine a window. Refer to'",
-     "SPEECH OUTPUT: 'Orca Keyboard Commands'",
-     "SPEECH OUTPUT: 'link'",
-     "SPEECH OUTPUT: '(Laptop Layout)'",
-     "SPEECH OUTPUT: 'link'",
+     "SPEECH OUTPUT: 'Orca Keyboard Commands link'",
+     "SPEECH OUTPUT: '(Laptop Layout) link'",
      "SPEECH OUTPUT: 'for more'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -580,8 +538,7 @@ sequence.append(utils.AssertPresentationAction(
     ["BRAILLE LINE:  'information on Orca-specific keyboard commands. The Orca Configuration GUI also'",
      "     VISIBLE:  'information on Orca-specific key', cursor=1",
      "SPEECH OUTPUT: 'information on Orca-specific keyboard commands. The'",
-     "SPEECH OUTPUT: 'Orca Configuration GUI'",
-     "SPEECH OUTPUT: 'link'",
+     "SPEECH OUTPUT: 'Orca Configuration GUI link'",
      "SPEECH OUTPUT: 'also'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -599,8 +556,7 @@ sequence.append(utils.AssertPresentationAction(
     ["BRAILLE LINE:  'Please also refer to the Configuration/Use page for detailed information.'",
      "     VISIBLE:  'Please also refer to the Configu', cursor=1",
      "SPEECH OUTPUT: 'Please also refer to the'",
-     "SPEECH OUTPUT: 'Configuration/Use page'",
-     "SPEECH OUTPUT: 'link'",
+     "SPEECH OUTPUT: 'Configuration/Use page link'",
      "SPEECH OUTPUT: 'for detailed information.'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -634,8 +590,7 @@ sequence.append(utils.AssertPresentationAction(
     ["BRAILLE LINE:  'applications, OpenOffice, Firefox, and the Java platform. Some applications work 
better'",
      "     VISIBLE:  'applications, OpenOffice, Firefo', cursor=1",
      "SPEECH OUTPUT: 'applications,'",
-     "SPEECH OUTPUT: 'OpenOffice'",
-     "SPEECH OUTPUT: 'link'",
+     "SPEECH OUTPUT: 'OpenOffice link'",
      "SPEECH OUTPUT: ', Firefox, and the Java platform. Some applications work better'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -661,8 +616,7 @@ sequence.append(utils.AssertPresentationAction(
     ["BRAILLE LINE:  'On the Accessible Applications page, you will find a growing list of information 
regarding'",
      "     VISIBLE:  'On the Accessible Applications p', cursor=1",
      "SPEECH OUTPUT: 'On the'",
-     "SPEECH OUTPUT: 'Accessible Applications page'",
-     "SPEECH OUTPUT: 'link'",
+     "SPEECH OUTPUT: 'Accessible Applications page link'",
      "SPEECH OUTPUT: ', you will find a growing list of information regarding'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -704,8 +658,7 @@ sequence.append(utils.AssertPresentationAction(
     ["BRAILLE LINE:  'See also the Application Specific Settings page for how to configure settings specific 
to an'",
      "     VISIBLE:  'See also the Application Specifi', cursor=1",
      "SPEECH OUTPUT: 'See also the'",
-     "SPEECH OUTPUT: 'Application Specific Settings'",
-     "SPEECH OUTPUT: 'link'",
+     "SPEECH OUTPUT: 'Application Specific Settings link'",
      "SPEECH OUTPUT: 'page for how to configure settings specific to an'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -723,8 +676,7 @@ sequence.append(utils.AssertPresentationAction(
     ["BRAILLE LINE:  'Please also refer to the Accessible Applications page for detailed information.'",
      "     VISIBLE:  'Please also refer to the Accessi', cursor=1",
      "SPEECH OUTPUT: 'Please also refer to the'",
-     "SPEECH OUTPUT: 'Accessible Applications page'",
-     "SPEECH OUTPUT: 'link'",
+     "SPEECH OUTPUT: 'Accessible Applications page link'",
      "SPEECH OUTPUT: 'for detailed information.'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -742,8 +694,7 @@ sequence.append(utils.AssertPresentationAction(
     ["BRAILLE LINE:  'There's a bunch you can do! Please refer to the How Can I Help page for detailed'",
      "     VISIBLE:  'There's a bunch you can do! Plea', cursor=1",
      "SPEECH OUTPUT: 'There's a bunch you can do! Please refer to the'",
-     "SPEECH OUTPUT: 'How Can I Help page'",
-     "SPEECH OUTPUT: 'link'",
+     "SPEECH OUTPUT: 'How Can I Help page link'",
      "SPEECH OUTPUT: 'for detailed'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -770,8 +721,7 @@ sequence.append(utils.AssertPresentationAction(
      "     VISIBLE:  '• Frequently Asked Questions: FA', cursor=1",
      "SPEECH OUTPUT: '•'",
      "SPEECH OUTPUT: 'Frequently Asked Questions:'",
-     "SPEECH OUTPUT: 'FAQ'",
-     "SPEECH OUTPUT: 'link'"]))
+     "SPEECH OUTPUT: 'FAQ link'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
@@ -781,11 +731,9 @@ sequence.append(utils.AssertPresentationAction(
      "     VISIBLE:  '• Mailing list: orca-list gnome ', cursor=1",
      "SPEECH OUTPUT: '•'",
      "SPEECH OUTPUT: 'Mailing list:'",
-     "SPEECH OUTPUT: 'orca-list gnome org'",
-     "SPEECH OUTPUT: 'link image'",
+     "SPEECH OUTPUT: 'orca-list gnome org link'",
      "SPEECH OUTPUT: '('",
-     "SPEECH OUTPUT: 'Archives'",
-     "SPEECH OUTPUT: 'link image'",
+     "SPEECH OUTPUT: 'Archives link'",
      "SPEECH OUTPUT: ')'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -796,11 +744,9 @@ sequence.append(utils.AssertPresentationAction(
      "     VISIBLE:  '• Bug database: GNOME Bug Tracki', cursor=1",
      "SPEECH OUTPUT: '•'",
      "SPEECH OUTPUT: 'Bug database:'",
-     "SPEECH OUTPUT: 'GNOME Bug Tracking System (Bugzilla)'",
-     "SPEECH OUTPUT: 'link image'",
+     "SPEECH OUTPUT: 'GNOME Bug Tracking System (Bugzilla) link'",
      "SPEECH OUTPUT: '('",
-     "SPEECH OUTPUT: 'current bug list'",
-     "SPEECH OUTPUT: 'link image'",
+     "SPEECH OUTPUT: 'current bug list link'",
      "SPEECH OUTPUT: ')'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -811,8 +757,7 @@ sequence.append(utils.AssertPresentationAction(
      "     VISIBLE:  '• Design documents: Orca Documen', cursor=1",
      "SPEECH OUTPUT: '•'",
      "SPEECH OUTPUT: 'Design documents:'",
-     "SPEECH OUTPUT: 'Orca Documentation Series'",
-     "SPEECH OUTPUT: 'link image'"]))
+     "SPEECH OUTPUT: 'Orca Documentation Series link'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
@@ -821,8 +766,7 @@ sequence.append(utils.AssertPresentationAction(
     ["BRAILLE LINE:  '• Dive Into Python, Mark Pilgrim'",
      "     VISIBLE:  '• Dive Into Python, Mark Pilgrim', cursor=1",
      "SPEECH OUTPUT: '•'",
-     "SPEECH OUTPUT: 'Dive Into Python, Mark Pilgrim'",
-     "SPEECH OUTPUT: 'link image'"]))
+     "SPEECH OUTPUT: 'Dive Into Python, Mark Pilgrim link'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
@@ -831,8 +775,7 @@ sequence.append(utils.AssertPresentationAction(
     ["BRAILLE LINE:  '• Python in a Nutshell, Alex Martelli'",
      "     VISIBLE:  '• Python in a Nutshell, Alex Mar', cursor=1",
      "SPEECH OUTPUT: '•'",
-     "SPEECH OUTPUT: 'Python in a Nutshell, Alex Martelli'",
-     "SPEECH OUTPUT: 'link image'"]))
+     "SPEECH OUTPUT: 'Python in a Nutshell, Alex Martelli link'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
@@ -841,8 +784,7 @@ sequence.append(utils.AssertPresentationAction(
     ["BRAILLE LINE:  '• Python Pocket Reference, Mark Lutz'",
      "     VISIBLE:  '• Python Pocket Reference, Mark ', cursor=1",
      "SPEECH OUTPUT: '•'",
-     "SPEECH OUTPUT: 'Python Pocket Reference, Mark Lutz'",
-     "SPEECH OUTPUT: 'link image'"]))
+     "SPEECH OUTPUT: 'Python Pocket Reference, Mark Lutz link'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
@@ -890,8 +832,7 @@ sequence.append(utils.AssertPresentationAction(
     "89. Line Down",
     ["BRAILLE LINE:  'CategoryAccessibility'",
      "     VISIBLE:  'CategoryAccessibility', cursor=1",
-     "SPEECH OUTPUT: 'CategoryAccessibility'",
-     "SPEECH OUTPUT: 'link'"]))
+     "SPEECH OUTPUT: 'CategoryAccessibility link'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
@@ -900,8 +841,7 @@ sequence.append(utils.AssertPresentationAction(
     ["BRAILLE LINE:  'Orca (last edited 2007-12-07 22:09:22 by WillieWalker)'",
      "     VISIBLE:  'Orca (last edited 2007-12-07 22:', cursor=1",
      "SPEECH OUTPUT: 'Orca (last edited 2007-12-07 22:09:22 by'",
-     "SPEECH OUTPUT: 'WillieWalker'",
-     "SPEECH OUTPUT: 'link'",
+     "SPEECH OUTPUT: 'WillieWalker link'",
      "SPEECH OUTPUT: ')'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -918,8 +858,7 @@ sequence.append(utils.AssertPresentationAction(
     "92. Line Down",
     ["BRAILLE LINE:  'Login'",
      "     VISIBLE:  'Login', cursor=1",
-     "SPEECH OUTPUT: 'Login'",
-     "SPEECH OUTPUT: 'link'"]))
+     "SPEECH OUTPUT: 'Login link'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
@@ -943,8 +882,7 @@ sequence.append(utils.AssertPresentationAction(
     "95. Line Down",
     ["BRAILLE LINE:  'Info'",
      "     VISIBLE:  'Info', cursor=1",
-     "SPEECH OUTPUT: 'Info'",
-     "SPEECH OUTPUT: 'link'"]))
+     "SPEECH OUTPUT: 'Info link'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
@@ -952,17 +890,15 @@ sequence.append(utils.AssertPresentationAction(
     "96. Line Down",
     ["BRAILLE LINE:  'Attachments'",
      "     VISIBLE:  'Attachments', cursor=1",
-     "SPEECH OUTPUT: 'Attachments'",
-     "SPEECH OUTPUT: 'link'"]))
+     "SPEECH OUTPUT: 'Attachments link'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
 sequence.append(utils.AssertPresentationAction(
     "97. Line Down",
-    ["KNOWN ISSUE: This is not correct",
-     "BRAILLE LINE:  'More Actions: combo box'",
+    ["BRAILLE LINE:  'More Actions: combo box'",
      "     VISIBLE:  'More Actions: combo box', cursor=1",
-     "SPEECH OUTPUT: 'Attachments More Actions: combo box'"]))
+     "SPEECH OUTPUT: 'More Actions: combo box'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
@@ -986,8 +922,7 @@ sequence.append(utils.AssertPresentationAction(
     "100. Line Down",
     ["BRAILLE LINE:  'GnomeWorldWide image'",
      "     VISIBLE:  'GnomeWorldWide image', cursor=1",
-     "SPEECH OUTPUT: 'GnomeWorldWide'",
-     "SPEECH OUTPUT: 'image link'"]))
+     "SPEECH OUTPUT: 'GnomeWorldWide image link'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
@@ -996,8 +931,7 @@ sequence.append(utils.AssertPresentationAction(
     ["BRAILLE LINE:  'Copyright \xa9 2005, 2006, 2007 The GNOME Project.'",
      "     VISIBLE:  'Copyright \xa9 2005, 2006, 2007 The', cursor=1",
      "SPEECH OUTPUT: 'Copyright \xa9 2005, 2006, 2007'",
-     "SPEECH OUTPUT: 'The GNOME Project'",
-     "SPEECH OUTPUT: 'link'",
+     "SPEECH OUTPUT: 'The GNOME Project link'",
      "SPEECH OUTPUT: '.'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -1007,8 +941,7 @@ sequence.append(utils.AssertPresentationAction(
     ["BRAILLE LINE:  'Hosted by Red Hat.'",
      "     VISIBLE:  'Hosted by Red Hat.', cursor=1",
      "SPEECH OUTPUT: 'Hosted by'",
-     "SPEECH OUTPUT: 'Red Hat'",
-     "SPEECH OUTPUT: 'link'",
+     "SPEECH OUTPUT: 'Red Hat link'",
      "SPEECH OUTPUT: '.'"]))
 
 sequence.append(utils.AssertionSummaryAction())
diff --git a/test/keystrokes/firefox/line_nav_wiki_up.py b/test/keystrokes/firefox/line_nav_wiki_up.py
index 668e9f3..11b814c 100644
--- a/test/keystrokes/firefox/line_nav_wiki_up.py
+++ b/test/keystrokes/firefox/line_nav_wiki_up.py
@@ -19,10 +19,9 @@ sequence.append(KeyComboAction("<Control>End"))
 sequence.append(utils.AssertPresentationAction(
     "1. Bottom of file",
     ["BRAILLE LINE:  'Hosted by Red Hat.'",
-     "     VISIBLE:  'Hosted by Red Hat.', cursor=1",
+     "     VISIBLE:  'Hosted by Red Hat.', cursor=19",
      "SPEECH OUTPUT: 'Hosted by'",
-     "SPEECH OUTPUT: 'Red Hat'",
-     "SPEECH OUTPUT: 'link'",
+     "SPEECH OUTPUT: 'Red Hat link'",
      "SPEECH OUTPUT: '.'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -32,8 +31,7 @@ sequence.append(utils.AssertPresentationAction(
     ["BRAILLE LINE:  'Copyright \xa9 2005, 2006, 2007 The GNOME Project.'",
      "     VISIBLE:  'Copyright \xa9 2005, 2006, 2007 The', cursor=1",
      "SPEECH OUTPUT: 'Copyright \xa9 2005, 2006, 2007'",
-     "SPEECH OUTPUT: 'The GNOME Project'",
-     "SPEECH OUTPUT: 'link'",
+     "SPEECH OUTPUT: 'The GNOME Project link'",
      "SPEECH OUTPUT: '.'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -42,8 +40,7 @@ sequence.append(utils.AssertPresentationAction(
     "3. Line Up",
     ["BRAILLE LINE:  'GnomeWorldWide image'",
      "     VISIBLE:  'GnomeWorldWide image', cursor=1",
-     "SPEECH OUTPUT: 'GnomeWorldWide'",
-     "SPEECH OUTPUT: 'image link'"]))
+     "SPEECH OUTPUT: 'GnomeWorldWide image link'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
@@ -65,10 +62,9 @@ sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
 sequence.append(utils.AssertPresentationAction(
     "6. Line Up",
-    ["KNOWN ISSUE: This is not correct",
-     "BRAILLE LINE:  'More Actions: combo box'",
+    ["BRAILLE LINE:  'More Actions: combo box'",
      "     VISIBLE:  'More Actions: combo box', cursor=1",
-     "SPEECH OUTPUT: 'Attachments More Actions: combo box'"]))
+     "SPEECH OUTPUT: 'More Actions: combo box'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
@@ -76,8 +72,7 @@ sequence.append(utils.AssertPresentationAction(
     "7. Line Up",
     ["BRAILLE LINE:  'Attachments'",
      "     VISIBLE:  'Attachments', cursor=1",
-     "SPEECH OUTPUT: 'Attachments'",
-     "SPEECH OUTPUT: 'link'"]))
+     "SPEECH OUTPUT: 'Attachments link'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
@@ -85,8 +80,7 @@ sequence.append(utils.AssertPresentationAction(
     "8. Line Up",
     ["BRAILLE LINE:  'Info'",
      "     VISIBLE:  'Info', cursor=1",
-     "SPEECH OUTPUT: 'Info'",
-     "SPEECH OUTPUT: 'link'"]))
+     "SPEECH OUTPUT: 'Info link'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
@@ -110,8 +104,7 @@ sequence.append(utils.AssertPresentationAction(
     "11. Line Up",
     ["BRAILLE LINE:  'Login'",
      "     VISIBLE:  'Login', cursor=1",
-     "SPEECH OUTPUT: 'Login'",
-     "SPEECH OUTPUT: 'link'"]))
+     "SPEECH OUTPUT: 'Login link'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
@@ -128,8 +121,7 @@ sequence.append(utils.AssertPresentationAction(
     ["BRAILLE LINE:  'Orca (last edited 2007-12-07 22:09:22 by WillieWalker)'",
      "     VISIBLE:  'Orca (last edited 2007-12-07 22:', cursor=1",
      "SPEECH OUTPUT: 'Orca (last edited 2007-12-07 22:09:22 by'",
-     "SPEECH OUTPUT: 'WillieWalker'",
-     "SPEECH OUTPUT: 'link'",
+     "SPEECH OUTPUT: 'WillieWalker link'",
      "SPEECH OUTPUT: ')'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -138,8 +130,7 @@ sequence.append(utils.AssertPresentationAction(
     "14. Line Up",
     ["BRAILLE LINE:  'CategoryAccessibility'",
      "     VISIBLE:  'CategoryAccessibility', cursor=1",
-     "SPEECH OUTPUT: 'CategoryAccessibility'",
-     "SPEECH OUTPUT: 'link'"]))
+     "SPEECH OUTPUT: 'CategoryAccessibility link'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
@@ -188,8 +179,7 @@ sequence.append(utils.AssertPresentationAction(
     ["BRAILLE LINE:  '• Python Pocket Reference, Mark Lutz'",
      "     VISIBLE:  '• Python Pocket Reference, Mark ', cursor=1",
      "SPEECH OUTPUT: '•'",
-     "SPEECH OUTPUT: 'Python Pocket Reference, Mark Lutz'",
-     "SPEECH OUTPUT: 'link image'"]))
+     "SPEECH OUTPUT: 'Python Pocket Reference, Mark Lutz link'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
@@ -198,8 +188,7 @@ sequence.append(utils.AssertPresentationAction(
     ["BRAILLE LINE:  '• Python in a Nutshell, Alex Martelli'",
      "     VISIBLE:  '• Python in a Nutshell, Alex Mar', cursor=1",
      "SPEECH OUTPUT: '•'",
-     "SPEECH OUTPUT: 'Python in a Nutshell, Alex Martelli'",
-     "SPEECH OUTPUT: 'link image'"]))
+     "SPEECH OUTPUT: 'Python in a Nutshell, Alex Martelli link'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
@@ -208,8 +197,7 @@ sequence.append(utils.AssertPresentationAction(
     ["BRAILLE LINE:  '• Dive Into Python, Mark Pilgrim'",
      "     VISIBLE:  '• Dive Into Python, Mark Pilgrim', cursor=1",
      "SPEECH OUTPUT: '•'",
-     "SPEECH OUTPUT: 'Dive Into Python, Mark Pilgrim'",
-     "SPEECH OUTPUT: 'link image'"]))
+     "SPEECH OUTPUT: 'Dive Into Python, Mark Pilgrim link'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
@@ -219,8 +207,7 @@ sequence.append(utils.AssertPresentationAction(
      "     VISIBLE:  '• Design documents: Orca Documen', cursor=1",
      "SPEECH OUTPUT: '•'",
      "SPEECH OUTPUT: 'Design documents:'",
-     "SPEECH OUTPUT: 'Orca Documentation Series'",
-     "SPEECH OUTPUT: 'link image'"]))
+     "SPEECH OUTPUT: 'Orca Documentation Series link'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
@@ -230,11 +217,9 @@ sequence.append(utils.AssertPresentationAction(
      "     VISIBLE:  '• Bug database: GNOME Bug Tracki', cursor=1",
      "SPEECH OUTPUT: '•'",
      "SPEECH OUTPUT: 'Bug database:'",
-     "SPEECH OUTPUT: 'GNOME Bug Tracking System (Bugzilla)'",
-     "SPEECH OUTPUT: 'link image'",
+     "SPEECH OUTPUT: 'GNOME Bug Tracking System (Bugzilla) link'",
      "SPEECH OUTPUT: '('",
-     "SPEECH OUTPUT: 'current bug list'",
-     "SPEECH OUTPUT: 'link image'",
+     "SPEECH OUTPUT: 'current bug list link'",
      "SPEECH OUTPUT: ')'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -245,11 +230,9 @@ sequence.append(utils.AssertPresentationAction(
      "     VISIBLE:  '• Mailing list: orca-list gnome ', cursor=1",
      "SPEECH OUTPUT: '•'",
      "SPEECH OUTPUT: 'Mailing list:'",
-     "SPEECH OUTPUT: 'orca-list gnome org'",
-     "SPEECH OUTPUT: 'link image'",
+     "SPEECH OUTPUT: 'orca-list gnome org link'",
      "SPEECH OUTPUT: '('",
-     "SPEECH OUTPUT: 'Archives'",
-     "SPEECH OUTPUT: 'link image'",
+     "SPEECH OUTPUT: 'Archives link'",
      "SPEECH OUTPUT: ')'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -260,8 +243,7 @@ sequence.append(utils.AssertPresentationAction(
      "     VISIBLE:  '• Frequently Asked Questions: FA', cursor=1",
      "SPEECH OUTPUT: '•'",
      "SPEECH OUTPUT: 'Frequently Asked Questions:'",
-     "SPEECH OUTPUT: 'FAQ'",
-     "SPEECH OUTPUT: 'link'"]))
+     "SPEECH OUTPUT: 'FAQ link'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
@@ -286,8 +268,7 @@ sequence.append(utils.AssertPresentationAction(
     ["BRAILLE LINE:  'There's a bunch you can do! Please refer to the How Can I Help page for detailed'",
      "     VISIBLE:  'There's a bunch you can do! Plea', cursor=1",
      "SPEECH OUTPUT: 'There's a bunch you can do! Please refer to the'",
-     "SPEECH OUTPUT: 'How Can I Help page'",
-     "SPEECH OUTPUT: 'link'",
+     "SPEECH OUTPUT: 'How Can I Help page link'",
      "SPEECH OUTPUT: 'for detailed'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -305,8 +286,7 @@ sequence.append(utils.AssertPresentationAction(
     ["BRAILLE LINE:  'Please also refer to the Accessible Applications page for detailed information.'",
      "     VISIBLE:  'Please also refer to the Accessi', cursor=1",
      "SPEECH OUTPUT: 'Please also refer to the'",
-     "SPEECH OUTPUT: 'Accessible Applications page'",
-     "SPEECH OUTPUT: 'link'",
+     "SPEECH OUTPUT: 'Accessible Applications page link'",
      "SPEECH OUTPUT: 'for detailed information.'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -324,8 +304,7 @@ sequence.append(utils.AssertPresentationAction(
     ["BRAILLE LINE:  'See also the Application Specific Settings page for how to configure settings specific 
to an'",
      "     VISIBLE:  'See also the Application Specifi', cursor=1",
      "SPEECH OUTPUT: 'See also the'",
-     "SPEECH OUTPUT: 'Application Specific Settings'",
-     "SPEECH OUTPUT: 'link'",
+     "SPEECH OUTPUT: 'Application Specific Settings link'",
      "SPEECH OUTPUT: 'page for how to configure settings specific to an'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -367,8 +346,7 @@ sequence.append(utils.AssertPresentationAction(
     ["BRAILLE LINE:  'On the Accessible Applications page, you will find a growing list of information 
regarding'",
      "     VISIBLE:  'On the Accessible Applications p', cursor=1",
      "SPEECH OUTPUT: 'On the'",
-     "SPEECH OUTPUT: 'Accessible Applications page'",
-     "SPEECH OUTPUT: 'link'",
+     "SPEECH OUTPUT: 'Accessible Applications page link'",
      "SPEECH OUTPUT: ', you will find a growing list of information regarding'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -394,8 +372,7 @@ sequence.append(utils.AssertPresentationAction(
     ["BRAILLE LINE:  'applications, OpenOffice, Firefox, and the Java platform. Some applications work 
better'",
      "     VISIBLE:  'applications, OpenOffice, Firefo', cursor=1",
      "SPEECH OUTPUT: 'applications,'",
-     "SPEECH OUTPUT: 'OpenOffice'",
-     "SPEECH OUTPUT: 'link'",
+     "SPEECH OUTPUT: 'OpenOffice link'",
      "SPEECH OUTPUT: ', Firefox, and the Java platform. Some applications work better'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -429,8 +406,7 @@ sequence.append(utils.AssertPresentationAction(
     ["BRAILLE LINE:  'Please also refer to the Configuration/Use page for detailed information.'",
      "     VISIBLE:  'Please also refer to the Configu', cursor=1",
      "SPEECH OUTPUT: 'Please also refer to the'",
-     "SPEECH OUTPUT: 'Configuration/Use page'",
-     "SPEECH OUTPUT: 'link'",
+     "SPEECH OUTPUT: 'Configuration/Use page link'",
      "SPEECH OUTPUT: 'for detailed information.'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -448,8 +424,7 @@ sequence.append(utils.AssertPresentationAction(
     ["BRAILLE LINE:  'information on Orca-specific keyboard commands. The Orca Configuration GUI also'",
      "     VISIBLE:  'information on Orca-specific key', cursor=1",
      "SPEECH OUTPUT: 'information on Orca-specific keyboard commands. The'",
-     "SPEECH OUTPUT: 'Orca Configuration GUI'",
-     "SPEECH OUTPUT: 'link'",
+     "SPEECH OUTPUT: 'Orca Configuration GUI link'",
      "SPEECH OUTPUT: 'also'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -459,10 +434,8 @@ sequence.append(utils.AssertPresentationAction(
     ["BRAILLE LINE:  'mode to examine a window. Refer to Orca Keyboard Commands \(Laptop Layout\) for more'",
      "     VISIBLE:  'mode to examine a window. Refer ', cursor=1",
      "SPEECH OUTPUT: 'mode to examine a window. Refer to'",
-     "SPEECH OUTPUT: 'Orca Keyboard Commands'",
-     "SPEECH OUTPUT: 'link'",
-     "SPEECH OUTPUT: '\(Laptop Layout\)'",
-     "SPEECH OUTPUT: 'link'",
+     "SPEECH OUTPUT: 'Orca Keyboard Commands link'",
+     "SPEECH OUTPUT: '\(Laptop Layout\) link'",
      "SPEECH OUTPUT: 'for more'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -500,7 +473,7 @@ sequence.append(utils.AssertPresentationAction(
     ["BRAILLE LINE:  'mechanisms of GNOME. These navigation mechanisms are consistent across most'",
      "     VISIBLE:  'mechanisms of GNOME. These navig', cursor=1",
      "SPEECH OUTPUT: 'mechanisms of GNOME'",
-     "SPEECH OUTPUT: 'link image'",
+     "SPEECH OUTPUT: 'link'",
      "SPEECH OUTPUT: '. These navigation mechanisms are consistent across most'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -511,7 +484,7 @@ sequence.append(utils.AssertPresentationAction(
      "     VISIBLE:  'designed to present information ', cursor=1",
      "SPEECH OUTPUT: 'designed to present information as you navigate the desktop using the'",
      "SPEECH OUTPUT: 'built-in navigation'",
-     "SPEECH OUTPUT: 'link image'"]))
+     "SPEECH OUTPUT: 'link'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
@@ -552,8 +525,7 @@ sequence.append(utils.AssertPresentationAction(
     ["BRAILLE LINE:  'Please also refer to the Download/Installation page for detailed information on 
various'",
      "     VISIBLE:  'Please also refer to the Downloa', cursor=1",
      "SPEECH OUTPUT: 'Please also refer to the'",
-     "SPEECH OUTPUT: 'Download/Installation page'",
-     "SPEECH OUTPUT: 'link'",
+     "SPEECH OUTPUT: 'Download/Installation page link'",
      "SPEECH OUTPUT: 'for detailed information on various'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -563,8 +535,7 @@ sequence.append(utils.AssertPresentationAction(
     ["BRAILLE LINE:  'and Ubuntu.'",
      "     VISIBLE:  'and Ubuntu.', cursor=1",
      "SPEECH OUTPUT: 'and'",
-     "SPEECH OUTPUT: 'Ubuntu'",
-     "SPEECH OUTPUT: 'link image'",
+     "SPEECH OUTPUT: 'Ubuntu link'",
      "SPEECH OUTPUT: '.'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -574,8 +545,7 @@ sequence.append(utils.AssertPresentationAction(
     ["BRAILLE LINE:  'provided by default on a number of operating system distributions, including Open 
Solaris'",
      "     VISIBLE:  'provided by default on a number ', cursor=1",
      "SPEECH OUTPUT: 'provided by default on a number of operating system distributions, including'",
-     "SPEECH OUTPUT: 'Open Solaris'",
-     "SPEECH OUTPUT: 'link image'"]))
+     "SPEECH OUTPUT: 'Open Solaris link'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
@@ -600,8 +570,7 @@ sequence.append(utils.AssertPresentationAction(
     ["BRAILLE LINE:  '• Guide to installing the latest versions of Firefox and Orca'",
      "     VISIBLE:  '• Guide to installing the latest', cursor=1",
      "SPEECH OUTPUT: '•'",
-     "SPEECH OUTPUT: 'Guide to installing the latest versions of Firefox and Orca'",
-     "SPEECH OUTPUT: 'link image'"]))
+     "SPEECH OUTPUT: 'Guide to installing the latest versions of Firefox and Orca link'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
@@ -610,8 +579,7 @@ sequence.append(utils.AssertPresentationAction(
     ["BRAILLE LINE:  '• Review of Fedora 7 and the Orca screen reader for the Gnome graphical desktop'",
      "     VISIBLE:  '• Review of Fedora 7 and the Orc', cursor=1",
      "SPEECH OUTPUT: '•'",
-     "SPEECH OUTPUT: 'Review of Fedora 7 and the Orca screen reader for the Gnome graphical desktop'",
-     "SPEECH OUTPUT: 'link image'"]))
+     "SPEECH OUTPUT: 'Review of Fedora 7 and the Orca screen reader for the Gnome graphical desktop link'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
@@ -620,8 +588,7 @@ sequence.append(utils.AssertPresentationAction(
     ["BRAILLE LINE:  '• Walk through of the installation of Ubuntu 7.4. Very helpful tutorial'",
      "     VISIBLE:  '• Walk through of the installati', cursor=1",
      "SPEECH OUTPUT: '•'",
-     "SPEECH OUTPUT: 'Walk through of the installation of Ubuntu 7.4. Very helpful tutorial'",
-     "SPEECH OUTPUT: 'link image'"]))
+     "SPEECH OUTPUT: 'Walk through of the installation of Ubuntu 7.4. Very helpful tutorial link'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
@@ -630,7 +597,7 @@ sequence.append(utils.AssertPresentationAction(
     ["BRAILLE LINE:  '/linuxat.asp and include the following:'",
      "     VISIBLE:  '/linuxat.asp and include the fol', cursor=1",
      "SPEECH OUTPUT: '/linuxat.asp'",
-     "SPEECH OUTPUT: 'link image'",
+     "SPEECH OUTPUT: 'link'",
      "SPEECH OUTPUT: 'and include the following:'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -641,7 +608,7 @@ sequence.append(utils.AssertPresentationAction(
      "     VISIBLE:  'contribution (THANKS!)!!! The au', cursor=1",
      "SPEECH OUTPUT: 'contribution (THANKS!)!!! The audio guides can be found at'",
      "SPEECH OUTPUT: 'http://www.digitaldarragh.com'",
-     "SPEECH OUTPUT: 'link image'"]))
+     "SPEECH OUTPUT: 'link'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
@@ -649,8 +616,7 @@ sequence.append(utils.AssertPresentationAction(
     "68. Line Up",
     ["BRAILLE LINE:  'Darragh Ó Héiligh has created several audio guides for Orca. This is a fantastic'",
      "     VISIBLE:  'Darragh Ó Héiligh has created se', cursor=1",
-     "SPEECH OUTPUT: 'Darragh Ó Héiligh'",
-     "SPEECH OUTPUT: 'link image'",
+     "SPEECH OUTPUT: 'Darragh Ó Héiligh link'",
      "SPEECH OUTPUT: 'has created several audio guides for Orca. This is a fantastic'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -676,11 +642,9 @@ sequence.append(utils.AssertPresentationAction(
     ["BRAILLE LINE:  'Please join and participate on the Orca mailing list (archives): it's a helpful, kind, 
and'",
      "     VISIBLE:  'Please join and participate on t', cursor=1",
      "SPEECH OUTPUT: 'Please join and participate on the'",
-     "SPEECH OUTPUT: 'Orca mailing list'",
-     "SPEECH OUTPUT: 'link image'",
+     "SPEECH OUTPUT: 'Orca mailing list link'",
      "SPEECH OUTPUT: '('",
-     "SPEECH OUTPUT: 'archives'",
-     "SPEECH OUTPUT: 'link image'",
+     "SPEECH OUTPUT: 'archives link'",
      "SPEECH OUTPUT: '): it's a helpful, kind, and'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -700,8 +664,7 @@ sequence.append(utils.AssertPresentationAction(
     ["BRAILLE LINE:  'problems in other components, is maintained in Bugzilla \(please see our notes on how 
we'",
      "     VISIBLE:  'problems in other components, is', cursor=1",
      "SPEECH OUTPUT: 'problems in other components, is maintained in'",
-     "SPEECH OUTPUT: 'Bugzilla'",
-     "SPEECH OUTPUT: 'link image'",
+     "SPEECH OUTPUT: 'Bugzilla link'",
      "SPEECH OUTPUT: '\(please see our'",
      "SPEECH OUTPUT: 'notes on how we'",
      "SPEECH OUTPUT: 'link'"]))
@@ -731,7 +694,7 @@ sequence.append(utils.AssertPresentationAction(
     ["BRAILLE LINE:  'Microsystems, Inc. with contributions from many'",
      "     VISIBLE:  'Microsystems, Inc. with contribu', cursor=1",
      "SPEECH OUTPUT: 'Microsystems, Inc.'",
-     "SPEECH OUTPUT: 'link image'",
+     "SPEECH OUTPUT: 'link'",
      "SPEECH OUTPUT: 'with'",
      "SPEECH OUTPUT: 'contributions from many'",
      "SPEECH OUTPUT: 'link'"]))
@@ -744,7 +707,7 @@ sequence.append(utils.AssertPresentationAction(
      "     VISIBLE:  'been led by the Accessibility Pr', cursor=1",
      "SPEECH OUTPUT: 'been led by the'",
      "SPEECH OUTPUT: 'Accessibility Program Office of Sun'",
-     "SPEECH OUTPUT: 'link image'"]))
+     "SPEECH OUTPUT: 'link'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
@@ -809,8 +772,7 @@ sequence.append(utils.AssertPresentationAction(
     ["BRAILLE LINE:  '8. More Information'",
      "     VISIBLE:  '8. More Information', cursor=1",
      "SPEECH OUTPUT: '8.'",
-     "SPEECH OUTPUT: 'More Information'",
-     "SPEECH OUTPUT: 'link'"]))
+     "SPEECH OUTPUT: 'More Information link'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
@@ -819,8 +781,7 @@ sequence.append(utils.AssertPresentationAction(
     ["BRAILLE LINE:  '7. How Can I Help?'",
      "     VISIBLE:  '7. How Can I Help?', cursor=1",
      "SPEECH OUTPUT: '7.'",
-     "SPEECH OUTPUT: 'How Can I Help?'",
-     "SPEECH OUTPUT: 'link'"]))
+     "SPEECH OUTPUT: 'How Can I Help? link'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
@@ -829,8 +790,7 @@ sequence.append(utils.AssertPresentationAction(
     ["BRAILLE LINE:  '6. Accessible Applications'",
      "     VISIBLE:  '6. Accessible Applications', cursor=1",
      "SPEECH OUTPUT: '6.'",
-     "SPEECH OUTPUT: 'Accessible Applications'",
-     "SPEECH OUTPUT: 'link'"]))
+     "SPEECH OUTPUT: 'Accessible Applications link'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
@@ -839,8 +799,7 @@ sequence.append(utils.AssertPresentationAction(
     ["BRAILLE LINE:  '5. Configuration/Use'",
      "     VISIBLE:  '5. Configuration/Use', cursor=1",
      "SPEECH OUTPUT: '5.'",
-     "SPEECH OUTPUT: 'Configuration/Use'",
-     "SPEECH OUTPUT: 'link'"]))
+     "SPEECH OUTPUT: 'Configuration/Use link'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
@@ -849,8 +808,7 @@ sequence.append(utils.AssertPresentationAction(
     ["BRAILLE LINE:  '4. Download/Installation'",
      "     VISIBLE:  '4. Download/Installation', cursor=1",
      "SPEECH OUTPUT: '4.'",
-     "SPEECH OUTPUT: 'Download/Installation'",
-     "SPEECH OUTPUT: 'link'"]))
+     "SPEECH OUTPUT: 'Download/Installation link'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
@@ -859,8 +817,7 @@ sequence.append(utils.AssertPresentationAction(
     ["BRAILLE LINE:  '3. Audio Guides'",
      "     VISIBLE:  '3. Audio Guides', cursor=1",
      "SPEECH OUTPUT: '3.'",
-     "SPEECH OUTPUT: 'Audio Guides'",
-     "SPEECH OUTPUT: 'link'"]))
+     "SPEECH OUTPUT: 'Audio Guides link'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
@@ -869,8 +826,7 @@ sequence.append(utils.AssertPresentationAction(
     ["BRAILLE LINE:  '2. About'",
      "     VISIBLE:  '2. About', cursor=1",
      "SPEECH OUTPUT: '2.'",
-     "SPEECH OUTPUT: 'About'",
-     "SPEECH OUTPUT: 'link'"]))
+     "SPEECH OUTPUT: 'About link'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
@@ -879,8 +835,7 @@ sequence.append(utils.AssertPresentationAction(
     ["BRAILLE LINE:  '1. Welcome to Orca!'",
      "     VISIBLE:  '1. Welcome to Orca!', cursor=1",
      "SPEECH OUTPUT: '1.'",
-     "SPEECH OUTPUT: 'Welcome to Orca!'",
-     "SPEECH OUTPUT: 'link'"]))
+     "SPEECH OUTPUT: 'Welcome to Orca! link'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
@@ -897,8 +852,7 @@ sequence.append(utils.AssertPresentationAction(
     ["BRAILLE LINE:  'HOT HOT HOT: Notes on access to Firefox 3.0'",
      "     VISIBLE:  'HOT HOT HOT: Notes on access to ', cursor=1",
      "SPEECH OUTPUT: 'HOT HOT HOT: Notes on'",
-     "SPEECH OUTPUT: 'access to Firefox 3.0'",
-     "SPEECH OUTPUT: 'link'"]))
+     "SPEECH OUTPUT: 'access to Firefox 3.0 link'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
@@ -922,14 +876,11 @@ sequence.append(utils.AssertPresentationAction(
     "97. Line Up",
     ["BRAILLE LINE:  'Archives\) | FAQ | DocIndex'",
      "     VISIBLE:  'Archives\) | FAQ | DocIndex', cursor=1",
-     "SPEECH OUTPUT: 'Archives'",
-     "SPEECH OUTPUT: 'link image'",
+     "SPEECH OUTPUT: 'Archives link'",
      "SPEECH OUTPUT: '\) |'",
-     "SPEECH OUTPUT: 'FAQ'",
-     "SPEECH OUTPUT: 'link'",
+     "SPEECH OUTPUT: 'FAQ link'",
      "SPEECH OUTPUT: '|'",
-     "SPEECH OUTPUT: 'DocIndex'",
-     "SPEECH OUTPUT: 'link'"]))
+     "SPEECH OUTPUT: 'DocIndex link'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
@@ -937,20 +888,15 @@ sequence.append(utils.AssertPresentationAction(
     "98. Line Up",
     ["BRAILLE LINE:  'Home | Download/Installation | Configuration/Use | Accessible Applications | Mailing 
List \('",
      "     VISIBLE:  'Home | Download/Installation | C', cursor=1",
-     "SPEECH OUTPUT: 'Home'",
-     "SPEECH OUTPUT: 'link'",
+     "SPEECH OUTPUT: 'Home link'",
      "SPEECH OUTPUT: '|'",
-     "SPEECH OUTPUT: 'Download/Installation'",
-     "SPEECH OUTPUT: 'link'",
+     "SPEECH OUTPUT: 'Download/Installation link'",
      "SPEECH OUTPUT: '|'",
-     "SPEECH OUTPUT: 'Configuration/Use'",
-     "SPEECH OUTPUT: 'link'",
+     "SPEECH OUTPUT: 'Configuration/Use link'",
      "SPEECH OUTPUT: '|'",
-     "SPEECH OUTPUT: 'Accessible Applications'",
-     "SPEECH OUTPUT: 'link'",
+     "SPEECH OUTPUT: 'Accessible Applications link'",
      "SPEECH OUTPUT: '|'",
-     "SPEECH OUTPUT: 'Mailing List'",
-     "SPEECH OUTPUT: 'link image'",
+     "SPEECH OUTPUT: 'Mailing List link'",
      "SPEECH OUTPUT: '('"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -959,8 +905,7 @@ sequence.append(utils.AssertPresentationAction(
     "99. Line Up",
     ["BRAILLE LINE:  'en Español'",
      "     VISIBLE:  'en Español', cursor=1",
-     "SPEECH OUTPUT: 'en Español'",
-     "SPEECH OUTPUT: 'link image'"]))
+     "SPEECH OUTPUT: 'en Español link'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
@@ -968,16 +913,11 @@ sequence.append(utils.AssertPresentationAction(
     "100. Line Up",
     ["BRAILLE LINE:  'Home RecentChanges FindPage HelpContents Orca'",
      "     VISIBLE:  'Home RecentChanges FindPage Help', cursor=1",
-     "SPEECH OUTPUT: 'Home'",
-     "SPEECH OUTPUT: 'link'",
-     "SPEECH OUTPUT: 'RecentChanges'",
-     "SPEECH OUTPUT: 'link'",
-     "SPEECH OUTPUT: 'FindPage'",
-     "SPEECH OUTPUT: 'link'",
-     "SPEECH OUTPUT: 'HelpContents'",
-     "SPEECH OUTPUT: 'link'",
-     "SPEECH OUTPUT: 'Orca'",
-     "SPEECH OUTPUT: 'link'"]))
+     "SPEECH OUTPUT: 'Home link'",
+     "SPEECH OUTPUT: 'RecentChanges link'",
+     "SPEECH OUTPUT: 'FindPage link'",
+     "SPEECH OUTPUT: 'HelpContents link'",
+     "SPEECH OUTPUT: 'Orca link'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
@@ -987,8 +927,8 @@ sequence.append(utils.AssertPresentationAction(
      "     VISIBLE:  'live.gnome.org  h1 Search $l Tit', cursor=1",
      "SPEECH OUTPUT: 'live.gnome.org heading level 1'",
      "SPEECH OUTPUT: 'entry Search'",
-     "SPEECH OUTPUT: 'Titles push button grayed'",
-     "SPEECH OUTPUT: 'Text push button grayed'"]))
+     "SPEECH OUTPUT: 'Titles push button'",
+     "SPEECH OUTPUT: 'Text push button'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
@@ -996,20 +936,13 @@ sequence.append(utils.AssertPresentationAction(
     "102. Line Up",
     ["BRAILLE LINE:  'Home News Projects Art Support Development Community'",
      "     VISIBLE:  'Home News Projects Art Support D', cursor=1",
-     "SPEECH OUTPUT: 'Home'",
-     "SPEECH OUTPUT: 'link'",
-     "SPEECH OUTPUT: 'News'",
-     "SPEECH OUTPUT: 'link'",
-     "SPEECH OUTPUT: 'Projects'",
-     "SPEECH OUTPUT: 'link'",
-     "SPEECH OUTPUT: 'Art'",
-     "SPEECH OUTPUT: 'link'",
-     "SPEECH OUTPUT: 'Support'",
-     "SPEECH OUTPUT: 'link'",
-     "SPEECH OUTPUT: 'Development'",
-     "SPEECH OUTPUT: 'link'",
-     "SPEECH OUTPUT: 'Community'",
-     "SPEECH OUTPUT: 'link'"]))
+     "SPEECH OUTPUT: 'Home link'",
+     "SPEECH OUTPUT: 'News link'",
+     "SPEECH OUTPUT: 'Projects link'",
+     "SPEECH OUTPUT: 'Art link'",
+     "SPEECH OUTPUT: 'Support link'",
+     "SPEECH OUTPUT: 'Development link'",
+     "SPEECH OUTPUT: 'Community link'"]))
 
 sequence.append(utils.AssertionSummaryAction())
 sequence.start()
diff --git a/test/keystrokes/firefox/link_where_am_i.py b/test/keystrokes/firefox/link_where_am_i.py
index 5e18147..432de50 100644
--- a/test/keystrokes/firefox/link_where_am_i.py
+++ b/test/keystrokes/firefox/link_where_am_i.py
@@ -13,8 +13,8 @@ sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("KP_Enter"))
 sequence.append(utils.AssertPresentationAction(
     "1. Where Am I on Product summary link", 
-    ["BRAILLE LINE:  '3. Product summary (designed for maintainers)'",
-     "     VISIBLE:  'Product summary (designed for ma', cursor=1",
+    ["BRAILLE LINE:  'Product summary'",
+     "     VISIBLE:  'Product summary', cursor=1",
      "SPEECH OUTPUT: 'http link Product summary different site'"]))
 
 sequence.append(KeyComboAction("<Control>Home"))
@@ -24,8 +24,8 @@ sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("KP_Enter"))
 sequence.append(utils.AssertPresentationAction(
     "2. Where Am I on New bug link", 
-    ["BRAILLE LINE:  'New bug · Browse · Search · Reports · Account · Admin · Help'",
-     "     VISIBLE:  'New bug · Browse · Search · Repo', cursor=1",
+    ["BRAILLE LINE:  'New bug'",
+     "     VISIBLE:  'New bug', cursor=1",
      "SPEECH OUTPUT: 'http link New bug different site'"]))
 
 sequence.append(utils.AssertionSummaryAction())
diff --git a/test/keystrokes/firefox/longdesc_10.py b/test/keystrokes/firefox/longdesc_10.py
index 3043e0c..5fe5b33 100644
--- a/test/keystrokes/firefox/longdesc_10.py
+++ b/test/keystrokes/firefox/longdesc_10.py
@@ -23,10 +23,9 @@ sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("KP_Enter"))
 sequence.append(utils.AssertPresentationAction(
     "2. Having selected View Description, do a Where Am I for new location",
-    ["KNOWN ISSUE: This test fails not because of longdesc, but because jumping to any anchor in a page is 
broken",
-     "BRAILLE LINE:  'Fail if you land here h1'",
-     "     VISIBLE:  'Fail if you land here h1', cursor=1",
-     "SPEECH OUTPUT: 'heading level 1 Fail if you land here'"]))
+    ["BRAILLE LINE:  'Pass h1'",
+     "     VISIBLE:  'Pass h1', cursor=1",
+     "SPEECH OUTPUT: 'heading level 1 Pass'"]))
 
 sequence.append(utils.AssertionSummaryAction())
 sequence.start()
diff --git a/test/keystrokes/firefox/object_nav_links_in_text.py 
b/test/keystrokes/firefox/object_nav_links_in_text.py
index 8ba59bb..293dd28 100644
--- a/test/keystrokes/firefox/object_nav_links_in_text.py
+++ b/test/keystrokes/firefox/object_nav_links_in_text.py
@@ -35,22 +35,6 @@ sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
 sequence.append(utils.AssertPresentationAction(
     "4. line Down",
-    ["BRAILLE LINE:  ''",
-     "     VISIBLE:  '', cursor=1",
-     "SPEECH OUTPUT: 'blank'"]))
-
-sequence.append(utils.StartRecordingAction())
-sequence.append(KeyComboAction("Down"))
-sequence.append(utils.AssertPresentationAction(
-    "5. line Down",
-    ["BRAILLE LINE:  ''",
-     "     VISIBLE:  '', cursor=1",
-     "SPEECH OUTPUT: 'blank'"]))
-
-sequence.append(utils.StartRecordingAction())
-sequence.append(KeyComboAction("Down"))
-sequence.append(utils.AssertPresentationAction(
-    "6. line Down",
     ["BRAILLE LINE:  'Before reporting a bug, please read the'",
      "     VISIBLE:  'Before reporting a bug, please r', cursor=1",
      "SPEECH OUTPUT: 'Before reporting a bug, please read the'"]))
@@ -58,7 +42,7 @@ sequence.append(utils.AssertPresentationAction(
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
 sequence.append(utils.AssertPresentationAction(
-    "7. line Down",
+    "5. line Down",
     ["BRAILLE LINE:  'bug writing guidelines,'",
      "     VISIBLE:  'bug writing guidelines,', cursor=1",
      "SPEECH OUTPUT: 'bug writing guidelines link'",
@@ -67,7 +51,7 @@ sequence.append(utils.AssertPresentationAction(
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
 sequence.append(utils.AssertPresentationAction(
-    "8. line Down",
+    "6. line Down",
     ["BRAILLE LINE:  'please look at the list of'",
      "     VISIBLE:  'please look at the list of', cursor=1",
      "SPEECH OUTPUT: 'please look at the list of'"]))
@@ -75,7 +59,7 @@ sequence.append(utils.AssertPresentationAction(
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
 sequence.append(utils.AssertPresentationAction(
-    "9. line Down",
+    "7. line Down",
     ["BRAILLE LINE:  'most frequently reported bugs,'",
      "     VISIBLE:  'most frequently reported bugs,', cursor=1",
      "SPEECH OUTPUT: 'most frequently reported bugs link'",
@@ -84,7 +68,7 @@ sequence.append(utils.AssertPresentationAction(
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
 sequence.append(utils.AssertPresentationAction(
-    "10. line Down",
+    "8. line Down",
     ["BRAILLE LINE:  ', and please'",
      "     VISIBLE:  ', and please', cursor=1",
      "SPEECH OUTPUT: ', and please'"]))
@@ -92,7 +76,7 @@ sequence.append(utils.AssertPresentationAction(
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
 sequence.append(utils.AssertPresentationAction(
-    "11. line Down",
+    "9. line Down",
     ["BRAILLE LINE:  'search'",
      "     VISIBLE:  'search', cursor=1",
      "SPEECH OUTPUT: 'search link'"]))
@@ -100,7 +84,7 @@ sequence.append(utils.AssertPresentationAction(
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
 sequence.append(utils.AssertPresentationAction(
-    "12. line Down",
+    "10. line Down",
     ["BRAILLE LINE:  ' or'",
      "     VISIBLE:  ' or', cursor=1",
      "SPEECH OUTPUT: 'or'"]))
@@ -108,7 +92,7 @@ sequence.append(utils.AssertPresentationAction(
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
 sequence.append(utils.AssertPresentationAction(
-    "13. line Down",
+    "11. line Down",
     ["BRAILLE LINE:  'browse'",
      "     VISIBLE:  'browse', cursor=1",
      "SPEECH OUTPUT: 'browse link'"]))
@@ -116,7 +100,7 @@ sequence.append(utils.AssertPresentationAction(
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
 sequence.append(utils.AssertPresentationAction(
-    "14. line Down",
+    "12. line Down",
     ["BRAILLE LINE:  ' for the bug.'",
      "     VISIBLE:  ' for the bug.', cursor=1",
      "SPEECH OUTPUT: 'for the bug.'"]))
@@ -124,7 +108,7 @@ sequence.append(utils.AssertPresentationAction(
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
 sequence.append(utils.AssertPresentationAction(
-    "15. line Up",
+    "13. line Up",
     ["BRAILLE LINE:  'browse'",
      "     VISIBLE:  'browse', cursor=1",
      "SPEECH OUTPUT: 'browse link'"]))
@@ -132,7 +116,7 @@ sequence.append(utils.AssertPresentationAction(
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
 sequence.append(utils.AssertPresentationAction(
-    "16. line Up",
+    "14. line Up",
     ["BRAILLE LINE:  ' or'",
      "     VISIBLE:  ' or', cursor=1",
      "SPEECH OUTPUT: 'or'"]))
@@ -140,7 +124,7 @@ sequence.append(utils.AssertPresentationAction(
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
 sequence.append(utils.AssertPresentationAction(
-    "17. line Up",
+    "15. line Up",
     ["BRAILLE LINE:  'search'",
      "     VISIBLE:  'search', cursor=1",
      "SPEECH OUTPUT: 'search link'"]))
@@ -148,7 +132,7 @@ sequence.append(utils.AssertPresentationAction(
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
 sequence.append(utils.AssertPresentationAction(
-    "18. line Up",
+    "16. line Up",
     ["BRAILLE LINE:  ', and please'",
      "     VISIBLE:  ', and please', cursor=1",
      "SPEECH OUTPUT: ', and please'"]))
@@ -156,7 +140,7 @@ sequence.append(utils.AssertPresentationAction(
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
 sequence.append(utils.AssertPresentationAction(
-    "19. line Up",
+    "17. line Up",
     ["BRAILLE LINE:  'most frequently reported bugs,'",
      "     VISIBLE:  'most frequently reported bugs,', cursor=1",
      "SPEECH OUTPUT: 'most frequently reported bugs link'",
@@ -165,7 +149,7 @@ sequence.append(utils.AssertPresentationAction(
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
 sequence.append(utils.AssertPresentationAction(
-    "20. line Up",
+    "18. line Up",
     ["BRAILLE LINE:  'please look at the list of'",
      "     VISIBLE:  'please look at the list of', cursor=1",
      "SPEECH OUTPUT: 'please look at the list of'"]))
@@ -173,7 +157,7 @@ sequence.append(utils.AssertPresentationAction(
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
 sequence.append(utils.AssertPresentationAction(
-    "21. line Up",
+    "19. line Up",
     ["BRAILLE LINE:  'bug writing guidelines,'",
      "     VISIBLE:  'bug writing guidelines,', cursor=1",
      "SPEECH OUTPUT: 'bug writing guidelines link'",
@@ -182,7 +166,7 @@ sequence.append(utils.AssertPresentationAction(
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
 sequence.append(utils.AssertPresentationAction(
-    "22. line Up",
+    "20. line Up",
     ["BRAILLE LINE:  'Before reporting a bug, please read the'",
      "     VISIBLE:  'Before reporting a bug, please r', cursor=1",
      "SPEECH OUTPUT: 'Before reporting a bug, please read the'"]))
@@ -190,23 +174,7 @@ sequence.append(utils.AssertPresentationAction(
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
 sequence.append(utils.AssertPresentationAction(
-    "23. line Up",
-    ["BRAILLE LINE:  ''",
-     "     VISIBLE:  '', cursor=1",
-     "SPEECH OUTPUT: 'blank'"]))
-
-sequence.append(utils.StartRecordingAction())
-sequence.append(KeyComboAction("Up"))
-sequence.append(utils.AssertPresentationAction(
-    "24. line Up",
-    ["BRAILLE LINE:  ''",
-     "     VISIBLE:  '', cursor=1",
-     "SPEECH OUTPUT: 'blank'"]))
-
-sequence.append(utils.StartRecordingAction())
-sequence.append(KeyComboAction("Up"))
-sequence.append(utils.AssertPresentationAction(
-    "25. line Up",
+    "21. line Up",
     ["BRAILLE LINE:  'into Bugzilla. h1'",
      "     VISIBLE:  'into Bugzilla. h1', cursor=1",
      "SPEECH OUTPUT: 'into Bugzilla. heading level 1'"]))
@@ -214,7 +182,7 @@ sequence.append(utils.AssertPresentationAction(
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
 sequence.append(utils.AssertPresentationAction(
-    "26. line Up",
+    "22. line Up",
     ["BRAILLE LINE:  'Enter Bug: orca \u2013 This page lets you enter a new bug  h1'",
      "     VISIBLE:  'Enter Bug: orca \u2013 This page lets', cursor=1",
      "SPEECH OUTPUT: 'Enter Bug: orca \u2013 This page lets you enter a new bug heading level 1'"]))
diff --git a/test/keystrokes/firefox/object_nav_links_on_line.py 
b/test/keystrokes/firefox/object_nav_links_on_line.py
index 6c72be9..ae349bf 100644
--- a/test/keystrokes/firefox/object_nav_links_on_line.py
+++ b/test/keystrokes/firefox/object_nav_links_on_line.py
@@ -7,6 +7,10 @@ import utils
 
 sequence = MacroSequence()
 
+# Work around some new quirk in Gecko that causes this test to fail if
+# run via the test harness rather than manually.
+sequence.append(KeyComboAction("<Control>r"))
+
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("<Control>Home"))
 sequence.append(utils.AssertPresentationAction(
diff --git a/test/keystrokes/firefox/object_nav_simple_form_down.py 
b/test/keystrokes/firefox/object_nav_simple_form_down.py
index 6485019..3006636 100644
--- a/test/keystrokes/firefox/object_nav_simple_form_down.py
+++ b/test/keystrokes/firefox/object_nav_simple_form_down.py
@@ -14,7 +14,7 @@ sequence.append(KeyComboAction("<Control>r"))
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("<Control>Home"))
 sequence.append(utils.AssertPresentationAction(
-    "1. Top of file",
+    "1. Top of File",
     ["BRAILLE LINE:  'Type something here:'",
      "     VISIBLE:  'Type something here:', cursor=1",
      "SPEECH OUTPUT: 'Type something here:'"]))
@@ -25,7 +25,7 @@ sequence.append(utils.AssertPresentationAction(
     "2. line Down",
     ["BRAILLE LINE:  ' $l'",
      "     VISIBLE:  ' $l', cursor=1",
-     "SPEECH OUTPUT: 'Type something here: entry"]))
+     "SPEECH OUTPUT: 'entry'"]))
 
 sequence.append(PauseAction(1000))
 
@@ -45,7 +45,7 @@ sequence.append(utils.AssertPresentationAction(
      "     VISIBLE:  ' $l', cursor=1",
      "BRAILLE LINE:  ' $l'",
      "     VISIBLE:  ' $l', cursor=1",
-     "SPEECH OUTPUT: 'Magic disappearing text trick: entry"]))
+     "SPEECH OUTPUT: 'entry'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
@@ -61,7 +61,7 @@ sequence.append(utils.AssertPresentationAction(
     "6. line Down",
     ["BRAILLE LINE:  ' $l'",
      "     VISIBLE:  ' $l', cursor=1",
-     "SPEECH OUTPUT: 'Tell me a secret: password text"]))
+     "SPEECH OUTPUT: 'password text'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
@@ -77,7 +77,7 @@ sequence.append(utils.AssertPresentationAction(
     "8. line Down",
     ["BRAILLE LINE:  'I am a monkey with a long tail.  I like  $l'",
      "     VISIBLE:  'I am a monkey with a long tail. ', cursor=1",
-     "SPEECH OUTPUT: 'Tell me a little more about yourself: entry I am a monkey with a long tail.  I like 
"]))
+     "SPEECH OUTPUT: 'entry I am a monkey with a long tail.  I like "]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
@@ -108,14 +108,6 @@ sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
 sequence.append(utils.AssertPresentationAction(
     "12. line Down",
-    ["BRAILLE LINE:  '      $l'",
-     "     VISIBLE:  '      $l', cursor=1",
-     "SPEECH OUTPUT: '     '"]))
-
-sequence.append(utils.StartRecordingAction())
-sequence.append(KeyComboAction("Down"))
-sequence.append(utils.AssertPresentationAction(
-    "13. line Down",
     ["BRAILLE LINE:  'Check one or more:'",
      "     VISIBLE:  'Check one or more:', cursor=1",
      "SPEECH OUTPUT: 'Check one or more:"]))
@@ -123,7 +115,7 @@ sequence.append(utils.AssertPresentationAction(
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
 sequence.append(utils.AssertPresentationAction(
-    "14. line Down",
+    "13. line Down",
     ["BRAILLE LINE:  '< > Red check box'",
      "     VISIBLE:  '< > Red check box', cursor=1",
      "SPEECH OUTPUT: 'Red check box not checked"]))
@@ -131,7 +123,7 @@ sequence.append(utils.AssertPresentationAction(
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
 sequence.append(utils.AssertPresentationAction(
-    "15. line Down",
+    "14. line Down",
     ["BRAILLE LINE:  'Red'",
      "     VISIBLE:  'Red', cursor=1",
      "SPEECH OUTPUT: 'Red"]))
@@ -139,7 +131,7 @@ sequence.append(utils.AssertPresentationAction(
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
 sequence.append(utils.AssertPresentationAction(
-    "16. line Down",
+    "15. line Down",
     ["BRAILLE LINE:  '< > Blue check box'",
      "     VISIBLE:  '< > Blue check box', cursor=1",
      "SPEECH OUTPUT: 'Blue check box not checked"]))
@@ -147,7 +139,7 @@ sequence.append(utils.AssertPresentationAction(
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
 sequence.append(utils.AssertPresentationAction(
-    "17. line Down",
+    "16. line Down",
     ["BRAILLE LINE:  'Blue'",
      "     VISIBLE:  'Blue', cursor=1",
      "SPEECH OUTPUT: 'Blue"]))
@@ -155,7 +147,7 @@ sequence.append(utils.AssertPresentationAction(
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
 sequence.append(utils.AssertPresentationAction(
-    "18. line Down",
+    "17. line Down",
     ["BRAILLE LINE:  '< > Green check box'",
      "     VISIBLE:  '< > Green check box', cursor=1",
      "SPEECH OUTPUT: 'Green check box not checked"]))
@@ -163,7 +155,7 @@ sequence.append(utils.AssertPresentationAction(
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
 sequence.append(utils.AssertPresentationAction(
-    "19. line Down",
+    "18. line Down",
     ["BRAILLE LINE:  'Green'",
      "     VISIBLE:  'Green', cursor=1",
      "SPEECH OUTPUT: 'Green"]))
@@ -171,7 +163,7 @@ sequence.append(utils.AssertPresentationAction(
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
 sequence.append(utils.AssertPresentationAction(
-    "20. line Down",
+    "19. line Down",
     ["BRAILLE LINE:  'Make a selection:'",
      "     VISIBLE:  'Make a selection:', cursor=1",
      "SPEECH OUTPUT: 'Make a selection:"]))
@@ -179,15 +171,15 @@ sequence.append(utils.AssertPresentationAction(
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
 sequence.append(utils.AssertPresentationAction(
-    "21. line Down",
+    "20. line Down",
     ["BRAILLE LINE:  'Water combo box'",
      "     VISIBLE:  'Water combo box', cursor=1",
-     "SPEECH OUTPUT: 'Make a selection: Water combo box"]))
+     "SPEECH OUTPUT: 'Water combo box"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
 sequence.append(utils.AssertPresentationAction(
-    "22. line Down",
+    "21. line Down",
     ["BRAILLE LINE:  'Which sports do you like?'",
      "     VISIBLE:  'Which sports do you like?', cursor=1",
      "SPEECH OUTPUT: 'Which sports do you like?"]))
@@ -195,15 +187,15 @@ sequence.append(utils.AssertPresentationAction(
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
 sequence.append(utils.AssertPresentationAction(
-    "23. line Down",
+    "22. line Down",
     ["BRAILLE LINE:  'Hockey list box'",
      "     VISIBLE:  'Hockey list box', cursor=1",
-     "SPEECH OUTPUT: 'Which sports do you like? Hockey multi-select List with 4 items' voice=system"]))
+     "SPEECH OUTPUT: 'Hockey multi-select List with 4 items'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
 sequence.append(utils.AssertPresentationAction(
-    "24. line Down",
+    "23. line Down",
     ["BRAILLE LINE:  'Dashing picture of Willie Walker image'",
      "     VISIBLE:  'Dashing picture of Willie Walker', cursor=1",
      "SPEECH OUTPUT: 'Dashing picture of Willie Walker image"]))
@@ -211,7 +203,7 @@ sequence.append(utils.AssertPresentationAction(
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
 sequence.append(utils.AssertPresentationAction(
-    "25. line Down",
+    "24. line Down",
     ["BRAILLE LINE:  'Ain't he handsome (please say yes)?'",
      "     VISIBLE:  'Ain't he handsome (please say ye', cursor=1",
      "SPEECH OUTPUT: 'Ain't he handsome (please say yes)?"]))
@@ -219,15 +211,15 @@ sequence.append(utils.AssertPresentationAction(
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
 sequence.append(utils.AssertPresentationAction(
-    "26. line Down",
-    ["BRAILLE LINE:  '& y radio button'",
-     "     VISIBLE:  '& y radio button', cursor=1",
+    "25. line Down",
+    ["BRAILLE LINE:  '& y Yes radio button'",
+     "     VISIBLE:  '& y Yes radio button', cursor=1",
      "SPEECH OUTPUT: 'Yes not selected radio button'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
 sequence.append(utils.AssertPresentationAction(
-    "27. line Down",
+    "26. line Down",
     ["BRAILLE LINE:  'Yes'",
      "     VISIBLE:  'Yes', cursor=1",
      "SPEECH OUTPUT: 'Yes'"]))
@@ -235,15 +227,15 @@ sequence.append(utils.AssertPresentationAction(
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
 sequence.append(utils.AssertPresentationAction(
-    "28. line Down",
-    ["BRAILLE LINE:  '& y radio button'",
-     "     VISIBLE:  '& y radio button', cursor=1",
+    "27. line Down",
+    ["BRAILLE LINE:  '& y No radio button'",
+     "     VISIBLE:  '& y No radio button', cursor=1",
      "SPEECH OUTPUT: 'No not selected radio button'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
 sequence.append(utils.AssertPresentationAction(
-    "29. line Down",
+    "28. line Down",
     ["BRAILLE LINE:  'No'",
      "     VISIBLE:  'No', cursor=1",
      "SPEECH OUTPUT: 'No'"]))
diff --git a/test/keystrokes/firefox/object_nav_simple_form_up.py 
b/test/keystrokes/firefox/object_nav_simple_form_up.py
index 1c5790d..d1e2444 100644
--- a/test/keystrokes/firefox/object_nav_simple_form_up.py
+++ b/test/keystrokes/firefox/object_nav_simple_form_up.py
@@ -16,15 +16,15 @@ sequence.append(KeyComboAction("<Control>End"))
 sequence.append(utils.AssertPresentationAction(
     "1. End of file",
     ["BRAILLE LINE:  'No'",
-     "     VISIBLE:  'No', cursor=2",
+     "     VISIBLE:  'No', cursor=3",
      "SPEECH OUTPUT: 'No'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
 sequence.append(utils.AssertPresentationAction(
     "2. line Up",
-    ["BRAILLE LINE:  '& y radio button'",
-     "     VISIBLE:  '& y radio button', cursor=1",
+    ["BRAILLE LINE:  '& y No radio button'",
+     "     VISIBLE:  '& y No radio button', cursor=1",
      "SPEECH OUTPUT: 'No not selected radio button'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -39,8 +39,8 @@ sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
 sequence.append(utils.AssertPresentationAction(
     "4. line Up",
-    ["BRAILLE LINE:  '& y radio button'",
-     "     VISIBLE:  '& y radio button', cursor=1",
+    ["BRAILLE LINE:  '& y Yes radio button'",
+     "     VISIBLE:  '& y Yes radio button', cursor=1",
      "SPEECH OUTPUT: 'Yes not selected radio button'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -65,7 +65,7 @@ sequence.append(utils.AssertPresentationAction(
     "7. line Up",
     ["BRAILLE LINE:  'Hockey list box'",
      "     VISIBLE:  'Hockey list box', cursor=1",
-     "SPEECH OUTPUT: 'Which sports do you like? Hockey multi-select List with 4 items'"]))
+     "SPEECH OUTPUT: 'Hockey multi-select List with 4 items'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
@@ -81,7 +81,7 @@ sequence.append(utils.AssertPresentationAction(
     "9. line Up",
     ["BRAILLE LINE:  'Water combo box'",
      "     VISIBLE:  'Water combo box', cursor=1",
-     "SPEECH OUTPUT: 'Make a selection: Water combo box"]))
+     "SPEECH OUTPUT: 'Water combo box"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
@@ -151,14 +151,6 @@ sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
 sequence.append(utils.AssertPresentationAction(
     "18. line Up",
-    ["BRAILLE LINE:  '      $l'",
-     "     VISIBLE:  '      $l', cursor=1",
-     "SPEECH OUTPUT: 'Tell me a little more about yourself: entry      '"]))
-
-sequence.append(utils.StartRecordingAction())
-sequence.append(KeyComboAction("Up"))
-sequence.append(utils.AssertPresentationAction(
-    "19. line Up",
     ["BRAILLE LINE:  'write my memoirs. $l'",
      "     VISIBLE:  'write my memoirs. $l', cursor=1",
      "SPEECH OUTPUT: 'write my memoirs.",
@@ -167,7 +159,7 @@ sequence.append(utils.AssertPresentationAction(
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
 sequence.append(utils.AssertPresentationAction(
-    "20. line Up",
+    "19. line Up",
     ["BRAILLE LINE:  'I've recently taken up typing and plan to  $l'",
      "     VISIBLE:  'I've recently taken up typing an', cursor=1",
      "SPEECH OUTPUT: 'I've recently taken up typing and plan to '"]))
@@ -175,7 +167,7 @@ sequence.append(utils.AssertPresentationAction(
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
 sequence.append(utils.AssertPresentationAction(
-    "21. line Up",
+    "20. line Up",
     ["BRAILLE LINE:  'to swing from trees and eat bananas.   $l'",
      "     VISIBLE:  'to swing from trees and eat bana', cursor=1",
      "SPEECH OUTPUT: 'to swing from trees and eat bananas.  "]))
@@ -183,7 +175,7 @@ sequence.append(utils.AssertPresentationAction(
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
 sequence.append(utils.AssertPresentationAction(
-    "22. line Up",
+    "21. line Up",
     ["BRAILLE LINE:  'I am a monkey with a long tail.  I like  $l'",
      "     VISIBLE:  'I am a monkey with a long tail. ', cursor=1",
      "SPEECH OUTPUT: 'I am a monkey with a long tail.  I like "]))
@@ -191,7 +183,7 @@ sequence.append(utils.AssertPresentationAction(
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
 sequence.append(utils.AssertPresentationAction(
-    "23. line Up",
+    "22. line Up",
     ["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:"]))
@@ -199,15 +191,15 @@ sequence.append(utils.AssertPresentationAction(
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
 sequence.append(utils.AssertPresentationAction(
-    "24. line Up",
+    "23. line Up",
     ["BRAILLE LINE:  ' $l'",
      "     VISIBLE:  ' $l', cursor=1",
-     "SPEECH OUTPUT: 'Tell me a secret: password text"]))
+     "SPEECH OUTPUT: 'password text"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
 sequence.append(utils.AssertPresentationAction(
-    "25. line Up",
+    "24. line Up",
     ["BRAILLE LINE:  'Tell me a secret:'",
      "     VISIBLE:  'Tell me a secret:', cursor=1",
      "SPEECH OUTPUT: 'Tell me a secret:"]))
@@ -215,17 +207,17 @@ sequence.append(utils.AssertPresentationAction(
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
 sequence.append(utils.AssertPresentationAction(
-    "26. line Up",
+    "25. line Up",
     ["BRAILLE LINE:  ' $l'",
      "     VISIBLE:  ' $l', cursor=1",
      "BRAILLE LINE:  ' $l'",
      "     VISIBLE:  ' $l', cursor=1",
-     "SPEECH OUTPUT: 'Magic disappearing text trick: entry"]))
+     "SPEECH OUTPUT: 'blank'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
 sequence.append(utils.AssertPresentationAction(
-    "27. line Up",
+    "26. line Up",
     ["BRAILLE LINE:  'Magic disappearing text trick:'",
      "     VISIBLE:  'Magic disappearing text trick:', cursor=1",
      "SPEECH OUTPUT: 'Magic disappearing text trick:"]))
@@ -233,15 +225,15 @@ sequence.append(utils.AssertPresentationAction(
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
 sequence.append(utils.AssertPresentationAction(
-    "28. line Up",
+    "27. line Up",
     ["BRAILLE LINE:  ' $l'",
      "     VISIBLE:  ' $l', cursor=1",
-     "SPEECH OUTPUT: 'Type something here: entry"]))
+     "SPEECH OUTPUT: 'entry"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
 sequence.append(utils.AssertPresentationAction(
-    "29. line Up",
+    "28. line Up",
     ["BRAILLE LINE:  'Type something here:'",
      "     VISIBLE:  'Type something here:', cursor=1",
      "SPEECH OUTPUT: 'Type something here:'"]))
diff --git a/test/keystrokes/firefox/say_all_blockquote.py b/test/keystrokes/firefox/say_all_blockquote.py
index bb02e39..8e068a0 100644
--- a/test/keystrokes/firefox/say_all_blockquote.py
+++ b/test/keystrokes/firefox/say_all_blockquote.py
@@ -35,8 +35,7 @@ sequence.append(utils.AssertPresentationAction(
      "SPEECH OUTPUT: 'Three last chances.'",
      "SPEECH OUTPUT: 'You have three last chances, the nature of which I have divulged in my previous 
utterance.'",
      "SPEECH OUTPUT: 'On castle decor:'",
-     "SPEECH OUTPUT: 'Hm!'",
-     "SPEECH OUTPUT: 'She is made of harder stuff!'",
+     "SPEECH OUTPUT: 'Hm! She is made of harder stuff!'",
      "SPEECH OUTPUT: 'Cardinal Fang!'",
      "SPEECH OUTPUT: 'Fetch the COMFY CHAIR!'"]))
 
diff --git a/test/keystrokes/firefox/say_all_bug_591351_1.py b/test/keystrokes/firefox/say_all_bug_591351_1.py
index 4b84066..820fb26 100644
--- a/test/keystrokes/firefox/say_all_bug_591351_1.py
+++ b/test/keystrokes/firefox/say_all_bug_591351_1.py
@@ -14,8 +14,7 @@ sequence.append(utils.AssertPresentationAction(
     ["SPEECH OUTPUT: 'Hello world.'",
      "SPEECH OUTPUT: 'I wonder what a bevezeto is.'",
      "SPEECH OUTPUT: 'I should Google that.'",
-     "SPEECH OUTPUT: 'Aha!'",
-     "SPEECH OUTPUT: 'It is the Hungarian word for \"Introduction\".'",
+     "SPEECH OUTPUT: 'Aha! It is the Hungarian word for \"Introduction\".'",
      "SPEECH OUTPUT: 'Here is some'",
      "SPEECH OUTPUT: 'proof'",
      "SPEECH OUTPUT: 'link'",
diff --git a/test/keystrokes/firefox/say_all_bugzilla_search.py 
b/test/keystrokes/firefox/say_all_bugzilla_search.py
index 5568b63..e51dfd1 100644
--- a/test/keystrokes/firefox/say_all_bugzilla_search.py
+++ b/test/keystrokes/firefox/say_all_bugzilla_search.py
@@ -43,7 +43,7 @@ sequence.append(utils.AssertPresentationAction(
      "SPEECH OUTPUT: '|'",
      "SPEECH OUTPUT: 'Log Out'",
      "SPEECH OUTPUT: 'link'",
-     "SPEECH OUTPUT: 'Short Bug Search Form'",
+     "SPEECH OUTPUT: 'Short Bug Search Form '",
      "SPEECH OUTPUT: 'link'",
      "SPEECH OUTPUT: 'Complicated Bug Search Form'",
      "SPEECH OUTPUT: 'Give me some help'",
@@ -51,7 +51,6 @@ sequence.append(utils.AssertPresentationAction(
      "SPEECH OUTPUT: '(reloads page.)'",
      "SPEECH OUTPUT: 'Summary:'",
      "SPEECH OUTPUT: 'row header'",
-     "SPEECH OUTPUT: 'Summary:'",
      "SPEECH OUTPUT: 'contains all of the words/strings'",
      "SPEECH OUTPUT: 'combo box'",
      "SPEECH OUTPUT: 'entry'",
@@ -59,60 +58,51 @@ sequence.append(utils.AssertPresentationAction(
      "SPEECH OUTPUT: 'push button'",
      "SPEECH OUTPUT: 'Classification:'",
      "SPEECH OUTPUT: 'column header'",
-     "SPEECH OUTPUT: 'Classification:'",
      "SPEECH OUTPUT: 'Admin '",
      "SPEECH OUTPUT: 'multi-select'",
      "SPEECH OUTPUT: 'List with 8 items'",
      "SPEECH OUTPUT: 'Product:'",
      "SPEECH OUTPUT: 'column header'",
-     "SPEECH OUTPUT: 'Product:'",
      "SPEECH OUTPUT: 'accerciser'",
      "SPEECH OUTPUT: 'multi-select'",
      "SPEECH OUTPUT: 'List with 379 items'",
      "SPEECH OUTPUT: 'Component'",
      "SPEECH OUTPUT: 'link'",
-     "SPEECH OUTPUT: 'Component :'",
+     "SPEECH OUTPUT: ':'",
      "SPEECH OUTPUT: 'column header'",
-     "SPEECH OUTPUT: 'Component:'",
      "SPEECH OUTPUT: 'abiscan'",
      "SPEECH OUTPUT: 'multi-select'",
      "SPEECH OUTPUT: 'List with 1248 items'",
      "SPEECH OUTPUT: 'Version:'",
      "SPEECH OUTPUT: 'column header'",
-     "SPEECH OUTPUT: 'Version:'",
      "SPEECH OUTPUT: '0.0.1'",
      "SPEECH OUTPUT: 'multi-select'",
      "SPEECH OUTPUT: 'List with 857 items'",
      "SPEECH OUTPUT: 'Target Milestone:'",
      "SPEECH OUTPUT: 'column header'",
-     "SPEECH OUTPUT: 'Target Milestone:'",
      "SPEECH OUTPUT: '---'",
      "SPEECH OUTPUT: 'multi-select'",
      "SPEECH OUTPUT: 'List with 555 items'",
      "SPEECH OUTPUT: 'A Comment:'",
      "SPEECH OUTPUT: 'row header'",
-     "SPEECH OUTPUT: 'A Comment:'",
      "SPEECH OUTPUT: 'contains the string'",
      "SPEECH OUTPUT: 'combo box'",
      "SPEECH OUTPUT: 'entry'",
      "SPEECH OUTPUT: 'Whiteboard:'",
      "SPEECH OUTPUT: 'row header'",
-     "SPEECH OUTPUT: 'Whiteboard:'",
      "SPEECH OUTPUT: 'contains all of the words/strings'",
      "SPEECH OUTPUT: 'combo box'",
      "SPEECH OUTPUT: 'entry'",
      "SPEECH OUTPUT: 'Keywords'",
      "SPEECH OUTPUT: 'link'",
-     "SPEECH OUTPUT: 'Keywords :'",
+     "SPEECH OUTPUT: ':'",
      "SPEECH OUTPUT: 'row header'",
-     "SPEECH OUTPUT: 'Keywords:'",
      "SPEECH OUTPUT: 'contains all of the keywords'",
      "SPEECH OUTPUT: 'combo box'",
      "SPEECH OUTPUT: 'entry'",
      "SPEECH OUTPUT: 'separator'",
      "SPEECH OUTPUT: 'Status:'",
      "SPEECH OUTPUT: 'column header'",
-     "SPEECH OUTPUT: 'Status:'",
      "SPEECH OUTPUT: 'UNCONFIRMED'",
      "SPEECH OUTPUT: 'NEW'",
      "SPEECH OUTPUT: 'ASSIGNED'",
@@ -120,35 +110,33 @@ sequence.append(utils.AssertPresentationAction(
      "SPEECH OUTPUT: 'NEEDINFO'",
      "SPEECH OUTPUT: 'multi-select'",
      "SPEECH OUTPUT: 'List with 8 items'",
-     "SPEECH OUTPUT: 'Resolution: '",
-     "SPEECH OUTPUT: 'column header'",
      "SPEECH OUTPUT: 'Resolution:'",
+     "SPEECH OUTPUT: 'column header'",
      "SPEECH OUTPUT: 'FIXED'",
      "SPEECH OUTPUT: 'multi-select'",
      "SPEECH OUTPUT: 'List with 12 items'",
      "SPEECH OUTPUT: 'Severity:'",
      "SPEECH OUTPUT: 'column header'",
-     "SPEECH OUTPUT: 'Severity:'",
      "SPEECH OUTPUT: 'blocker'",
      "SPEECH OUTPUT: 'multi-select'",
      "SPEECH OUTPUT: 'List with 7 items'",
      "SPEECH OUTPUT: 'Priority:'",
      "SPEECH OUTPUT: 'column header'",
-     "SPEECH OUTPUT: 'Priority:'",
      "SPEECH OUTPUT: 'Immediate'",
      "SPEECH OUTPUT: 'multi-select'",
      "SPEECH OUTPUT: 'List with 5 items'",
      "SPEECH OUTPUT: 'OS:'",
      "SPEECH OUTPUT: 'column header'",
-     "SPEECH OUTPUT: 'OS:'",
      "SPEECH OUTPUT: 'All'",
      "SPEECH OUTPUT: 'multi-select'",
      "SPEECH OUTPUT: 'List with 21 items'",
      "SPEECH OUTPUT: 'Email and Numbering '",
      "SPEECH OUTPUT: 'Any one of:'",
-     "SPEECH OUTPUT: 'the bug assignee'",
      "SPEECH OUTPUT: 'check box'",
      "SPEECH OUTPUT: 'checked'",
+     "SPEECH OUTPUT: 'the bug assignee'",
+     "SPEECH OUTPUT: 'check box'",
+     "SPEECH OUTPUT: 'not checked'",
      "SPEECH OUTPUT: 'the reporter'",
      "SPEECH OUTPUT: 'check box'",
      "SPEECH OUTPUT: 'not checked'",
@@ -159,12 +147,12 @@ sequence.append(utils.AssertPresentationAction(
      "SPEECH OUTPUT: 'check box'",
      "SPEECH OUTPUT: 'not checked'",
      "SPEECH OUTPUT: 'a commenter'",
-     "SPEECH OUTPUT: 'check box'",
-     "SPEECH OUTPUT: 'not checked'",
      "SPEECH OUTPUT: 'contains'",
      "SPEECH OUTPUT: 'combo box'",
      "SPEECH OUTPUT: 'entry'",
      "SPEECH OUTPUT: 'Any one of:'",
+     "SPEECH OUTPUT: 'check box'",
+     "SPEECH OUTPUT: 'checked'",
      "SPEECH OUTPUT: 'the bug assignee'",
      "SPEECH OUTPUT: 'check box'",
      "SPEECH OUTPUT: 'checked'",
@@ -176,10 +164,8 @@ sequence.append(utils.AssertPresentationAction(
      "SPEECH OUTPUT: 'checked'",
      "SPEECH OUTPUT: 'a CC list member'",
      "SPEECH OUTPUT: 'check box'",
-     "SPEECH OUTPUT: 'checked'",
-     "SPEECH OUTPUT: 'a commenter'",
-     "SPEECH OUTPUT: 'check box'",
      "SPEECH OUTPUT: 'not checked'",
+     "SPEECH OUTPUT: 'a commenter'",
      "SPEECH OUTPUT: 'contains'",
      "SPEECH OUTPUT: 'combo box'",
      "SPEECH OUTPUT: 'entry'",
@@ -187,15 +173,15 @@ sequence.append(utils.AssertPresentationAction(
      "SPEECH OUTPUT: 'Only include'",
      "SPEECH OUTPUT: 'combo box'",
      "SPEECH OUTPUT: 'bugs numbered:'",
-     "SPEECH OUTPUT: '(comma-separated list)'",
      "SPEECH OUTPUT: 'entry'",
+     "SPEECH OUTPUT: '(comma-separated list)'",
      "SPEECH OUTPUT: 'Bug Changes'",
      "SPEECH OUTPUT: 'Only bugs changed between:'",
-     "SPEECH OUTPUT: '(YYYY-MM-DD or relative dates)'",
      "SPEECH OUTPUT: 'entry'",
      "SPEECH OUTPUT: 'and'",
      "SPEECH OUTPUT: 'entry'",
      "SPEECH OUTPUT: 'Now'",
+     "SPEECH OUTPUT: '(YYYY-MM-DD or relative dates)'",
      "SPEECH OUTPUT: 'where one or more of the following changed:'",
      "SPEECH OUTPUT: '[Bug creation]'",
      "SPEECH OUTPUT: 'multi-select'",
@@ -204,13 +190,11 @@ sequence.append(utils.AssertPresentationAction(
      "SPEECH OUTPUT: 'entry'",
      "SPEECH OUTPUT: 'GNOME version:'",
      "SPEECH OUTPUT: 'column header'",
-     "SPEECH OUTPUT: 'GNOME version:'",
      "SPEECH OUTPUT: 'Unspecified'",
      "SPEECH OUTPUT: 'multi-select'",
      "SPEECH OUTPUT: 'List with 14 items'",
      "SPEECH OUTPUT: 'GNOME target:'",
      "SPEECH OUTPUT: 'column header'",
-     "SPEECH OUTPUT: 'GNOME target:'",
      "SPEECH OUTPUT: 'Unspecified'",
      "SPEECH OUTPUT: 'multi-select'",
      "SPEECH OUTPUT: 'List with 12 items'",
@@ -219,14 +203,14 @@ sequence.append(utils.AssertPresentationAction(
      "SPEECH OUTPUT: 'combo box'",
      "SPEECH OUTPUT: 'Search'",
      "SPEECH OUTPUT: 'push button'",
-     "SPEECH OUTPUT: 'and remember these as my default search options'",
      "SPEECH OUTPUT: 'check box'",
      "SPEECH OUTPUT: 'not checked'",
+     "SPEECH OUTPUT: 'and remember these as my default search options'",
      "SPEECH OUTPUT: 'separator'",
      "SPEECH OUTPUT: 'Advanced Searching Using Boolean Charts:'",
-     "SPEECH OUTPUT: 'Not (negate this whole chart)'",
      "SPEECH OUTPUT: 'check box'",
      "SPEECH OUTPUT: 'not checked'",
+     "SPEECH OUTPUT: 'Not (negate this whole chart)'",
      "SPEECH OUTPUT: '---'",
      "SPEECH OUTPUT: 'combo box'",
      "SPEECH OUTPUT: '---'",
diff --git a/test/keystrokes/firefox/say_all_empty_anchor.py b/test/keystrokes/firefox/say_all_empty_anchor.py
index ee6b8e7..2ab6760 100644
--- a/test/keystrokes/firefox/say_all_empty_anchor.py
+++ b/test/keystrokes/firefox/say_all_empty_anchor.py
@@ -29,18 +29,15 @@ sequence.append(utils.AssertPresentationAction(
      "SPEECH OUTPUT: 'link'",
      "SPEECH OUTPUT: 'Battery'",
      "SPEECH OUTPUT: 'heading level 2'",
-     "SPEECH OUTPUT: 'Q.'",
-     "SPEECH OUTPUT: 'What is a battery?'",
-     "SPEECH OUTPUT: 'A'",
-     "SPEECH OUTPUT: '. Look it up.'",
-     "SPEECH OUTPUT: 'Q.'",
-     "SPEECH OUTPUT: 'Which way is up?'",
-     "SPEECH OUTPUT: 'A'",
-     "SPEECH OUTPUT: '. That way.'",
-     "SPEECH OUTPUT: 'Q.'",
-     "SPEECH OUTPUT: 'Why did Orca used to get stuck on this page?'",
-     "SPEECH OUTPUT: 'A'",
-     "SPEECH OUTPUT: '. Empty anchors.'"]))
+     "SPEECH OUTPUT: 'Q. What is a battery?",
+     "SPEECH OUTPUT: 'A.'",
+     "SPEECH OUTPUT: 'Look it up.'",
+     "SPEECH OUTPUT: 'Q. Which way is up?",
+     "SPEECH OUTPUT: 'A.'",
+     "SPEECH OUTPUT: 'That way.'",
+     "SPEECH OUTPUT: 'Q. Why did Orca used to get stuck on this page?",
+     "SPEECH OUTPUT: 'A.'",
+     "SPEECH OUTPUT: 'Empty anchors.'"]))
 
 sequence.append(utils.AssertionSummaryAction())
 sequence.start()
diff --git a/test/keystrokes/firefox/say_all_enter_bug.py b/test/keystrokes/firefox/say_all_enter_bug.py
index b3c67dd..24a26b4 100644
--- a/test/keystrokes/firefox/say_all_enter_bug.py
+++ b/test/keystrokes/firefox/say_all_enter_bug.py
@@ -59,53 +59,42 @@ sequence.append(utils.AssertPresentationAction(
      "SPEECH OUTPUT: 'Product:'",
      "SPEECH OUTPUT: 'orca'",
      "SPEECH OUTPUT: 'Version:'",
-     "SPEECH OUTPUT: 'Version:'",
      "SPEECH OUTPUT: '2.21.x '",
      "SPEECH OUTPUT: 'List with 9 items'",
      "SPEECH OUTPUT: 'Component'",
      "SPEECH OUTPUT: 'link'",
      "SPEECH OUTPUT: ':'",
-     "SPEECH OUTPUT: 'Component:'",
      "SPEECH OUTPUT: 'braille '",
      "SPEECH OUTPUT: 'List with 5 items'",
      "SPEECH OUTPUT: 'GNOME version'",
      "SPEECH OUTPUT: 'link'",
      "SPEECH OUTPUT: ':'",
-     "SPEECH OUTPUT: 'GNOME version:'",
      "SPEECH OUTPUT: 'Unspecified'",
      "SPEECH OUTPUT: 'combo box'",
      "SPEECH OUTPUT: 'OS'",
      "SPEECH OUTPUT: 'link'",
      "SPEECH OUTPUT: ':'",
-     "SPEECH OUTPUT: 'OS:'",
      "SPEECH OUTPUT: 'Linux'",
      "SPEECH OUTPUT: 'combo box'",
      "SPEECH OUTPUT: 'Severity'",
      "SPEECH OUTPUT: 'link'",
      "SPEECH OUTPUT: ':'",
-     "SPEECH OUTPUT: 'Severity:'",
      "SPEECH OUTPUT: 'normal'",
      "SPEECH OUTPUT: 'combo box'",
      "SPEECH OUTPUT: 'Summary:'",
-     "SPEECH OUTPUT: 'Summary:'",
      "SPEECH OUTPUT: 'entry'",
      "SPEECH OUTPUT: 'Description:'",
-     "SPEECH OUTPUT: 'Description:'",
      "SPEECH OUTPUT: 'entry'",
      "SPEECH OUTPUT: 'Optional Fields'",
      "SPEECH OUTPUT: 'Cc:'",
-     "SPEECH OUTPUT: 'Cc:'",
      "SPEECH OUTPUT: 'entry'",
      "SPEECH OUTPUT: 'Keywords'",
      "SPEECH OUTPUT: 'link'",
      "SPEECH OUTPUT: ':'",
-     "SPEECH OUTPUT: 'Keywords:'",
      "SPEECH OUTPUT: 'entry'",
      "SPEECH OUTPUT: 'Depends on:'",
-     "SPEECH OUTPUT: 'Depends on:'",
      "SPEECH OUTPUT: 'entry'",
      "SPEECH OUTPUT: 'Blocks:'",
-     "SPEECH OUTPUT: 'Blocks:'",
      "SPEECH OUTPUT: 'entry'",
      "SPEECH OUTPUT: 'Commit'",
      "SPEECH OUTPUT: 'push button'",
diff --git a/test/keystrokes/firefox/say_all_entries.py b/test/keystrokes/firefox/say_all_entries.py
index 101a029..27e5288 100644
--- a/test/keystrokes/firefox/say_all_entries.py
+++ b/test/keystrokes/firefox/say_all_entries.py
@@ -20,43 +20,38 @@ sequence.append(utils.AssertPresentationAction(
      "SPEECH OUTPUT: 'amusing'",
      "SPEECH OUTPUT: 'link'",
      "SPEECH OUTPUT: 'here:'",
-     "SPEECH OUTPUT: 'Type something rather amusing here:'",
      "SPEECH OUTPUT: 'entry'",
      "SPEECH OUTPUT: 'Amusing numbers fall between'",
      "SPEECH OUTPUT: 'entry'",
      "SPEECH OUTPUT: 'and'",
      "SPEECH OUTPUT: 'entry'",
      "SPEECH OUTPUT: '.'",
-     "SPEECH OUTPUT: 'I'm a label'",
      "SPEECH OUTPUT: 'entry'",
+     "SPEECH OUTPUT: 'I'm a label'",
      "SPEECH OUTPUT: 'entry'",
      "SPEECH OUTPUT: 'Am I a label as well?'",
      "SPEECH OUTPUT: 'What the heck should we do here?'",
      "SPEECH OUTPUT: 'heading level 2'",
      "SPEECH OUTPUT: 'Looking at what follows visually, I'm not sure what I would type/i.e.'",
      "SPEECH OUTPUT: 'what the labels are.'",
-     "SPEECH OUTPUT: 'Looking at what follows visually, I'm not sure what I would type/i.e. what the labels 
are.'",
      "SPEECH OUTPUT: 'entry'",
      "SPEECH OUTPUT: 'Too far away to be a label.'",
      "SPEECH OUTPUT: 'Distance doesn't count on the left'",
-     "SPEECH OUTPUT: 'Distance doesn't count on the left'",
      "SPEECH OUTPUT: 'entry'",
      "SPEECH OUTPUT: 'Sometimes labels can be below the fields due to <br />'",
      "SPEECH OUTPUT: 'heading level 2'",
+     "SPEECH OUTPUT: 'entry'",
      "SPEECH OUTPUT: 'First Name'",
      "SPEECH OUTPUT: 'entry'",
      "SPEECH OUTPUT: 'M.I.'",
      "SPEECH OUTPUT: 'entry'",
      "SPEECH OUTPUT: 'Last Name'",
-     "SPEECH OUTPUT: 'entry'",
      "SPEECH OUTPUT: 'Other times it's due to layout tables'",
      "SPEECH OUTPUT: 'heading level 2'",
-     "SPEECH OUTPUT: 'First name'",
      "SPEECH OUTPUT: 'entry'",
-     "SPEECH OUTPUT: 'Middle initial'",
      "SPEECH OUTPUT: 'entry'",
-     "SPEECH OUTPUT: 'Last name'",
      "SPEECH OUTPUT: 'entry'",
+     "SPEECH OUTPUT: 'First name'",
      "SPEECH OUTPUT: 'Middle",
      "initial'",
      "SPEECH OUTPUT: 'Last'",
@@ -70,11 +65,8 @@ sequence.append(utils.AssertPresentationAction(
      "SPEECH OUTPUT: 'Last'",
      "SPEECH OUTPUT: 'name'",
      "SPEECH OUTPUT: 'link'",
-     "SPEECH OUTPUT: 'First Name'",
      "SPEECH OUTPUT: 'entry'",
-     "SPEECH OUTPUT: 'Middle initial'",
      "SPEECH OUTPUT: 'entry'",
-     "SPEECH OUTPUT: 'Last name'",
      "SPEECH OUTPUT: 'entry'",
      "SPEECH OUTPUT: 'Decisions, decisions.... When in doubt, closest table cell text wins'",
      "SPEECH OUTPUT: 'heading level 2'",
@@ -82,23 +74,18 @@ sequence.append(utils.AssertPresentationAction(
      "SPEECH OUTPUT: 'Middle",
      "initial'",
      "SPEECH OUTPUT: 'Last name'",
-     "SPEECH OUTPUT: 'Given name'",
      "SPEECH OUTPUT: 'entry'",
-     "SPEECH OUTPUT: 'initial'",
      "SPEECH OUTPUT: 'entry'",
-     "SPEECH OUTPUT: 'Surname'",
      "SPEECH OUTPUT: 'entry'",
+     "SPEECH OUTPUT: 'Given name'",
      "SPEECH OUTPUT: 'initial'",
      "SPEECH OUTPUT: 'Surname'",
      "SPEECH OUTPUT: 'First name'",
      "SPEECH OUTPUT: 'Middle",
      "initial'",
      "SPEECH OUTPUT: 'Last name'",
-     "SPEECH OUTPUT: 'First name'",
      "SPEECH OUTPUT: 'entry'",
-     "SPEECH OUTPUT: 'Middle initial'",
      "SPEECH OUTPUT: 'entry'",
-     "SPEECH OUTPUT: 'Last name'",
      "SPEECH OUTPUT: 'entry'",
      "SPEECH OUTPUT: 'Given name'",
      "SPEECH OUTPUT: 'initial'",
@@ -110,37 +97,24 @@ sequence.append(utils.AssertPresentationAction(
      "initial'",
      "SPEECH OUTPUT: 'Last name'",
      "SPEECH OUTPUT: 'patched image'",
-     "SPEECH OUTPUT: 'First name'",
      "SPEECH OUTPUT: 'entry'",
-     "SPEECH OUTPUT: 'Middle initial'",
      "SPEECH OUTPUT: 'entry'",
-     "SPEECH OUTPUT: 'Last name'",
      "SPEECH OUTPUT: 'entry'",
-     "SPEECH OUTPUT: 'patched image'",
      "SPEECH OUTPUT: 'entry'",
-     "SPEECH OUTPUT: 'First name'",
      "SPEECH OUTPUT: 'entry'",
-     "SPEECH OUTPUT: 'Middle initial'",
      "SPEECH OUTPUT: 'entry'",
-     "SPEECH OUTPUT: 'Last name'",
      "SPEECH OUTPUT: 'entry'",
-     "SPEECH OUTPUT: 'patched image'",
      "SPEECH OUTPUT: 'entry'",
-     "SPEECH OUTPUT: 'First name'",
      "SPEECH OUTPUT: 'entry'",
-     "SPEECH OUTPUT: 'Middle initial'",
      "SPEECH OUTPUT: 'entry'",
-     "SPEECH OUTPUT: 'Last name'",
      "SPEECH OUTPUT: 'entry'",
-     "SPEECH OUTPUT: 'patched image'",
      "SPEECH OUTPUT: 'entry'",
      "SPEECH OUTPUT: 'We mustn't forget images as labels -- even if that practice is lame'",
      "SPEECH OUTPUT: 'heading level 2'",
      "SPEECH OUTPUT: 'bandaid graphic'",
-     "SPEECH OUTPUT: 'bandaid graphic'",
      "SPEECH OUTPUT: 'entry'",
-     "SPEECH OUTPUT: 'bandaid graphic redux'",
      "SPEECH OUTPUT: 'entry'",
+     "SPEECH OUTPUT: 'bandaid graphic redux'",
      "SPEECH OUTPUT: 'Magic disappearing text trick:'",
      "SPEECH OUTPUT: 'entry'",
      "SPEECH OUTPUT: 'tab to me and I disappear'",
@@ -149,8 +123,10 @@ sequence.append(utils.AssertPresentationAction(
      "SPEECH OUTPUT: 'Tell me a little more about yourself:'",
      "SPEECH OUTPUT: 'entry'",
      "SPEECH OUTPUT: 'I",
-     "am a monkey with a long tail. I like to swing from trees and eat",
-     "bananas. I've recently taken up typing and plan to write my memoirs. '"]))
+     "am a monkey with a long tail. '",
+     "SPEECH OUTPUT: ' I like to swing from trees and eat",
+     "bananas. '",
+     "SPEECH OUTPUT: ' I've recently taken up typing and plan to write my memoirs. '"]))
 
 sequence.append(utils.AssertionSummaryAction())
 sequence.start()
diff --git a/test/keystrokes/firefox/say_all_multi_line_text.py 
b/test/keystrokes/firefox/say_all_multi_line_text.py
index fe9ffb3..2c51a1f 100644
--- a/test/keystrokes/firefox/say_all_multi_line_text.py
+++ b/test/keystrokes/firefox/say_all_multi_line_text.py
@@ -17,9 +17,9 @@ sequence.append(utils.AssertPresentationAction(
      "SPEECH OUTPUT: 'foo'",
      "SPEECH OUTPUT: 'bar'",
      "SPEECH OUTPUT: 'foo",
-     "foo'",
+     "foo",
      "SPEECH OUTPUT: 'bar",
-     "bar'",
+     "bar",
      "SPEECH OUTPUT: 'Hello'",
      "SPEECH OUTPUT: 'heading level 3'",
      "SPEECH OUTPUT: '•'",
diff --git a/test/keystrokes/firefox/say_all_role_combo_box.py 
b/test/keystrokes/firefox/say_all_role_combo_box.py
index 226dc03..c63341f 100644
--- a/test/keystrokes/firefox/say_all_role_combo_box.py
+++ b/test/keystrokes/firefox/say_all_role_combo_box.py
@@ -20,18 +20,15 @@ sequence.append(utils.AssertPresentationAction(
      "SPEECH OUTPUT: 'Priority'",
      "SPEECH OUTPUT: 'link'",
      "SPEECH OUTPUT: ':'",
-     "SPEECH OUTPUT: 'Priority:",
      "SPEECH OUTPUT: 'Normal'",
      "SPEECH OUTPUT: 'combo box'",
      "SPEECH OUTPUT: 'Resolution:'",
      "SPEECH OUTPUT: 'FIXED'",
      "SPEECH OUTPUT: 'combo box'",
      "SPEECH OUTPUT: 'Version'",
-     "SPEECH OUTPUT: 'Version'",
      "SPEECH OUTPUT: '2.16'",
      "SPEECH OUTPUT: 'combo box'",
      "SPEECH OUTPUT: 'Component'",
-     "SPEECH OUTPUT: 'Component'",
      "SPEECH OUTPUT: 'Speech'",
      "SPEECH OUTPUT: 'combo box'"]))
 
diff --git a/test/keystrokes/firefox/say_all_simple_form.py b/test/keystrokes/firefox/say_all_simple_form.py
index 45a207e..ff8a67a 100644
--- a/test/keystrokes/firefox/say_all_simple_form.py
+++ b/test/keystrokes/firefox/say_all_simple_form.py
@@ -20,34 +20,40 @@ sequence.append(utils.AssertPresentationAction(
      "SPEECH OUTPUT: 'password text'",
      "SPEECH OUTPUT: 'Tell me a little more about yourself:'",
      "SPEECH OUTPUT: 'entry'",
-     "SPEECH OUTPUT: 'I am a monkey with a long tail.  I like to swing from trees and eat bananas.  I've 
recently taken up typing and plan to write my memoirs.",
-     "     '",
+     "SPEECH OUTPUT: 'I am a monkey with a long tail. '",
+     "SPEECH OUTPUT: '  I like to swing from trees and eat bananas. '",
+     "SPEECH OUTPUT: '  I've recently taken up typing and plan to write my memoirs.",
+     "'",
+     "SPEECH OUTPUT: '     '",
      "SPEECH OUTPUT: 'Check one or more:'",
      "SPEECH OUTPUT: 'Red'",
      "SPEECH OUTPUT: 'check box'",
      "SPEECH OUTPUT: 'not checked'",
+     "SPEECH OUTPUT: 'Red'",
      "SPEECH OUTPUT: 'Blue'",
      "SPEECH OUTPUT: 'check box'",
      "SPEECH OUTPUT: 'not checked'",
+     "SPEECH OUTPUT: 'Blue'",
      "SPEECH OUTPUT: 'Green'",
      "SPEECH OUTPUT: 'check box'",
      "SPEECH OUTPUT: 'not checked'",
+     "SPEECH OUTPUT: 'Green'",
      "SPEECH OUTPUT: 'Make a selection:'",
      "SPEECH OUTPUT: 'Water'",
      "SPEECH OUTPUT: 'combo box'",
      "SPEECH OUTPUT: 'Which sports do you like?'",
-#     "SPEECH OUTPUT: 'Hockey'",
-#     "SPEECH OUTPUT: 'multi-select'",
-#     "SPEECH OUTPUT: 'List with 4 items'",
+     "SPEECH OUTPUT: 'Hockey'",
+     "SPEECH OUTPUT: 'multi-select'",
+     "SPEECH OUTPUT: 'List with 4 items'",
      "SPEECH OUTPUT: 'Dashing picture of Willie Walker'",
      "SPEECH OUTPUT: 'image'",
      "SPEECH OUTPUT: 'Ain't he handsome (please say yes)?'",
-     "SPEECH OUTPUT: 'Yes'",
      "SPEECH OUTPUT: 'not selected'",
      "SPEECH OUTPUT: 'radio button'",
-     "SPEECH OUTPUT: 'No'",
+     "SPEECH OUTPUT: 'Yes'",
      "SPEECH OUTPUT: 'not selected'",
-     "SPEECH OUTPUT: 'radio button'"]))
+     "SPEECH OUTPUT: 'radio button'",
+     "SPEECH OUTPUT: 'No'"]))
 
 sequence.append(utils.AssertionSummaryAction())
 sequence.start()
diff --git a/test/keystrokes/firefox/say_all_wiki.py b/test/keystrokes/firefox/say_all_wiki.py
index 2206676..23b3d7a 100644
--- a/test/keystrokes/firefox/say_all_wiki.py
+++ b/test/keystrokes/firefox/say_all_wiki.py
@@ -47,7 +47,6 @@ sequence.append(utils.AssertPresentationAction(
      "SPEECH OUTPUT: 'link'",
      "SPEECH OUTPUT: 'en Español'",
      "SPEECH OUTPUT: 'link'",
-     "SPEECH OUTPUT: 'image'",
      "SPEECH OUTPUT: 'Home'",
      "SPEECH OUTPUT: 'link'",
      "SPEECH OUTPUT: '|'",
@@ -62,11 +61,9 @@ sequence.append(utils.AssertPresentationAction(
      "SPEECH OUTPUT: '|'",
      "SPEECH OUTPUT: 'Mailing List'",
      "SPEECH OUTPUT: 'link'",
-     "SPEECH OUTPUT: 'image'",
      "SPEECH OUTPUT: '('",
      "SPEECH OUTPUT: 'Archives'",
      "SPEECH OUTPUT: 'link'",
-     "SPEECH OUTPUT: 'image'",
      "SPEECH OUTPUT: ') |'",
      "SPEECH OUTPUT: 'FAQ'",
      "SPEECH OUTPUT: 'link'",
@@ -113,7 +110,6 @@ sequence.append(utils.AssertPresentationAction(
      "SPEECH OUTPUT: 'The development of Orca has been led by the'",
      "SPEECH OUTPUT: 'Accessibility Program Office of Sun Microsystems, Inc.'",
      "SPEECH OUTPUT: 'link'",
-     "SPEECH OUTPUT: 'image'",
      "SPEECH OUTPUT: 'with'",
      "SPEECH OUTPUT: 'contributions from many community members'",
      "SPEECH OUTPUT: 'link'",
@@ -121,7 +117,6 @@ sequence.append(utils.AssertPresentationAction(
      "SPEECH OUTPUT: 'The complete list of work to do, including bugs and feature requests, along with known 
problems in other components, is maintained in'",
      "SPEECH OUTPUT: 'Bugzilla'",
      "SPEECH OUTPUT: 'link'",
-     "SPEECH OUTPUT: 'image'",
      "SPEECH OUTPUT: '(please see our'",
      "SPEECH OUTPUT: 'notes on how we use Bugzilla'",
      "SPEECH OUTPUT: 'link'",
@@ -129,36 +124,29 @@ sequence.append(utils.AssertPresentationAction(
      "SPEECH OUTPUT: 'Please join and participate on the'",
      "SPEECH OUTPUT: 'Orca mailing list'",
      "SPEECH OUTPUT: 'link'",
-     "SPEECH OUTPUT: 'image'",
      "SPEECH OUTPUT: '('",
      "SPEECH OUTPUT: 'archives'",
      "SPEECH OUTPUT: 'link'",
-     "SPEECH OUTPUT: 'image'",
      "SPEECH OUTPUT: '): it's a helpful, kind, and productive environment composed of users and 
developers.'",
      "SPEECH OUTPUT: 'Audio Guides'",
      "SPEECH OUTPUT: 'heading level 1'",
      "SPEECH OUTPUT: 'Darragh \xd3 H\xe9iligh'",
      "SPEECH OUTPUT: 'link'",
-     "SPEECH OUTPUT: 'image'",
      "SPEECH OUTPUT: 'has created several audio guides for Orca.'",
      "SPEECH OUTPUT: 'This is a fantastic contribution (THANKS!)!!!'",
      "SPEECH OUTPUT: 'The audio guides can be found at'",
      "SPEECH OUTPUT: 'http://www.digitaldarragh.com/linuxat.asp'",
      "SPEECH OUTPUT: 'link'",
-     "SPEECH OUTPUT: 'image'",
      "SPEECH OUTPUT: 'and include the following:'",
      "SPEECH OUTPUT: '•'",
      "SPEECH OUTPUT: 'Walk through of the installation of Ubuntu 7.4. Very helpful tutorial'",
      "SPEECH OUTPUT: 'link'",
-     "SPEECH OUTPUT: 'image'",
      "SPEECH OUTPUT: '•'",
      "SPEECH OUTPUT: 'Review of Fedora 7 and the Orca screen reader for the Gnome graphical desktop'",
      "SPEECH OUTPUT: 'link'",
-     "SPEECH OUTPUT: 'image'",
      "SPEECH OUTPUT: '•'",
      "SPEECH OUTPUT: 'Guide to installing the latest versions of Firefox and Orca'",
      "SPEECH OUTPUT: 'link'",
-     "SPEECH OUTPUT: 'image'",
      "SPEECH OUTPUT: 'Download/Installation'",
      "SPEECH OUTPUT: 'heading level 1'",
      "SPEECH OUTPUT: 'As of GNOME 2.16,'",
@@ -166,11 +154,9 @@ sequence.append(utils.AssertPresentationAction(
      "SPEECH OUTPUT: 'As a result, Orca is already provided by default on a number of operating system 
distributions, including'",
      "SPEECH OUTPUT: 'Open Solaris'",
      "SPEECH OUTPUT: 'link'",
-     "SPEECH OUTPUT: 'image'",
      "SPEECH OUTPUT: 'and'",
      "SPEECH OUTPUT: 'Ubuntu'",
      "SPEECH OUTPUT: 'link'",
-     "SPEECH OUTPUT: 'image'",
      "SPEECH OUTPUT: '.'",
      "SPEECH OUTPUT: 'Please also refer to the'",
      "SPEECH OUTPUT: 'Download/Installation page'",
@@ -183,7 +169,6 @@ sequence.append(utils.AssertPresentationAction(
      "SPEECH OUTPUT: 'Orca is designed to present information as you navigate the desktop using the'",
      "SPEECH OUTPUT: 'built-in navigation mechanisms of GNOME'",
      "SPEECH OUTPUT: 'link'",
-     "SPEECH OUTPUT: 'image'",
      "SPEECH OUTPUT: '.'",
      "SPEECH OUTPUT: 'These navigation mechanisms are consistent across most desktop applications.'",
      "SPEECH OUTPUT: 'You may sometimes wish to control Orca itself, such as bringing up the'",
@@ -243,39 +228,31 @@ sequence.append(utils.AssertPresentationAction(
      "SPEECH OUTPUT: 'Mailing list:'",
      "SPEECH OUTPUT: 'orca-list gnome org'",
      "SPEECH OUTPUT: 'link'",
-     "SPEECH OUTPUT: 'image'",
      "SPEECH OUTPUT: '('",
      "SPEECH OUTPUT: 'Archives'",
      "SPEECH OUTPUT: 'link'",
-     "SPEECH OUTPUT: 'image'",
      "SPEECH OUTPUT: ')'",
      "SPEECH OUTPUT: '•'",
      "SPEECH OUTPUT: 'Bug database:'",
      "SPEECH OUTPUT: 'GNOME Bug Tracking System (Bugzilla)'",
      "SPEECH OUTPUT: 'link'",
-     "SPEECH OUTPUT: 'image'",
      "SPEECH OUTPUT: '('",
      "SPEECH OUTPUT: 'current bug list'",
      "SPEECH OUTPUT: 'link'",
-     "SPEECH OUTPUT: 'image'",
      "SPEECH OUTPUT: ')'",
      "SPEECH OUTPUT: '•'",
      "SPEECH OUTPUT: 'Design documents:'",
      "SPEECH OUTPUT: 'Orca Documentation Series'",
      "SPEECH OUTPUT: 'link'",
-     "SPEECH OUTPUT: 'image'",
      "SPEECH OUTPUT: '•'",
      "SPEECH OUTPUT: 'Dive Into Python, Mark Pilgrim'",
      "SPEECH OUTPUT: 'link'",
-     "SPEECH OUTPUT: 'image'",
      "SPEECH OUTPUT: '•'",
      "SPEECH OUTPUT: 'Python in a Nutshell, Alex Martelli'",
      "SPEECH OUTPUT: 'link'",
-     "SPEECH OUTPUT: 'image'",
      "SPEECH OUTPUT: '•'",
      "SPEECH OUTPUT: 'Python Pocket Reference, Mark Lutz'",
      "SPEECH OUTPUT: 'link'",
-     "SPEECH OUTPUT: 'image'",
      "SPEECH OUTPUT: 'separator'",
      "SPEECH OUTPUT: 'The information on this page and the other Orca-related pages on this site are 
distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty 
of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.'",
      "SPEECH OUTPUT: 'separator'",
@@ -295,6 +272,7 @@ sequence.append(utils.AssertPresentationAction(
      "SPEECH OUTPUT: 'Info'",
      "SPEECH OUTPUT: 'link'",
      "SPEECH OUTPUT: 'Attachments'",
+     "SPEECH OUTPUT: 'link'",
      "SPEECH OUTPUT: 'More Actions:'",
      "SPEECH OUTPUT: 'combo box'",
      "SPEECH OUTPUT: 'GNOME World Wide'",
diff --git a/test/keystrokes/firefox/spelling_errors.py b/test/keystrokes/firefox/spelling_errors.py
index e5bc582..79e736e 100644
--- a/test/keystrokes/firefox/spelling_errors.py
+++ b/test/keystrokes/firefox/spelling_errors.py
@@ -20,24 +20,24 @@ sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Left"))
 sequence.append(utils.AssertPresentationAction(
     "1. Left",
-    ["BRAILLE LINE:  'Thiss is a tesst.  $l'",
-     "     VISIBLE:  'Thiss is a tesst.  $l', cursor=18",
+    ["BRAILLE LINE:  'Tell me a little more about yourself: Thiss is a tesst.  $l'",
+     "     VISIBLE:  'ut yourself: Thiss is a tesst.  ', cursor=31",
      "SPEECH OUTPUT: 'space'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Left"))
 sequence.append(utils.AssertPresentationAction(
     "2. Left",
-    ["BRAILLE LINE:  'Thiss is a tesst.  $l'",
-     "     VISIBLE:  'Thiss is a tesst.  $l', cursor=17",
+    ["BRAILLE LINE:  'Tell me a little more about yourself: Thiss is a tesst.  $l'",
+     "     VISIBLE:  'ut yourself: Thiss is a tesst.  ', cursor=30",
      "SPEECH OUTPUT: 'dot'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Left"))
 sequence.append(utils.AssertPresentationAction(
     "3. Left",
-    ["BRAILLE LINE:  'Thiss is a tesst.  $l'",
-     "     VISIBLE:  'Thiss is a tesst.  $l', cursor=16",
+    ["BRAILLE LINE:  'Tell me a little more about yourself: Thiss is a tesst.  $l'",
+     "     VISIBLE:  'ut yourself: Thiss is a tesst.  ', cursor=29",
      "SPEECH OUTPUT: 'misspelled'",
      "SPEECH OUTPUT: 't'"]))
 
@@ -45,88 +45,88 @@ sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Left"))
 sequence.append(utils.AssertPresentationAction(
     "4. Left",
-    ["BRAILLE LINE:  'Thiss is a tesst.  $l'",
-     "     VISIBLE:  'Thiss is a tesst.  $l', cursor=15",
+    ["BRAILLE LINE:  'Tell me a little more about yourself: Thiss is a tesst.  $l'",
+     "     VISIBLE:  'ut yourself: Thiss is a tesst.  ', cursor=28",
      "SPEECH OUTPUT: 's'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Left"))
 sequence.append(utils.AssertPresentationAction(
     "5. Left",
-    ["BRAILLE LINE:  'Thiss is a tesst.  $l'",
-     "     VISIBLE:  'Thiss is a tesst.  $l', cursor=14",
+    ["BRAILLE LINE:  'Tell me a little more about yourself: Thiss is a tesst.  $l'",
+     "     VISIBLE:  'ut yourself: Thiss is a tesst.  ', cursor=27",
      "SPEECH OUTPUT: 's'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Left"))
 sequence.append(utils.AssertPresentationAction(
     "6. Left",
-    ["BRAILLE LINE:  'Thiss is a tesst.  $l'",
-     "     VISIBLE:  'Thiss is a tesst.  $l', cursor=13",
+    ["BRAILLE LINE:  'Tell me a little more about yourself: Thiss is a tesst.  $l'",
+     "     VISIBLE:  'ut yourself: Thiss is a tesst.  ', cursor=26",
      "SPEECH OUTPUT: 'e'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Left"))
 sequence.append(utils.AssertPresentationAction(
     "7. Left",
-    ["BRAILLE LINE:  'Thiss is a tesst.  $l'",
-     "     VISIBLE:  'Thiss is a tesst.  $l', cursor=12",
+    ["BRAILLE LINE:  'Tell me a little more about yourself: Thiss is a tesst.  $l'",
+     "     VISIBLE:  'ut yourself: Thiss is a tesst.  ', cursor=25",
      "SPEECH OUTPUT: 't'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Left"))
 sequence.append(utils.AssertPresentationAction(
     "8. Left",
-    ["BRAILLE LINE:  'Thiss is a tesst.  $l'",
-     "     VISIBLE:  'Thiss is a tesst.  $l', cursor=11",
+    ["BRAILLE LINE:  'Tell me a little more about yourself: Thiss is a tesst.  $l'",
+     "     VISIBLE:  'ut yourself: Thiss is a tesst.  ', cursor=24",
      "SPEECH OUTPUT: 'space'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Left"))
 sequence.append(utils.AssertPresentationAction(
     "9. Left",
-    ["BRAILLE LINE:  'Thiss is a tesst.  $l'",
-     "     VISIBLE:  'Thiss is a tesst.  $l', cursor=10",
+    ["BRAILLE LINE:  'Tell me a little more about yourself: Thiss is a tesst.  $l'",
+     "     VISIBLE:  'ut yourself: Thiss is a tesst.  ', cursor=23",
      "SPEECH OUTPUT: 'a'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Left"))
 sequence.append(utils.AssertPresentationAction(
     "10. Left",
-    ["BRAILLE LINE:  'Thiss is a tesst.  $l'",
-     "     VISIBLE:  'Thiss is a tesst.  $l', cursor=9",
+    ["BRAILLE LINE:  'Tell me a little more about yourself: Thiss is a tesst.  $l'",
+     "     VISIBLE:  'ut yourself: Thiss is a tesst.  ', cursor=22",
      "SPEECH OUTPUT: 'space'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Left"))
 sequence.append(utils.AssertPresentationAction(
     "11. Left",
-    ["BRAILLE LINE:  'Thiss is a tesst.  $l'",
-     "     VISIBLE:  'Thiss is a tesst.  $l', cursor=8",
+    ["BRAILLE LINE:  'Tell me a little more about yourself: Thiss is a tesst.  $l'",
+     "     VISIBLE:  'ut yourself: Thiss is a tesst.  ', cursor=21",
      "SPEECH OUTPUT: 's'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Left"))
 sequence.append(utils.AssertPresentationAction(
     "12. Left",
-    ["BRAILLE LINE:  'Thiss is a tesst.  $l'",
-     "     VISIBLE:  'Thiss is a tesst.  $l', cursor=7",
+    ["BRAILLE LINE:  'Tell me a little more about yourself: Thiss is a tesst.  $l'",
+     "     VISIBLE:  'ut yourself: Thiss is a tesst.  ', cursor=20",
      "SPEECH OUTPUT: 'i'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Left"))
 sequence.append(utils.AssertPresentationAction(
     "13. Left",
-    ["BRAILLE LINE:  'Thiss is a tesst.  $l'",
-     "     VISIBLE:  'Thiss is a tesst.  $l', cursor=6",
+    ["BRAILLE LINE:  'Tell me a little more about yourself: Thiss is a tesst.  $l'",
+     "     VISIBLE:  'ut yourself: Thiss is a tesst.  ', cursor=19",
      "SPEECH OUTPUT: 'space'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Left"))
 sequence.append(utils.AssertPresentationAction(
     "14. Left",
-    ["BRAILLE LINE:  'Thiss is a tesst.  $l'",
-     "     VISIBLE:  'Thiss is a tesst.  $l', cursor=5",
+    ["BRAILLE LINE:  'Tell me a little more about yourself: Thiss is a tesst.  $l'",
+     "     VISIBLE:  'ut yourself: Thiss is a tesst.  ', cursor=18",
      "SPEECH OUTPUT: 'misspelled'",
      "SPEECH OUTPUT: 's'"]))
 
@@ -134,120 +134,120 @@ sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Left"))
 sequence.append(utils.AssertPresentationAction(
     "15. Left",
-    ["BRAILLE LINE:  'Thiss is a tesst.  $l'",
-     "     VISIBLE:  'Thiss is a tesst.  $l', cursor=4",
+    ["BRAILLE LINE:  'Tell me a little more about yourself: Thiss is a tesst.  $l'",
+     "     VISIBLE:  'ut yourself: Thiss is a tesst.  ', cursor=17",
      "SPEECH OUTPUT: 's'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Left"))
 sequence.append(utils.AssertPresentationAction(
     "16. Left",
-    ["BRAILLE LINE:  'Thiss is a tesst.  $l'",
-     "     VISIBLE:  'Thiss is a tesst.  $l', cursor=3",
+    ["BRAILLE LINE:  'Tell me a little more about yourself: Thiss is a tesst.  $l'",
+     "     VISIBLE:  'ut yourself: Thiss is a tesst.  ', cursor=16",
      "SPEECH OUTPUT: 'i'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Left"))
 sequence.append(utils.AssertPresentationAction(
     "17. Left",
-    ["BRAILLE LINE:  'Thiss is a tesst.  $l'",
-     "     VISIBLE:  'Thiss is a tesst.  $l', cursor=2",
+    ["BRAILLE LINE:  'Tell me a little more about yourself: Thiss is a tesst.  $l'",
+     "     VISIBLE:  'ut yourself: Thiss is a tesst.  ', cursor=15",
      "SPEECH OUTPUT: 'h'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Left"))
 sequence.append(utils.AssertPresentationAction(
     "18. Left",
-    ["BRAILLE LINE:  'Thiss is a tesst.  $l'",
-     "     VISIBLE:  'Thiss is a tesst.  $l', cursor=1",
+    ["BRAILLE LINE:  'Tell me a little more about yourself: Thiss is a tesst.  $l'",
+     "     VISIBLE:  'ut yourself: Thiss is a tesst.  ', cursor=14",
      "SPEECH OUTPUT: 'T'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Right"))
 sequence.append(utils.AssertPresentationAction(
     "19. Right",
-    ["BRAILLE LINE:  'Thiss is a tesst.  $l'",
-     "     VISIBLE:  'Thiss is a tesst.  $l', cursor=2",
+    ["BRAILLE LINE:  'Tell me a little more about yourself: Thiss is a tesst.  $l'",
+     "     VISIBLE:  'ut yourself: Thiss is a tesst.  ', cursor=15",
      "SPEECH OUTPUT: 'h'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Right"))
 sequence.append(utils.AssertPresentationAction(
     "20. Right",
-    ["BRAILLE LINE:  'Thiss is a tesst.  $l'",
-     "     VISIBLE:  'Thiss is a tesst.  $l', cursor=3",
+    ["BRAILLE LINE:  'Tell me a little more about yourself: Thiss is a tesst.  $l'",
+     "     VISIBLE:  'ut yourself: Thiss is a tesst.  ', cursor=16",
      "SPEECH OUTPUT: 'i'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Right"))
 sequence.append(utils.AssertPresentationAction(
     "21. Right",
-    ["BRAILLE LINE:  'Thiss is a tesst.  $l'",
-     "     VISIBLE:  'Thiss is a tesst.  $l', cursor=4",
+    ["BRAILLE LINE:  'Tell me a little more about yourself: Thiss is a tesst.  $l'",
+     "     VISIBLE:  'ut yourself: Thiss is a tesst.  ', cursor=17",
      "SPEECH OUTPUT: 's'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Right"))
 sequence.append(utils.AssertPresentationAction(
     "22. Right",
-    ["BRAILLE LINE:  'Thiss is a tesst.  $l'",
-     "     VISIBLE:  'Thiss is a tesst.  $l', cursor=5",
+    ["BRAILLE LINE:  'Tell me a little more about yourself: Thiss is a tesst.  $l'",
+     "     VISIBLE:  'ut yourself: Thiss is a tesst.  ', cursor=18",
      "SPEECH OUTPUT: 's'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Right"))
 sequence.append(utils.AssertPresentationAction(
     "23. Right",
-    ["BRAILLE LINE:  'Thiss is a tesst.  $l'",
-     "     VISIBLE:  'Thiss is a tesst.  $l', cursor=6",
+    ["BRAILLE LINE:  'Tell me a little more about yourself: Thiss is a tesst.  $l'",
+     "     VISIBLE:  'ut yourself: Thiss is a tesst.  ', cursor=19",
      "SPEECH OUTPUT: 'space'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Right"))
 sequence.append(utils.AssertPresentationAction(
     "24. Right",
-    ["BRAILLE LINE:  'Thiss is a tesst.  $l'",
-     "     VISIBLE:  'Thiss is a tesst.  $l', cursor=7",
+    ["BRAILLE LINE:  'Tell me a little more about yourself: Thiss is a tesst.  $l'",
+     "     VISIBLE:  'ut yourself: Thiss is a tesst.  ', cursor=20",
      "SPEECH OUTPUT: 'i'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Right"))
 sequence.append(utils.AssertPresentationAction(
     "25. Right",
-    ["BRAILLE LINE:  'Thiss is a tesst.  $l'",
-     "     VISIBLE:  'Thiss is a tesst.  $l', cursor=8",
+    ["BRAILLE LINE:  'Tell me a little more about yourself: Thiss is a tesst.  $l'",
+     "     VISIBLE:  'ut yourself: Thiss is a tesst.  ', cursor=21",
      "SPEECH OUTPUT: 's'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Right"))
 sequence.append(utils.AssertPresentationAction(
     "26. Right",
-    ["BRAILLE LINE:  'Thiss is a tesst.  $l'",
-     "     VISIBLE:  'Thiss is a tesst.  $l', cursor=9",
+    ["BRAILLE LINE:  'Tell me a little more about yourself: Thiss is a tesst.  $l'",
+     "     VISIBLE:  'ut yourself: Thiss is a tesst.  ', cursor=22",
      "SPEECH OUTPUT: 'space'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Right"))
 sequence.append(utils.AssertPresentationAction(
     "27. Right",
-    ["BRAILLE LINE:  'Thiss is a tesst.  $l'",
-     "     VISIBLE:  'Thiss is a tesst.  $l', cursor=10",
+    ["BRAILLE LINE:  'Tell me a little more about yourself: Thiss is a tesst.  $l'",
+     "     VISIBLE:  'ut yourself: Thiss is a tesst.  ', cursor=23",
      "SPEECH OUTPUT: 'a'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Right"))
 sequence.append(utils.AssertPresentationAction(
     "28. Right",
-    ["BRAILLE LINE:  'Thiss is a tesst.  $l'",
-     "     VISIBLE:  'Thiss is a tesst.  $l', cursor=11",
+    ["BRAILLE LINE:  'Tell me a little more about yourself: Thiss is a tesst.  $l'",
+     "     VISIBLE:  'ut yourself: Thiss is a tesst.  ', cursor=24",
      "SPEECH OUTPUT: 'space'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Right"))
 sequence.append(utils.AssertPresentationAction(
     "29. Right",
-    ["BRAILLE LINE:  'Thiss is a tesst.  $l'",
-     "     VISIBLE:  'Thiss is a tesst.  $l', cursor=12",
+    ["BRAILLE LINE:  'Tell me a little more about yourself: Thiss is a tesst.  $l'",
+     "     VISIBLE:  'ut yourself: Thiss is a tesst.  ', cursor=25",
      "SPEECH OUTPUT: 'misspelled'",
      "SPEECH OUTPUT: 't'"]))
 
@@ -255,64 +255,64 @@ sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Right"))
 sequence.append(utils.AssertPresentationAction(
     "30. Right",
-    ["BRAILLE LINE:  'Thiss is a tesst.  $l'",
-     "     VISIBLE:  'Thiss is a tesst.  $l', cursor=13",
+    ["BRAILLE LINE:  'Tell me a little more about yourself: Thiss is a tesst.  $l'",
+     "     VISIBLE:  'ut yourself: Thiss is a tesst.  ', cursor=26",
      "SPEECH OUTPUT: 'e'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Right"))
 sequence.append(utils.AssertPresentationAction(
     "31. Right",
-    ["BRAILLE LINE:  'Thiss is a tesst.  $l'",
-     "     VISIBLE:  'Thiss is a tesst.  $l', cursor=14",
+    ["BRAILLE LINE:  'Tell me a little more about yourself: Thiss is a tesst.  $l'",
+     "     VISIBLE:  'ut yourself: Thiss is a tesst.  ', cursor=27",
      "SPEECH OUTPUT: 's'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Right"))
 sequence.append(utils.AssertPresentationAction(
     "32. Right",
-    ["BRAILLE LINE:  'Thiss is a tesst.  $l'",
-     "     VISIBLE:  'Thiss is a tesst.  $l', cursor=15",
+    ["BRAILLE LINE:  'Tell me a little more about yourself: Thiss is a tesst.  $l'",
+     "     VISIBLE:  'ut yourself: Thiss is a tesst.  ', cursor=28",
      "SPEECH OUTPUT: 's'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Right"))
 sequence.append(utils.AssertPresentationAction(
     "33. Right",
-    ["BRAILLE LINE:  'Thiss is a tesst.  $l'",
-     "     VISIBLE:  'Thiss is a tesst.  $l', cursor=16",
+    ["BRAILLE LINE:  'Tell me a little more about yourself: Thiss is a tesst.  $l'",
+     "     VISIBLE:  'ut yourself: Thiss is a tesst.  ', cursor=29",
      "SPEECH OUTPUT: 't'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Right"))
 sequence.append(utils.AssertPresentationAction(
     "34. Right",
-    ["BRAILLE LINE:  'Thiss is a tesst.  $l'",
-     "     VISIBLE:  'Thiss is a tesst.  $l', cursor=17",
+    ["BRAILLE LINE:  'Tell me a little more about yourself: Thiss is a tesst.  $l'",
+     "     VISIBLE:  'ut yourself: Thiss is a tesst.  ', cursor=30",
      "SPEECH OUTPUT: 'dot'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Right"))
 sequence.append(utils.AssertPresentationAction(
     "35. Right",
-    ["BRAILLE LINE:  'Thiss is a tesst.  $l'",
-     "     VISIBLE:  'Thiss is a tesst.  $l', cursor=18",
+    ["BRAILLE LINE:  'Tell me a little more about yourself: Thiss is a tesst.  $l'",
+     "     VISIBLE:  'ut yourself: Thiss is a tesst.  ', cursor=31",
      "SPEECH OUTPUT: 'space'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Right"))
 sequence.append(utils.AssertPresentationAction(
     "36. Right",
-    ["BRAILLE LINE:  'Thiss is a tesst.  $l'",
-     "     VISIBLE:  'Thiss is a tesst.  $l', cursor=19",
+    ["BRAILLE LINE:  'Tell me a little more about yourself: Thiss is a tesst.  $l'",
+     "     VISIBLE:  'ut yourself: Thiss is a tesst.  ', cursor=32",
      "SPEECH OUTPUT: 'blank' voice=system"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("<Control>Left"))
 sequence.append(utils.AssertPresentationAction(
     "37. Control Left",
-    ["BRAILLE LINE:  'Thiss is a tesst.  $l'",
-     "     VISIBLE:  'Thiss is a tesst.  $l', cursor=12",
+    ["BRAILLE LINE:  'Tell me a little more about yourself: Thiss is a tesst.  $l'",
+     "     VISIBLE:  'ut yourself: Thiss is a tesst.  ', cursor=25",
      "SPEECH OUTPUT: 'misspelled' voice=system",
      "SPEECH OUTPUT: 'tesst. '"]))
 
@@ -320,24 +320,24 @@ sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("<Control>Left"))
 sequence.append(utils.AssertPresentationAction(
     "38. Control Left",
-    ["BRAILLE LINE:  'Thiss is a tesst.  $l'",
-     "     VISIBLE:  'Thiss is a tesst.  $l', cursor=10",
+    ["BRAILLE LINE:  'Tell me a little more about yourself: Thiss is a tesst.  $l'",
+     "     VISIBLE:  'ut yourself: Thiss is a tesst.  ', cursor=23",
      "SPEECH OUTPUT: 'a '"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("<Control>Left"))
 sequence.append(utils.AssertPresentationAction(
     "39. Control Left",
-    ["BRAILLE LINE:  'Thiss is a tesst.  $l'",
-     "     VISIBLE:  'Thiss is a tesst.  $l', cursor=7",
+    ["BRAILLE LINE:  'Tell me a little more about yourself: Thiss is a tesst.  $l'",
+     "     VISIBLE:  'ut yourself: Thiss is a tesst.  ', cursor=20",
      "SPEECH OUTPUT: 'is '"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("<Control>Left"))
 sequence.append(utils.AssertPresentationAction(
     "40. Control Left",
-    ["BRAILLE LINE:  'Thiss is a tesst.  $l'",
-     "     VISIBLE:  'Thiss is a tesst.  $l', cursor=1",
+    ["BRAILLE LINE:  'Tell me a little more about yourself: Thiss is a tesst.  $l'",
+     "     VISIBLE:  'ut yourself: Thiss is a tesst.  ', cursor=14",
      "SPEECH OUTPUT: 'misspelled'",
      "SPEECH OUTPUT: 'Thiss '"]))
 
@@ -356,32 +356,32 @@ sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("<Control>Right"))
 sequence.append(utils.AssertPresentationAction(
     "42. Control Right",
-    ["BRAILLE LINE:  'Thiss is a tesst.  $l'",
-     "     VISIBLE:  'Thiss is a tesst.  $l', cursor=6",
+    ["BRAILLE LINE:  'Tell me a little more about yourself: Thiss is a tesst.  $l'",
+     "     VISIBLE:  'ut yourself: Thiss is a tesst.  ', cursor=19",
      "SPEECH OUTPUT: 'Thiss '"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("<Control>Right"))
 sequence.append(utils.AssertPresentationAction(
     "43. Control Right",
-    ["BRAILLE LINE:  'Thiss is a tesst.  $l'",
-     "     VISIBLE:  'Thiss is a tesst.  $l', cursor=9",
+    ["BRAILLE LINE:  'Tell me a little more about yourself: Thiss is a tesst.  $l'",
+     "     VISIBLE:  'ut yourself: Thiss is a tesst.  ', cursor=22",
      "SPEECH OUTPUT: 'is '"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("<Control>Right"))
 sequence.append(utils.AssertPresentationAction(
     "44. Control Right",
-    ["BRAILLE LINE:  'Thiss is a tesst.  $l'",
-     "     VISIBLE:  'Thiss is a tesst.  $l', cursor=11",
+    ["BRAILLE LINE:  'Tell me a little more about yourself: Thiss is a tesst.  $l'",
+     "     VISIBLE:  'ut yourself: Thiss is a tesst.  ', cursor=24",
      "SPEECH OUTPUT: 'a '"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("<Control>Right"))
 sequence.append(utils.AssertPresentationAction(
     "45. Control Right",
-    ["BRAILLE LINE:  'Thiss is a tesst.  $l'",
-     "     VISIBLE:  'Thiss is a tesst.  $l', cursor=18",
+    ["BRAILLE LINE:  'Tell me a little more about yourself: Thiss is a tesst.  $l'",
+     "     VISIBLE:  'ut yourself: Thiss is a tesst.  ', cursor=31",
      "SPEECH OUTPUT: 'misspelled'",
      "SPEECH OUTPUT: 'tesst. '"]))
 
diff --git a/test/keystrokes/firefox/ui_doc_tabs.py b/test/keystrokes/firefox/ui_doc_tabs.py
index 3325b60..223d64f 100644
--- a/test/keystrokes/firefox/ui_doc_tabs.py
+++ b/test/keystrokes/firefox/ui_doc_tabs.py
@@ -24,6 +24,8 @@ sequence.append(utils.AssertPresentationAction(
      "SPEECH OUTPUT: 'Orca - GNOME Live! page tab'",
      "SPEECH OUTPUT: 'Home link'"]))
 
+sequence.append(PauseAction(3000))
+
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("<Alt>1"))
 sequence.append(utils.AssertPresentationAction(
@@ -35,27 +37,29 @@ sequence.append(utils.AssertPresentationAction(
      "SPEECH OUTPUT: 'HTML test page page tab'",
      "SPEECH OUTPUT: 'Test Formats link'"]))
 
+sequence.append(PauseAction(3000))
+
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("<Alt>3"))
 sequence.append(utils.AssertPresentationAction(
     "3. Switch to third page tab - Bugzilla",
     ["BRAILLE LINE:  'Firefox application GNOME Bug Tracking System - Mozilla Firefox frame Browser tabs 
tool bar GNOME Bug Tracking System page tab'",
      "     VISIBLE:  'GNOME Bug Tracking System page t', cursor=1",
-     "BRAILLE LINE:  ' $l Show push button [Help]'",
-     "     VISIBLE:  ' $l Show push button [Help]', cursor=1",
+     "BRAILLE LINE:  'Enter a bug # or some search terms:  $l'",
+     "     VISIBLE:  ' a bug # or some search terms:  ', cursor=32",
      "BRAILLE LINE:  'Focus mode'",
      "     VISIBLE:  'Focus mode', cursor=0",
      "SPEECH OUTPUT: 'GNOME Bug Tracking System page tab'",
-     "SPEECH OUTPUT: 'entry'",
+     "SPEECH OUTPUT: 'Enter a bug # or some search terms: entry'",
      "SPEECH OUTPUT: 'Focus mode' voice=system"]))
 
+sequence.append(PauseAction(3000))
+
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("<Ctrl>w"))
 sequence.append(utils.AssertPresentationAction(
     "4. Close third page tab - land in second page",
-    ["BRAILLE LINE:  ' $l Show push button [Help]'",
-     "     VISIBLE:  ' $l Show push button [Help]', cursor=1",
-     "BRAILLE LINE:  'Firefox application Orca - GNOME Live! - Mozilla Firefox frame Browser tabs tool bar 
Orca - GNOME Live! page tab'",
+    ["BRAILLE LINE:  'Firefox application Orca - GNOME Live! - Mozilla Firefox frame Browser tabs tool bar 
Orca - GNOME Live! page tab'",
      "     VISIBLE:  'Orca - GNOME Live! page tab', cursor=1",
      "BRAILLE LINE:  'Home'",
      "     VISIBLE:  'Home', cursor=1",
diff --git a/test/keystrokes/firefox/ui_role_accel_label.py b/test/keystrokes/firefox/ui_role_accel_label.py
index 4e292a9..f43e846 100644
--- a/test/keystrokes/firefox/ui_role_accel_label.py
+++ b/test/keystrokes/firefox/ui_role_accel_label.py
@@ -31,6 +31,7 @@ sequence.append(utils.AssertPresentationAction(
     "3. Basic Where Am I",
     ["BRAILLE LINE:  'Firefox application Mozilla Firefox frame Menu Bar tool bar Application menu bar New 
Private Window(Shift+Ctrl+P)'",
      "     VISIBLE:  'New Private Window(Shift+Ctrl+P)', cursor=1",
+     "SPEECH OUTPUT: 'Mozilla Firefox frame'",
      "SPEECH OUTPUT: 'File menu'",
      "SPEECH OUTPUT: 'Menu Bar tool bar menu bar New Private Window Shift+Ctrl+P 3 of 12.'",
      "SPEECH OUTPUT: 'W'"]))
diff --git a/test/keystrokes/firefox/ui_role_check_menu_item.py 
b/test/keystrokes/firefox/ui_role_check_menu_item.py
index 9db44de..c22bd26 100644
--- a/test/keystrokes/firefox/ui_role_check_menu_item.py
+++ b/test/keystrokes/firefox/ui_role_check_menu_item.py
@@ -23,6 +23,7 @@ sequence.append(utils.AssertPresentationAction(
     "2. Basic Where Am I",
     ["BRAILLE LINE:  'Firefox application Mozilla Firefox frame Menu Bar tool bar Application menu bar < > 
Full Screen check menu item'",
      "     VISIBLE:  '< > Full Screen check menu item', cursor=1",
+     "SPEECH OUTPUT: 'Mozilla Firefox frame'",
      "SPEECH OUTPUT: 'View menu'",
      "SPEECH OUTPUT: 'Menu Bar tool bar Full Screen check menu item not checked 6 of 6.'",
      "SPEECH OUTPUT: 'F'"]))
diff --git a/test/keystrokes/firefox/ui_role_menu_bar.py b/test/keystrokes/firefox/ui_role_menu_bar.py
index 0261bc7..7f439c0 100644
--- a/test/keystrokes/firefox/ui_role_menu_bar.py
+++ b/test/keystrokes/firefox/ui_role_menu_bar.py
@@ -35,6 +35,7 @@ sequence.append(utils.AssertPresentationAction(
     "3. Basic Where Am I",
     ["BRAILLE LINE:  'Firefox application Mozilla Firefox frame Menu Bar tool bar Application menu bar New 
Tab(Ctrl+T)'",
      "     VISIBLE:  'New Tab(Ctrl+T)', cursor=1",
+     "SPEECH OUTPUT: 'Mozilla Firefox frame'",
      "SPEECH OUTPUT: 'File menu'",
      "SPEECH OUTPUT: 'Menu Bar tool bar menu bar New Tab Ctrl+T 1 of 12.'",
      "SPEECH OUTPUT: 'T'"]))
diff --git a/test/keystrokes/firefox/ui_role_radio_button.py b/test/keystrokes/firefox/ui_role_radio_button.py
index 9f54c33..822f460 100644
--- a/test/keystrokes/firefox/ui_role_radio_button.py
+++ b/test/keystrokes/firefox/ui_role_radio_button.py
@@ -17,6 +17,7 @@ sequence.append(utils.AssertPresentationAction(
     ["BRAILLE LINE:  'Firefox application Print dialog General page tab Range Range &=y All Pages radio 
button'",
      "     VISIBLE:  '&=y All Pages radio button', cursor=1",
      "SPEECH OUTPUT: 'General page tab'",
+     "SPEECH OUTPUT: 'Range panel'",
      "SPEECH OUTPUT: 'All Pages selected radio button'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -25,7 +26,7 @@ sequence.append(utils.AssertPresentationAction(
     "2. Basic Where Am I",
     ["BRAILLE LINE:  'Firefox application Print dialog General page tab Range Range &=y All Pages radio 
button'",
      "     VISIBLE:  '&=y All Pages radio button', cursor=1",
-     "SPEECH OUTPUT: 'All Pages radio button selected 1 of 4.'",
+     "SPEECH OUTPUT: 'Range All Pages radio button selected 1 of 4.'",
      "SPEECH OUTPUT: 'Alt+A'"]))
 
 sequence.append(KeyComboAction("Escape"))
diff --git a/test/keystrokes/firefox/ui_role_radio_menu_item.py 
b/test/keystrokes/firefox/ui_role_radio_menu_item.py
index 2db892b..685dd9e 100644
--- a/test/keystrokes/firefox/ui_role_radio_menu_item.py
+++ b/test/keystrokes/firefox/ui_role_radio_menu_item.py
@@ -24,6 +24,7 @@ sequence.append(utils.AssertPresentationAction(
     "2. Basic Where Am I",
     ["BRAILLE LINE:  'Firefox application Mozilla Firefox frame Menu Bar tool bar Application menu bar View 
menu & y No Style radio menu item'",
      "     VISIBLE:  '& y No Style radio menu item', cursor=1",
+     "SPEECH OUTPUT: 'Mozilla Firefox frame'",
      "SPEECH OUTPUT: 'View menu'",
      "SPEECH OUTPUT: 'Page Style menu'",
      "SPEECH OUTPUT: 'Menu Bar tool bar No Style radio menu item not selected 1 of 2.'",
@@ -43,6 +44,7 @@ sequence.append(utils.AssertPresentationAction(
     "4. Basic Where Am I",
     ["BRAILLE LINE:  'Firefox application Mozilla Firefox frame Menu Bar tool bar Application menu bar View 
menu &=y Basic Page Style radio menu item'",
      "     VISIBLE:  '&=y Basic Page Style radio menu ', cursor=1",
+     "SPEECH OUTPUT: 'Mozilla Firefox frame'",
      "SPEECH OUTPUT: 'View menu'",
      "SPEECH OUTPUT: 'Page Style menu'",
      "SPEECH OUTPUT: 'Menu Bar tool bar Basic Page Style radio menu item selected 2 of 2.'",
diff --git a/test/keystrokes/firefox/word_nav_links.py b/test/keystrokes/firefox/word_nav_links.py
index 05ed199..79e9d30 100644
--- a/test/keystrokes/firefox/word_nav_links.py
+++ b/test/keystrokes/firefox/word_nav_links.py
@@ -28,14 +28,10 @@ sequence.append(utils.AssertPresentationAction(
     "2. Next Word",
     ["BRAILLE LINE:  'Hello W o r l d. Go odbye w orld.'",
      "     VISIBLE:  'd. Go odbye w orld.', cursor=3",
-     "SPEECH OUTPUT: 'W'",
-     "SPEECH OUTPUT: 'link'",
-     "SPEECH OUTPUT: 'o'",
-     "SPEECH OUTPUT: 'link'",
-     "SPEECH OUTPUT: 'r'",
-     "SPEECH OUTPUT: 'link'",
-     "SPEECH OUTPUT: 'l'",
-     "SPEECH OUTPUT: 'link'",
+     "SPEECH OUTPUT: 'W link'",
+     "SPEECH OUTPUT: 'o link'",
+     "SPEECH OUTPUT: 'r link'",
+     "SPEECH OUTPUT: 'l link'",
      "SPEECH OUTPUT: 'd.'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -52,8 +48,8 @@ sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("<Control>Right"))
 sequence.append(utils.AssertPresentationAction(
     "4. Next Word",
-    ["BRAILLE LINE:  ' $l'",
-     "     VISIBLE:  ' $l', cursor=1",
+    ["BRAILLE LINE:  'Hello W o r l d. Go odbye w orld.'",
+     "     VISIBLE:  'Hello W o r l d. Go odbye w orld', cursor=0",
      "SPEECH OUTPUT: 'w'",
      "SPEECH OUTPUT: 'link'",
      "SPEECH OUTPUT: 'orld.'"]))
@@ -72,8 +68,7 @@ sequence.append(utils.AssertPresentationAction(
     "6. Next Word",
     ["BRAILLE LINE:  'More stuff! Yay!'",
      "     VISIBLE:  'More stuff! Yay!', cursor=12",
-     "SPEECH OUTPUT: 'stuff'",
-     "SPEECH OUTPUT: 'link'",
+     "SPEECH OUTPUT: 'stuff link'",
      "SPEECH OUTPUT: '!'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -82,8 +77,7 @@ sequence.append(utils.AssertPresentationAction(
     "7. Previous Word",
     ["BRAILLE LINE:  'More stuff! Yay!'",
      "     VISIBLE:  'More stuff! Yay!', cursor=6",
-     "SPEECH OUTPUT: 'stuff'",
-     "SPEECH OUTPUT: 'link'",
+     "SPEECH OUTPUT: 'stuff link'",
      "SPEECH OUTPUT: '!'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -120,14 +114,10 @@ sequence.append(utils.AssertPresentationAction(
     "11. Previous Word",
     ["BRAILLE LINE:  'Hello W o r l d. Go odbye w orld.'",
      "     VISIBLE:  'W o r l d. Go odbye w orld.', cursor=1",
-     "SPEECH OUTPUT: 'W'",
-     "SPEECH OUTPUT: 'link'",
-     "SPEECH OUTPUT: 'o'",
-     "SPEECH OUTPUT: 'link'",
-     "SPEECH OUTPUT: 'r'",
-     "SPEECH OUTPUT: 'link'",
-     "SPEECH OUTPUT: 'l'",
-     "SPEECH OUTPUT: 'link'",
+     "SPEECH OUTPUT: 'W link'",
+     "SPEECH OUTPUT: 'o link'",
+     "SPEECH OUTPUT: 'r link'",
+     "SPEECH OUTPUT: 'l link'",
      "SPEECH OUTPUT: 'd.'"]))
 
 sequence.append(utils.StartRecordingAction())
diff --git a/test/keystrokes/firefox/word_nav_list_items.py b/test/keystrokes/firefox/word_nav_list_items.py
index 05bba55..0add9b4 100644
--- a/test/keystrokes/firefox/word_nav_list_items.py
+++ b/test/keystrokes/firefox/word_nav_list_items.py
@@ -16,7 +16,7 @@ sequence.append(utils.AssertPresentationAction(
     "1. Line Down",
     ["BRAILLE LINE:  '1. This is a short list item.'",
      "     VISIBLE:  '1. This is a short list item.', cursor=1",
-     "SPEECH OUTPUT: '1. This is a short list item.'"]))
+     "SPEECH OUTPUT: '1. This is a short list item. '"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("<Control>Right"))


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]