[orca] Optionally announce when entering and leaving blockquotes, lists, and tables



commit 41382c219df17bd24df11f14c55bc77b925f4c56
Author: Joanmarie Diggs <jdiggs igalia com>
Date:   Wed Jan 11 06:40:46 2017 -0500

    Optionally announce when entering and leaving blockquotes, lists, and tables
    
    * Announcement is enabled by default, for both navigation and Say All
    * Announcement of each object type is independent (e.g. you can enable
      blockquotes, but disable tables and lists)
    * Announcement during navigation is independent of announcement during
      Say All (e.g. you can have blockquotes announced during navigation but
      not when using Say All, and tables announced during Say All but not
      during navigation)
    * At this time, announcement during Structural Navigation is not impacted
      by these changes. Thus disabling list announcement during navigation
      will not stop Orca from announcing list details when L is used to move
      to the next list. This is intentional.
    * In order for this functionality to work, the application or toolkit
      needs to expose the objects to us correctly. For example, LibreOffice
      Writer exposes list items using ROLE_PARAGRAPH; not ROLE_LIST_ITEM. It
      also fails to expose any parent container with ROLE_LIST. This makes it
      difficult to reliably identify the start and end of lists, doubly so
      due to other LibreOffice accessibility bugs. The situation is similar
      for blockquotes. We aren't attempting sad, fragile hacks to work around
      these LibreOffice issues.

 help/C/preferences_general.page                    |   25 ++
 help/C/preferences_speech.page                     |   42 +++
 src/orca/formatting.py                             |    8 +-
 src/orca/generator.py                              |    5 +
 src/orca/messages.py                               |   16 +-
 src/orca/orca-setup.ui                             |  299 +++++++++++++-------
 src/orca/orca_gui_prefs.py                         |   12 +
 src/orca/script_utilities.py                       |   21 ++-
 src/orca/scripts/apps/soffice/speech_generator.py  |   28 +--
 src/orca/scripts/default.py                        |    8 +-
 src/orca/scripts/web/script.py                     |   51 +++-
 src/orca/scripts/web/script_utilities.py           |   22 ++
 src/orca/scripts/web/speech_generator.py           |   14 +-
 src/orca/settings.py                               |   14 +-
 src/orca/speech_generator.py                       |  137 ++++++++-
 src/orca/structural_navigation.py                  |   20 +-
 test/keystrokes/firefox/html_access_keys.py        |    2 +-
 .../firefox/html_struct_nav_activate_link.py       |    6 +-
 .../firefox/html_struct_nav_large_obj.py           |    1 +
 .../firefox/html_struct_nav_list_item.py           |    6 +-
 test/keystrokes/firefox/html_struct_nav_lists.py   |   40 ++--
 test/keystrokes/firefox/line_nav_broken_list.py    |    1 +
 test/keystrokes/firefox/line_nav_bug_552887a.py    |    3 +-
 test/keystrokes/firefox/line_nav_bug_570757.py     |    7 +-
 .../firefox/line_nav_bug_570757.settings           |  165 +++++++++++
 .../firefox/line_nav_bug_570757_no_context.params  |    1 +
 .../firefox/line_nav_bug_570757_no_context.py      |   87 ++++++
 .../line_nav_bug_570757_no_context.settings        |  165 +++++++++++
 test/keystrokes/firefox/line_nav_bug_577239.py     |    8 +-
 .../firefox/line_nav_bug_577239.settings           |  165 +++++++++++
 .../firefox/line_nav_bug_577239_no_context.params  |    1 +
 .../firefox/line_nav_bug_577239_no_context.py      |  158 +++++++++++
 .../line_nav_bug_577239_no_context.settings        |  165 +++++++++++
 .../firefox/line_nav_roledescriptions.py           |    1 +
 test/keystrokes/firefox/line_nav_slash_test.py     |    3 +
 test/keystrokes/firefox/say_all_blockquote.py      |    5 +
 .../keystrokes/firefox/say_all_blockquote.settings |  165 +++++++++++
 .../firefox/say_all_blockquote_no_context.params   |    1 +
 .../firefox/say_all_blockquote_no_context.py       |   46 +++
 .../firefox/say_all_blockquote_no_context.settings |  165 +++++++++++
 test/keystrokes/firefox/say_all_bugzilla_search.py |   30 ++
 .../firefox/say_all_bugzilla_search.settings       |  165 +++++++++++
 .../say_all_bugzilla_search_no_context.params      |    1 +
 .../firefox/say_all_bugzilla_search_no_context.py  |  236 +++++++++++++++
 .../say_all_bugzilla_search_no_context.settings    |  165 +++++++++++
 test/keystrokes/firefox/say_all_multi_line_text.py |    8 +-
 .../firefox/say_all_multi_line_text.settings       |  165 +++++++++++
 .../say_all_multi_line_text_no_context.params      |    1 +
 .../firefox/say_all_multi_line_text_no_context.py  |   63 ++++
 .../say_all_multi_line_text_no_context.settings    |  165 +++++++++++
 test/keystrokes/firefox/say_all_nested_tables.py   |    1 -
 .../firefox/say_all_nested_tables.settings         |  165 +++++++++++
 .../say_all_nested_tables_no_context.params        |    1 +
 .../firefox/say_all_nested_tables_no_context.py    |   44 +++
 .../say_all_nested_tables_no_context.settings      |  165 +++++++++++
 test/keystrokes/firefox/say_all_role_links.py      |    1 +
 .../keystrokes/firefox/say_all_role_links.settings |  165 +++++++++++
 .../firefox/say_all_role_links_no_context.params   |    1 +
 .../firefox/say_all_role_links_no_context.py       |   68 +++++
 .../firefox/say_all_role_links_no_context.settings |  165 +++++++++++
 test/keystrokes/firefox/say_all_role_lists.py      |   17 ++
 .../keystrokes/firefox/say_all_role_lists.settings |  165 +++++++++++
 .../firefox/say_all_role_lists_no_context.params   |    1 +
 .../firefox/say_all_role_lists_no_context.py       |   50 ++++
 .../firefox/say_all_role_lists_no_context.settings |  165 +++++++++++
 test/keystrokes/firefox/say_all_table_caption.py   |    3 +
 .../firefox/say_all_table_caption.settings         |  165 +++++++++++
 .../say_all_table_caption_no_context.params        |    1 +
 .../firefox/say_all_table_caption_no_context.py    |   38 +++
 .../say_all_table_caption_no_context.settings      |  165 +++++++++++
 test/keystrokes/firefox/say_all_wiki.py            |   14 +-
 test/keystrokes/firefox/say_all_wiki.settings      |  165 +++++++++++
 .../firefox/say_all_wiki_no_context.params         |    1 +
 test/keystrokes/firefox/say_all_wiki_no_context.py |  296 +++++++++++++++++++
 .../firefox/say_all_wiki_no_context.settings       |  165 +++++++++++
 .../keystrokes/oocalc/document_enter_text.settings |  165 +++++++++++
 .../oocalc/document_enter_text_no_context.py       |   40 +++
 .../oocalc/document_enter_text_no_context.settings |  165 +++++++++++
 .../oocalc/document_nav_dynamic_headers.py         |    1 +
 .../oocalc/manage_names_combobox.settings          |  165 +++++++++++
 .../oocalc/manage_names_combobox_no_context.py     |   43 +++
 .../manage_names_combobox_no_context.settings      |  165 +++++++++++
 test/keystrokes/oowriter/messages_table.settings   |  165 +++++++++++
 .../oowriter/messages_table_no_context.py          |   93 ++++++
 .../oowriter/messages_table_no_context.settings    |  165 +++++++++++
 test/keystrokes/oowriter/say_all_table.params      |    1 +
 test/keystrokes/oowriter/say_all_table.py          |   65 +++++
 test/keystrokes/oowriter/say_all_table.settings    |  165 +++++++++++
 .../oowriter/say_all_table_no_context.params       |    1 +
 .../oowriter/say_all_table_no_context.py           |   62 ++++
 .../oowriter/say_all_table_no_context.settings     |  165 +++++++++++
 91 files changed, 6693 insertions(+), 208 deletions(-)
---
diff --git a/help/C/preferences_general.page b/help/C/preferences_general.page
index dc7c70b..1f14699 100644
--- a/help/C/preferences_general.page
+++ b/help/C/preferences_general.page
@@ -120,6 +120,31 @@
       Default value: not checked
     </p>
   </section>
+  <section id="say_all_announce_context">
+    <title>Announce Blockquotes, Lists, and Tables in Say All</title>
+    <p>
+      <app>Orca</app> can optionally provide more information about the document
+      content being spoken, such as announcing when you are entering and leaving
+      a blockquote, list, or table. Whether or not these announcements are made
+      can be configured independently through the following checkboxes:
+    </p>
+    <list>
+      <item><p>Announce blockquotes in Say All</p></item>
+      <item><p>Announce lists in Say All</p></item>
+      <item><p>Announce tables in Say All</p></item>
+    </list>
+    <p>
+      Default value: checked
+    </p>
+    <note style="note">
+      <p>
+        Whether or not <app>Orca</app> makes these announcements during
+        navigation is also configurable. You will find similar checkboxes
+        on the <gui>Speech</gui> page. For more information, see
+        <link xref="preferences_speech#spoken_context">Spoken Context</link>.
+      </p>
+    </note>
+  </section>
   <section id="say_all_by">
    <info>
       <desc>
diff --git a/help/C/preferences_speech.page b/help/C/preferences_speech.page
index 0665970..7099f51 100644
--- a/help/C/preferences_speech.page
+++ b/help/C/preferences_speech.page
@@ -196,6 +196,48 @@
         Default value: checked
       </p>
     </section>
+    <section id="announce_blockquotes_during_navigation">
+      <title>Announce blockquotes during navigation</title>
+      <p>
+        If <gui>Announce blockquotes during navigation</gui> is checked,
+        <app>Orca</app> will tell you when you navigate into or out of a
+        blockquote. Note that this setting is independent of whether or not
+        this announcement is made during Say All. See
+        <link xref="preferences_general#say_all_announce_context">Announce
+        Blockquotes, Lists, and Tables in Say All</link> for more information.
+      </p>
+      <p>
+        Default value: checked
+      </p>
+    </section>
+    <section id="announce_lists_during_navigation">
+      <title>Announce lists during navigation</title>
+      <p>
+        If <gui>Announce lists during navigation</gui> is checked,
+        <app>Orca</app> will tell you when you navigate into or out of a
+        list. Note that this setting is independent of whether or not
+        this announcement is made during Say All. See
+        <link xref="preferences_general#say_all_announce_context">Announce
+        Blockquotes, Lists, and Tables in Say All</link> for more information.
+      </p>
+      <p>
+        Default value: checked
+      </p>
+    </section>
+    <section id="announce_tables_during_navigation">
+      <title>Announce tables during navigation</title>
+      <p>
+        If <gui>Announce tables during navigation</gui> is checked,
+        <app>Orca</app> will tell you when you navigate into or out of a
+        table. Note that this setting is independent of whether or not
+        this announcement is made during Say All. See
+        <link xref="preferences_general#say_all_announce_context">Announce
+        Blockquotes, Lists, and Tables in Say All</link> for more information.
+      </p>
+      <p>
+        Default value: checked
+      </p>
+    </section>
     <section id="read_full_row_in_gui_tables">
       <title>Read full row in GUI tables</title>
       <p>
diff --git a/src/orca/formatting.py b/src/orca/formatting.py
index a61fa2a..1cb7037 100644
--- a/src/orca/formatting.py
+++ b/src/orca/formatting.py
@@ -129,6 +129,10 @@ formatting = {
         pyatspi.ROLE_ANIMATION: {
             'unfocused': 'labelAndName'
             },
+        pyatspi.ROLE_BLOCK_QUOTE: {
+            'focused' : 'leaving or roleName',
+            'unfocused': 'roleName + pause + displayedText',
+            },
         pyatspi.ROLE_CANVAS: {
             'focused': 'labelAndName + imageDescription + roleName + pause + positionInList',
             'unfocused': 'labelAndName + imageDescription + roleName + pause + positionInList',
@@ -233,7 +237,7 @@ formatting = {
             'basicWhereAmI': 'linkInfo + pause + siteDescription + pause + fileSize + pause + ' + MNEMONIC
             },
         pyatspi.ROLE_LIST: {
-            'focused': 'labelOrName + multiselectableState + numberOfChildren',
+            'focused': 'leaving or (labelOrName + multiselectableState + numberOfChildren)',
             'unfocused': 'labelOrName + pause + focusedItem + pause + multiselectableState + 
numberOfChildren + pause'
             },
         pyatspi.ROLE_LIST_BOX: {
@@ -385,7 +389,7 @@ formatting = {
             'unfocused': '(displayedText or name) + roleName',
         },
         pyatspi.ROLE_TABLE: {
-            'focused': 'labelAndName + pause + table',
+            'focused': 'leaving or (labelAndName + pause + table)',
             'unfocused': 'labelAndName + pause + table',
             'basicWhereAmI': 'labelAndName + pause + table'
             },
diff --git a/src/orca/generator.py b/src/orca/generator.py
index a037f9c..f7f9609 100644
--- a/src/orca/generator.py
+++ b/src/orca/generator.py
@@ -156,6 +156,9 @@ class Generator:
     def generateContents(self, contents, **args):
         return []
 
+    def generateContext(self, obj, **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
@@ -1167,6 +1170,8 @@ class Generator:
                 return 'ROLE_MATH_TABLE_ROW'
         if self._script.utilities.isStatic(obj):
             return 'ROLE_STATIC'
+        if self._script.utilities.isBlockquote(obj):
+            return pyatspi.ROLE_BLOCK_QUOTE
         if self._script.utilities.isFocusableLabel(obj):
             return pyatspi.ROLE_LIST_ITEM
 
diff --git a/src/orca/messages.py b/src/orca/messages.py
index 31853fa..287510a 100644
--- a/src/orca/messages.py
+++ b/src/orca/messages.py
@@ -1034,6 +1034,18 @@ LEARN_MODE_START_SPEECH = \
       "press F3. " \
       "To exit learn mode, press the escape key.")
 
+# Translators: This message is presented when a user is navigating within a
+# blockquote and then navigates out of it.
+LEAVING_BLOCKQUOTE = _("leaving blockquote.")
+
+# Translators: This message is presented when a user is navigating within a
+# list and then navigates out of it.
+LEAVING_LIST = _("leaving list.")
+
+# Translators: This message is presented when a user is navigating within a
+# table and then navigates out of it.
+LEAVING_TABLE = _("leaving table.")
+
 # Translators: when the user selects (highlights) or unselects text in a
 # document, Orca will speak information about what they have selected or
 # unselected. This message is presented when the user selects from the
@@ -1836,10 +1848,6 @@ TABLE_CELL_COORDINATES = _("Row %(row)d, column %(column)d.")
 # cell of a table in a document.
 TABLE_END = _("End of table")
 
-# Translators: This message is presented when a user is navigating within a
-# table and then navigates out of it.
-TABLE_LEAVING = _("leaving table.")
-
 # Translators: When users are navigating a table, they sometimes want the entire
 # row of a table read; other times they want just the current cell presented.
 # This string is a message presented to the user when this setting is toggled.
diff --git a/src/orca/orca-setup.ui b/src/orca/orca-setup.ui
index 846c7dc..1af3c40 100644
--- a/src/orca/orca-setup.ui
+++ b/src/orca/orca-setup.ui
@@ -459,7 +459,7 @@
                   </object>
                   <packing>
                     <property name="left_attach">0</property>
-                    <property name="top_attach">4</property>
+                    <property name="top_attach">3</property>
                     <property name="width">1</property>
                     <property name="height">1</property>
                   </packing>
@@ -652,42 +652,43 @@
                   </packing>
                 </child>
                 <child>
-                  <object class="GtkFrame" id="sayAllFrame">
+                  <object class="GtkFrame" id="progressBarUpdatesFrame">
                     <property name="visible">True</property>
                     <property name="can_focus">False</property>
                     <property name="label_xalign">0</property>
                     <property name="shadow_type">none</property>
                     <child>
-                      <object class="GtkAlignment" id="sayAllAlignment">
+                      <object class="GtkAlignment" id="progressBarUpdatesAlignment">
                         <property name="visible">True</property>
                         <property name="can_focus">False</property>
                         <property name="left_padding">12</property>
                         <child>
-                          <object class="GtkGrid" id="sayAllGrid">
+                          <object class="GtkGrid" id="progressBarUpdatesGrid">
                             <property name="visible">True</property>
                             <property name="can_focus">False</property>
                             <child>
-                              <object class="GtkCheckButton" id="rewindAndFastForwardInSayAllCheckButton">
-                                <property name="label" translatable="yes" comments="Translators: Orca has a 
Say All feature which speaks the entire document. Normally, pressing any key will interrupt Say All 
presentation. However, if rewind and fast forward is enabled, Up Arrow and Down Arrow can be used within Say 
All to quickly move within the document to re-hear something which was just read or skip past something of no 
interest.">Enable _rewind and fast forward in Say All</property>
+                              <object class="GtkCheckButton" id="speakProgressBarUpdatesCheckButton">
+                                <property name="label" translatable="yes" comments="Translators: This is an 
option in the Preferences dialog box related to the presentation of progress bar updates. If this checkbox is 
checked, Orca will periodically speak the current percentage.">_Speak updates</property>
                                 <property name="use_action_appearance">False</property>
                                 <property name="visible">True</property>
                                 <property name="can_focus">True</property>
                                 <property name="receives_default">False</property>
-                                <property name="use_action_appearance">False</property>
+                                <property name="valign">start</property>
+                                <property name="hexpand">True</property>
                                 <property name="use_underline">True</property>
+                                <property name="xalign">0</property>
+                                <property name="active">True</property>
                                 <property name="draw_indicator">True</property>
                                 <signal name="toggled" handler="checkButtonToggled" swapped="no"/>
                               </object>
                               <packing>
                                 <property name="left_attach">0</property>
                                 <property name="top_attach">0</property>
-                                <property name="width">1</property>
-                                <property name="height">1</property>
                               </packing>
                             </child>
                             <child>
-                              <object class="GtkCheckButton" id="structNavInSayAllCheckButton">
-                                <property name="label" translatable="yes" comments="Translators: Orca has a 
Say All feature which speaks the entire document. Normally, pressing any key will interrupt Say All 
presentation. However, if structural navigation is enabled for Say All, users can use commands such as 
H/Shift+H to jump to the next/previous heading, P/Shift+P to jump to the next/previous paragraph, T/Shift+T 
to jump to the next/previous table, and so on. Thus this setting is like fast forward and rewind, but with 
semantic awareness for web documents and similar content.">Enable _structural navigation in Say All</property>
+                              <object class="GtkCheckButton" id="brailleProgressBarUpdatesCheckButton">
+                                <property name="label" translatable="yes" comments="Translators: This is an 
option in the Preferences dialog box related to the presentation of progress bar updates. If this checkbox is 
checked, Orca will periodically display the current percentage in braille.">_Braille updates</property>
                                 <property name="use_action_appearance">False</property>
                                 <property name="visible">True</property>
                                 <property name="can_focus">True</property>
@@ -706,23 +707,36 @@
                               </packing>
                             </child>
                             <child>
-                              <object class="GtkGrid" id="sayAllStyleGrid">
+                              <object class="GtkGrid" id="progressBarUpdatesOptionsGrid">
                                 <property name="visible">True</property>
                                 <property name="can_focus">False</property>
-                                <property name="row_spacing">20</property>
+                                <property name="row_spacing">10</property>
                                 <property name="column_spacing">20</property>
                                 <child>
-                                  <object class="GtkLabel" id="sayAllStyleLabel">
-                                    <property name="name">-`</property>
+                                  <object class="GtkSpinButton" id="progressBarUpdateIntervalSpinButton">
+                                    <property name="visible">True</property>
+                                    <property name="can_focus">True</property>
+                                    <property name="invisible_char">●</property>
+                                    <property name="text" translatable="yes">10</property>
+                                    <property 
name="adjustment">progressBarUpdateIntervalAdjustment</property>
+                                    <property name="climb_rate">1</property>
+                                    <property name="numeric">True</property>
+                                    <property name="value">10</property>
+                                    <signal name="value-changed" 
handler="progressBarUpdateIntervalValueChanged" swapped="no"/>
+                                  </object>
+                                  <packing>
+                                    <property name="left_attach">1</property>
+                                    <property name="top_attach">0</property>
+                                  </packing>
+                                </child>
+                                <child>
+                                  <object class="GtkLabel" id="speakProgressBarLabel">
                                     <property name="visible">True</property>
                                     <property name="can_focus">False</property>
-                                    <property name="label" translatable="yes" comments="Translators: Say all 
by refers to the way that Orca will say (speak) an amount of text -- in particular, where Orca where insert 
pauses. There are currently two choices (supplied by a combo box to the right of this label): say all by 
sentence and say all by line.  If Orca were speaking a work of fiction, it would probably be best to do say 
all by sentence so it sounds more natural. If Orca were speaking something like a page of computer commands, 
doing a say all by line would work better.">Say All B_y:</property>
+                                    <property name="label" translatable="yes" context="ProgressBar" 
comments="Translators: Here this is a label for a spin button through which a user can customize the 
frequency in seconds an announcement should be made regarding the current value of a progress bar.">Frequency 
(secs):</property>
                                     <property name="use_underline">True</property>
-                                    <property name="mnemonic_widget">sayAllStyle</property>
+                                    <property 
name="mnemonic_widget">progressBarUpdateIntervalSpinButton</property>
                                     <property name="xalign">0</property>
-                                    <accessibility>
-                                      <relation type="label-for" target="sayAllStyle"/>
-                                    </accessibility>
                                   </object>
                                   <packing>
                                     <property name="left_attach">0</property>
@@ -730,13 +744,27 @@
                                   </packing>
                                 </child>
                                 <child>
-                                  <object class="GtkComboBox" id="sayAllStyle">
+                                  <object class="GtkLabel" id="progressBarVerbosityLabel">
                                     <property name="visible">True</property>
                                     <property name="can_focus">False</property>
-                                    <property name="model">model2</property>
-                                    <signal name="changed" handler="sayAllStyleChanged" swapped="no"/>
+                                    <property name="label" translatable="yes" comments="Translators: Orca 
has a setting which determines which progress bar updates should be announced. The options are all progress 
bars, only progress bars in the active application, or only progress bars in the current window.">Restrict 
to:</property>
+                                    <property name="use_underline">True</property>
+                                    <property name="mnemonic_widget">progressBarVerbosity</property>
+                                    <property name="xalign">0</property>
+                                  </object>
+                                  <packing>
+                                    <property name="left_attach">0</property>
+                                    <property name="top_attach">1</property>
+                                  </packing>
+                                </child>
+                                <child>
+                                  <object class="GtkComboBox" id="progressBarVerbosity">
+                                    <property name="visible">True</property>
+                                    <property name="can_focus">False</property>
+                                    <property name="model">model7</property>
+                                    <signal name="changed" handler="progressBarVerbosityChanged" 
swapped="no"/>
                                     <child>
-                                      <object class="GtkCellRendererText" id="renderer2"/>
+                                      <object class="GtkCellRendererText" id="renderer33"/>
                                       <attributes>
                                         <attribute name="text">0</attribute>
                                       </attributes>
@@ -744,12 +772,32 @@
                                   </object>
                                   <packing>
                                     <property name="left_attach">1</property>
-                                    <property name="top_attach">0</property>
+                                    <property name="top_attach">1</property>
                                   </packing>
                                 </child>
                               </object>
                               <packing>
                                 <property name="left_attach">0</property>
+                                <property name="top_attach">3</property>
+                              </packing>
+                            </child>
+                            <child>
+                              <object class="GtkCheckButton" id="beepProgressBarUpdatesCheckButton">
+                                <property name="label" translatable="yes" comments="Translators: This is an 
option in the Preferences dialog box related to the presentation of progress bar updates. If this checkbox is 
checked, Orca will periodically emit beeps which increase in pitch as the value of the progress bar 
increases.">Bee_p updates</property>
+                                <property name="use_action_appearance">False</property>
+                                <property name="visible">True</property>
+                                <property name="can_focus">True</property>
+                                <property name="receives_default">False</property>
+                                <property name="valign">start</property>
+                                <property name="hexpand">True</property>
+                                <property name="use_underline">True</property>
+                                <property name="xalign">0</property>
+                                <property name="active">True</property>
+                                <property name="draw_indicator">True</property>
+                                <signal name="toggled" handler="checkButtonToggled" swapped="no"/>
+                              </object>
+                              <packing>
+                                <property name="left_attach">0</property>
                                 <property name="top_attach">2</property>
                               </packing>
                             </child>
@@ -758,10 +806,10 @@
                       </object>
                     </child>
                     <child type="label">
-                      <object class="GtkLabel" id="sayAllLabel">
+                      <object class="GtkLabel" id="progressBarUpdatesLabel">
                         <property name="visible">True</property>
                         <property name="can_focus">False</property>
-                        <property name="label" translatable="yes">Say All</property>
+                        <property name="label" translatable="yes" comments="Translators: This is a label in 
the Preferences dialog box. It applies to several options related to which progress bars Orca should speak 
and how often Orca should speak them.">Progress Bar Updates</property>
                         <attributes>
                           <attribute name="weight" value="bold"/>
                         </attributes>
@@ -769,56 +817,52 @@
                     </child>
                   </object>
                   <packing>
-                    <property name="left_attach">0</property>
-                    <property name="top_attach">3</property>
-                    <property name="width">1</property>
-                    <property name="height">1</property>
+                    <property name="left_attach">1</property>
+                    <property name="top_attach">0</property>
+                    <property name="height">2</property>
                   </packing>
                 </child>
                 <child>
-                  <object class="GtkFrame" id="progressBarUpdatesFrame">
+                  <object class="GtkFrame" id="sayAllFrame">
                     <property name="visible">True</property>
                     <property name="can_focus">False</property>
                     <property name="label_xalign">0</property>
                     <property name="shadow_type">none</property>
                     <child>
-                      <object class="GtkAlignment" id="progressBarUpdatesAlignment">
+                      <object class="GtkAlignment" id="sayAllAlignment">
                         <property name="visible">True</property>
                         <property name="can_focus">False</property>
                         <property name="left_padding">12</property>
                         <child>
-                          <object class="GtkGrid" id="progressBarUpdatesGrid">
+                          <object class="GtkGrid" id="sayAllGrid">
                             <property name="visible">True</property>
                             <property name="can_focus">False</property>
                             <child>
-                              <object class="GtkCheckButton" id="speakProgressBarUpdatesCheckButton">
-                                <property name="label" translatable="yes" comments="Translators: This is an 
option in the Preferences dialog box related to the presentation of progress bar updates. If this checkbox is 
checked, Orca will periodically speak the current percentage.">_Speak updates</property>
+                              <object class="GtkCheckButton" id="rewindAndFastForwardInSayAllCheckButton">
+                                <property name="label" translatable="yes" comments="Translators: Orca has a 
Say All feature which speaks the entire document. Normally, pressing any key will interrupt Say All 
presentation. However, if rewind and fast forward is enabled, Up Arrow and Down Arrow can be used within Say 
All to quickly move within the document to re-hear something which was just read or skip past something of no 
interest.">Enable _rewind and fast forward in Say All</property>
                                 <property name="use_action_appearance">False</property>
                                 <property name="visible">True</property>
                                 <property name="can_focus">True</property>
                                 <property name="receives_default">False</property>
-                                <property name="valign">start</property>
-                                <property name="hexpand">True</property>
                                 <property name="use_underline">True</property>
                                 <property name="xalign">0</property>
-                                <property name="active">True</property>
                                 <property name="draw_indicator">True</property>
                                 <signal name="toggled" handler="checkButtonToggled" swapped="no"/>
                               </object>
                               <packing>
                                 <property name="left_attach">0</property>
                                 <property name="top_attach">0</property>
+                                <property name="width">1</property>
+                                <property name="height">1</property>
                               </packing>
                             </child>
                             <child>
-                              <object class="GtkCheckButton" id="brailleProgressBarUpdatesCheckButton">
-                                <property name="label" translatable="yes" comments="Translators: This is an 
option in the Preferences dialog box related to the presentation of progress bar updates. If this checkbox is 
checked, Orca will periodically display the current percentage in braille.">_Braille updates</property>
+                              <object class="GtkCheckButton" id="structNavInSayAllCheckButton">
+                                <property name="label" translatable="yes" comments="Translators: Orca has a 
Say All feature which speaks the entire document. Normally, pressing any key will interrupt Say All 
presentation. However, if structural navigation is enabled for Say All, users can use commands such as 
H/Shift+H to jump to the next/previous heading, P/Shift+P to jump to the next/previous paragraph, T/Shift+T 
to jump to the next/previous table, and so on. Thus this setting is like fast forward and rewind, but with 
semantic awareness for web documents and similar content.">Enable _structural navigation in Say All</property>
                                 <property name="use_action_appearance">False</property>
                                 <property name="visible">True</property>
                                 <property name="can_focus">True</property>
                                 <property name="receives_default">False</property>
-                                <property name="valign">start</property>
-                                <property name="hexpand">True</property>
                                 <property name="use_underline">True</property>
                                 <property name="xalign">0</property>
                                 <property name="active">True</property>
@@ -831,35 +875,23 @@
                               </packing>
                             </child>
                             <child>
-                              <object class="GtkGrid" id="progressBarUpdatesOptionsGrid">
+                              <object class="GtkGrid" id="sayAllStyleGrid">
                                 <property name="visible">True</property>
                                 <property name="can_focus">False</property>
-                                <property name="column_spacing">12</property>
-                                <child>
-                                  <object class="GtkSpinButton" id="progressBarUpdateIntervalSpinButton">
-                                    <property name="visible">True</property>
-                                    <property name="can_focus">True</property>
-                                    <property name="invisible_char">●</property>
-                                    <property name="text" translatable="yes">10</property>
-                                    <property 
name="adjustment">progressBarUpdateIntervalAdjustment</property>
-                                    <property name="climb_rate">1</property>
-                                    <property name="numeric">True</property>
-                                    <property name="value">10</property>
-                                    <signal name="value-changed" 
handler="progressBarUpdateIntervalValueChanged" swapped="no"/>
-                                  </object>
-                                  <packing>
-                                    <property name="left_attach">1</property>
-                                    <property name="top_attach">0</property>
-                                  </packing>
-                                </child>
+                                <property name="row_spacing">20</property>
+                                <property name="column_spacing">20</property>
                                 <child>
-                                  <object class="GtkLabel" id="speakProgressBarLabel">
+                                  <object class="GtkLabel" id="sayAllStyleLabel">
+                                    <property name="name">-`</property>
                                     <property name="visible">True</property>
                                     <property name="can_focus">False</property>
-                                    <property name="label" translatable="yes" context="ProgressBar" 
comments="Translators: Here this is a label for a spin button through which a user can customize the 
frequency in seconds an announcement should be made regarding the current value of a progress bar.">Frequency 
(secs):</property>
+                                    <property name="label" translatable="yes" comments="Translators: Say all 
by refers to the way that Orca will say (speak) an amount of text -- in particular, where Orca where insert 
pauses. There are currently two choices (supplied by a combo box to the right of this label): say all by 
sentence and say all by line.  If Orca were speaking a work of fiction, it would probably be best to do say 
all by sentence so it sounds more natural. If Orca were speaking something like a page of computer commands, 
doing a say all by line would work better.">Say All B_y:</property>
                                     <property name="use_underline">True</property>
-                                    <property 
name="mnemonic_widget">progressBarUpdateIntervalSpinButton</property>
+                                    <property name="mnemonic_widget">sayAllStyle</property>
                                     <property name="xalign">0</property>
+                                    <accessibility>
+                                      <relation type="label-for" target="sayAllStyle"/>
+                                    </accessibility>
                                   </object>
                                   <packing>
                                     <property name="left_attach">0</property>
@@ -867,27 +899,13 @@
                                   </packing>
                                 </child>
                                 <child>
-                                  <object class="GtkLabel" id="progressBarVerbosityLabel">
-                                    <property name="visible">True</property>
-                                    <property name="can_focus">False</property>
-                                    <property name="label" translatable="yes" comments="Translators: Orca 
has a setting which determines which progress bar updates should be announced. The options are all progress 
bars, only progress bars in the active application, or only progress bars in the current window.">Restrict 
to:</property>
-                                    <property name="use_underline">True</property>
-                                    <property name="mnemonic_widget">progressBarVerbosity</property>
-                                    <property name="xalign">0</property>
-                                  </object>
-                                  <packing>
-                                    <property name="left_attach">0</property>
-                                    <property name="top_attach">1</property>
-                                  </packing>
-                                </child>
-                                <child>
-                                  <object class="GtkComboBox" id="progressBarVerbosity">
+                                  <object class="GtkComboBox" id="sayAllStyle">
                                     <property name="visible">True</property>
                                     <property name="can_focus">False</property>
-                                    <property name="model">model7</property>
-                                    <signal name="changed" handler="progressBarVerbosityChanged" 
swapped="no"/>
+                                    <property name="model">model2</property>
+                                    <signal name="changed" handler="sayAllStyleChanged" swapped="no"/>
                                     <child>
-                                      <object class="GtkCellRendererText" id="renderer33"/>
+                                      <object class="GtkCellRendererText" id="renderer2"/>
                                       <attributes>
                                         <attribute name="text">0</attribute>
                                       </attributes>
@@ -895,24 +913,22 @@
                                   </object>
                                   <packing>
                                     <property name="left_attach">1</property>
-                                    <property name="top_attach">1</property>
+                                    <property name="top_attach">0</property>
                                   </packing>
                                 </child>
                               </object>
                               <packing>
                                 <property name="left_attach">0</property>
-                                <property name="top_attach">3</property>
+                                <property name="top_attach">5</property>
                               </packing>
                             </child>
                             <child>
-                              <object class="GtkCheckButton" id="beepProgressBarUpdatesCheckButton">
-                                <property name="label" translatable="yes" comments="Translators: This is an 
option in the Preferences dialog box related to the presentation of progress bar updates. If this checkbox is 
checked, Orca will periodically emit beeps which increase in pitch as the value of the progress bar 
increases.">Bee_p updates</property>
+                              <object class="GtkCheckButton" id="sayAllContextBlockquoteCheckButton">
+                                <property name="label" translatable="yes" comments="Translators: Orca has a 
Say All feature which speaks the entire document. Some users want to hear additional information about what 
is being spoken. If this checkbox is checked, Orca will announce that a blockquote has been entered before 
speaking the text. At the end of the text, Orca will announce that the blockquote is being exited.">Announce 
block_quotes in Say All</property>
                                 <property name="use_action_appearance">False</property>
                                 <property name="visible">True</property>
                                 <property name="can_focus">True</property>
                                 <property name="receives_default">False</property>
-                                <property name="valign">start</property>
-                                <property name="hexpand">True</property>
                                 <property name="use_underline">True</property>
                                 <property name="xalign">0</property>
                                 <property name="active">True</property>
@@ -924,15 +940,51 @@
                                 <property name="top_attach">2</property>
                               </packing>
                             </child>
+                            <child>
+                              <object class="GtkCheckButton" id="sayAllContextListCheckButton">
+                                <property name="label" translatable="yes" comments="Translators: Orca has a 
Say All feature which speaks the entire document. Some users want to hear additional information about what 
is being spoken. If this checkbox is checked, Orca will announce that a list with x items has been entered 
before speaking the content of that list. At the end of the list content, Orca will announce that the list is 
being exited.">Announce li_sts in Say All</property>
+                                <property name="use_action_appearance">False</property>
+                                <property name="visible">True</property>
+                                <property name="can_focus">True</property>
+                                <property name="receives_default">False</property>
+                                <property name="use_underline">True</property>
+                                <property name="xalign">0</property>
+                                <property name="active">True</property>
+                                <property name="draw_indicator">True</property>
+                                <signal name="toggled" handler="checkButtonToggled" swapped="no"/>
+                              </object>
+                              <packing>
+                                <property name="left_attach">0</property>
+                                <property name="top_attach">3</property>
+                              </packing>
+                            </child>
+                            <child>
+                              <object class="GtkCheckButton" id="sayAllContextTableCheckButton">
+                                <property name="label" translatable="yes" comments="Translators: Orca has a 
Say All feature which speaks the entire document. Some users want to hear additional information about what 
is being spoken. If this checkbox is checked, Orca will announce that a table with x rows and y columns has 
been entered before speaking the content of that table. At the end of the table content, Orca will announce 
that the table is being exited.">Announce _tables in Say All</property>
+                                <property name="use_action_appearance">False</property>
+                                <property name="visible">True</property>
+                                <property name="can_focus">True</property>
+                                <property name="receives_default">False</property>
+                                <property name="use_underline">True</property>
+                                <property name="xalign">0</property>
+                                <property name="active">True</property>
+                                <property name="draw_indicator">True</property>
+                                <signal name="toggled" handler="checkButtonToggled" swapped="no"/>
+                              </object>
+                              <packing>
+                                <property name="left_attach">0</property>
+                                <property name="top_attach">4</property>
+                              </packing>
+                            </child>
                           </object>
                         </child>
                       </object>
                     </child>
                     <child type="label">
-                      <object class="GtkLabel" id="progressBarUpdatesLabel">
+                      <object class="GtkLabel" id="sayAllLabel">
                         <property name="visible">True</property>
                         <property name="can_focus">False</property>
-                        <property name="label" translatable="yes" comments="Translators: This is a label in 
the Preferences dialog box. It applies to several options related to which progress bars Orca should speak 
and how often Orca should speak them.">Progress Bar Updates</property>
+                        <property name="label" translatable="yes">Say All</property>
                         <attributes>
                           <attribute name="weight" value="bold"/>
                         </attributes>
@@ -941,19 +993,10 @@
                   </object>
                   <packing>
                     <property name="left_attach">1</property>
-                    <property name="top_attach">0</property>
+                    <property name="top_attach">2</property>
                     <property name="height">2</property>
                   </packing>
                 </child>
-                <child>
-                  <placeholder/>
-                </child>
-                <child>
-                  <placeholder/>
-                </child>
-                <child>
-                  <placeholder/>
-                </child>
               </object>
             </child>
             <child type="tab">
@@ -1808,6 +1851,60 @@
                                             <property name="top_attach">6</property>
                                           </packing>
                                         </child>
+                                        <child>
+                                          <object class="GtkCheckButton" 
id="speakContextBlockquoteCheckButton">
+                                            <property name="label" translatable="yes" comments="Translators: 
Orca can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document 
content.  If this checkbox is checked, Orca will announce that a blockquote has been entered as the user 
arrows into it and before speaking the text. Upon navigating out of the blockquote, Orca will announce that 
the blockquote has been exited prior to speaking the new location.">Announce block_quotes during 
navigation</property>
+                                            <property name="use_action_appearance">False</property>
+                                            <property name="visible">True</property>
+                                            <property name="can_focus">True</property>
+                                            <property name="receives_default">False</property>
+                                            <property name="use_underline">True</property>
+                                            <property name="xalign">0</property>
+                                            <property name="active">True</property>
+                                            <property name="draw_indicator">True</property>
+                                            <signal name="toggled" handler="checkButtonToggled" 
swapped="no"/>
+                                          </object>
+                                          <packing>
+                                            <property name="left_attach">0</property>
+                                            <property name="top_attach">7</property>
+                                          </packing>
+                                        </child>
+                                        <child>
+                                          <object class="GtkCheckButton" id="speakContextListCheckButton">
+                                            <property name="label" translatable="yes" comments="Translators: 
Orca can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document 
content.  If this checkbox is checked, Orca will announce that a list with x items has been entered as the 
user arrows into it and before speaking the list content. Upon navigating out of the list, Orca will announce 
that the list has been exited prior to speaking the new location.">Announce _lists during 
navigation</property>
+                                            <property name="use_action_appearance">False</property>
+                                            <property name="visible">True</property>
+                                            <property name="can_focus">True</property>
+                                            <property name="receives_default">False</property>
+                                            <property name="use_underline">True</property>
+                                            <property name="xalign">0</property>
+                                            <property name="active">True</property>
+                                            <property name="draw_indicator">True</property>
+                                            <signal name="toggled" handler="checkButtonToggled" 
swapped="no"/>
+                                          </object>
+                                          <packing>
+                                            <property name="left_attach">0</property>
+                                            <property name="top_attach">8</property>
+                                          </packing>
+                                        </child>
+                                        <child>
+                                          <object class="GtkCheckButton" id="speakContextTableCheckButton">
+                                            <property name="label" translatable="yes" comments="Translators: 
Orca can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document 
content.  If this checkbox is checked, Orca will announce that a table with x rows and y columns has been 
entered as the user arrows into it and before speaking the table content. Upon navigating out of the table, 
Orca will announce that the table has been exited prior to speaking the new location.">Announce _tables 
during navigation</property>
+                                            <property name="use_action_appearance">False</property>
+                                            <property name="visible">True</property>
+                                            <property name="can_focus">True</property>
+                                            <property name="receives_default">False</property>
+                                            <property name="use_underline">True</property>
+                                            <property name="xalign">0</property>
+                                            <property name="active">True</property>
+                                            <property name="draw_indicator">True</property>
+                                            <signal name="toggled" handler="checkButtonToggled" 
swapped="no"/>
+                                          </object>
+                                          <packing>
+                                            <property name="left_attach">0</property>
+                                            <property name="top_attach">9</property>
+                                          </packing>
+                                        </child>
                                       </object>
                                       <packing>
                                         <property name="left_attach">0</property>
diff --git a/src/orca/orca_gui_prefs.py b/src/orca/orca_gui_prefs.py
index ea92f3c..1c41020 100644
--- a/src/orca/orca_gui_prefs.py
+++ b/src/orca/orca_gui_prefs.py
@@ -1324,6 +1324,12 @@ class OrcaSetupGUI(orca_gtkbuilder.GtkBuilderWrapper):
             prefs["enableMnemonicSpeaking"])
         self.get_widget("speakMisspelledIndicatorCheckButton").set_active(
             prefs.get("speakMisspelledIndicator", settings.speakMisspelledIndicator))
+        self.get_widget("speakContextBlockquoteCheckButton").set_active(
+            prefs.get("speakContextBlockquote", settings.speakContextList))
+        self.get_widget("speakContextListCheckButton").set_active(
+            prefs.get("speakContextList", settings.speakContextList))
+        self.get_widget("speakContextTableCheckButton").set_active(
+            prefs.get("speakContextTable", settings.speakContextTable))
 
         enable = prefs.get("messagesAreDetailed", settings.messagesAreDetailed)
         self.get_widget("messagesAreDetailedCheckButton").set_active(enable)
@@ -1606,6 +1612,12 @@ class OrcaSetupGUI(orca_gtkbuilder.GtkBuilderWrapper):
             prefs.get("rewindAndFastForwardInSayAll", settings.rewindAndFastForwardInSayAll))
         self.get_widget("structNavInSayAllCheckButton").set_active(
             prefs.get("structNavInSayAll", settings.structNavInSayAll))
+        self.get_widget("sayAllContextBlockquoteCheckButton").set_active(
+            prefs.get("sayAllContextBlockquote", settings.sayAllContextBlockquote))
+        self.get_widget("sayAllContextListCheckButton").set_active(
+            prefs.get("sayAllListBlockquote", settings.sayAllContextList))
+        self.get_widget("sayAllContextTableCheckButton").set_active(
+            prefs.get("sayAllTableBlockquote", settings.sayAllContextTable))
 
         # Orca User Profiles
         #
diff --git a/src/orca/script_utilities.py b/src/orca/script_utilities.py
index f7c8cad..501ccac 100644
--- a/src/orca/script_utilities.py
+++ b/src/orca/script_utilities.py
@@ -884,6 +884,22 @@ class Utilities:
 
         return int((val / (maxval - minval)) * 100)
 
+    def isBlockquote(self, obj):
+        return obj and obj.getRole() == pyatspi.ROLE_BLOCK_QUOTE
+
+    def isDocumentList(self, obj):
+        if not (obj and obj.getRole() == pyatspi.ROLE_LIST):
+            return False
+
+        try:
+            document = pyatspi.findAncestor(obj, self.isDocument)
+        except:
+            msg = "ERROR: Exception finding ancestor of %s" % obj
+            debug.println(debug.LEVEL_INFO, msg)
+            return False
+
+        return document is not None
+
     def isDocument(self, obj):
         documentRoles = [pyatspi.ROLE_DOCUMENT_EMAIL,
                          pyatspi.ROLE_DOCUMENT_FRAME,
@@ -1035,6 +1051,9 @@ class Utilities:
         return row != lastRow
 
     def shouldReadFullRow(self, obj):
+        if self._script.inSayAll():
+            return False
+
         table = self.getTable(obj)
         if not table:
             return False
@@ -1179,7 +1198,7 @@ class Utilities:
             elif parentRole == pyatspi.ROLE_TABLE:
                 layoutOnly = self.isLayoutOnly(obj.parent)
         elif role == pyatspi.ROLE_SECTION:
-            layoutOnly = True
+            layoutOnly = not self.isBlockquote(obj)
         elif role == pyatspi.ROLE_FILLER:
             layoutOnly = True
         elif role == pyatspi.ROLE_SCROLL_PANE:
diff --git a/src/orca/scripts/apps/soffice/speech_generator.py 
b/src/orca/scripts/apps/soffice/speech_generator.py
index 0e66ef2..c05e90f 100644
--- a/src/orca/scripts/apps/soffice/speech_generator.py
+++ b/src/orca/scripts/apps/soffice/speech_generator.py
@@ -389,6 +389,9 @@ class SpeechGenerator(speech_generator.SpeechGenerator):
         Returns a list of utterances to be spoken for the object.
         """
 
+        if self._script.inSayAll():
+            return []
+
         result = super()._generateRealTableCell(obj, **args)
 
         if not self._script.utilities.isSpreadSheetCell(obj):
@@ -447,48 +450,35 @@ class SpeechGenerator(speech_generator.SpeechGenerator):
         dialog).
         """
 
-        if self._script._lastCommandWasStructNav:
+        if self._script._lastCommandWasStructNav or self._script.inSayAll():
             return []
 
         topLevel = self._script.utilities.topLevelObject(obj)
         if topLevel and topLevel.getRole() == pyatspi.ROLE_DIALOG:
             return []
 
-        return (speech_generator.SpeechGenerator._generateEndOfTableIndicator(
-                self, obj, **args))
+        return super()._generateEndOfTableIndicator(obj, **args)
 
     def _generateNewAncestors(self, obj, **args):
         priorObj = args.get('priorObj', None)
         if not priorObj or priorObj.getRoleName() == 'text frame':
             return []
 
-        return speech_generator.SpeechGenerator._generateNewAncestors(
-            self, obj, **args)
+        return super()._generateNewAncestors(obj, **args)
 
     def _generateOldAncestors(self, obj, **args):
         """Returns an array of strings (and possibly voice and audio
         specifications) that represent the text of the ancestors for
         the object being left."""
 
-        priorObj = args.get('priorObj', None)
-        if not priorObj:
+        if obj.getRoleName() == 'text frame':
             return []
 
+        priorObj = args.get('priorObj', None)
         if self._script.utilities.isSpreadSheetCell(priorObj):
             return []
 
-        isTable = lambda x: x and x.getRole() == pyatspi.ROLE_TABLE
-        oldTable = pyatspi.findAncestor(priorObj, isTable)
-        if oldTable:
-            ancestor = self._script.utilities.commonAncestor(oldTable, obj)
-            if self._script.utilities.isDocument(ancestor):
-                result = [messages.TABLE_LEAVING]
-                result.extend(self.voice(speech_generator.SYSTEM))
-                result.extend(self._generatePause(obj, **args))
-                return result
-
-        return speech_generator.SpeechGenerator._generateOldAncestors(
-            self, obj, **args)
+        return super()._generateOldAncestors(obj, **args)
 
     def _generateUnselectedCell(self, obj, **args):
         if self._script.utilities.isSpreadSheetCell(obj):
diff --git a/src/orca/scripts/default.py b/src/orca/scripts/default.py
index 54c0380..924d181 100644
--- a/src/orca/scripts/default.py
+++ b/src/orca/scripts/default.py
@@ -3451,10 +3451,14 @@ class Script(script.Script):
         else:
             mode = pyatspi.TEXT_BOUNDARY_LINE_START
 
+        priorObj = obj
+
         # Get the next line of text to read
         #
         done = False
         while not done:
+            speech.speak(self.speechGenerator.generateContext(obj, priorObj=priorObj))
+
             lastEndOffset = -1
             while offset < length:
                 [lineString, startOffset, endOffset] = text.getTextAtOffset(
@@ -3502,8 +3506,8 @@ class Script(script.Script):
             moreLines = False
             relations = obj.getRelationSet()
             for relation in relations:
-                if relation.getRelationType()  \
-                       == pyatspi.RELATION_FLOWS_TO:
+                if relation.getRelationType() == pyatspi.RELATION_FLOWS_TO:
+                    priorObj = obj
                     obj = relation.getTarget(0)
 
                     try:
diff --git a/src/orca/scripts/web/script.py b/src/orca/scripts/web/script.py
index c519bc2..65f3689 100644
--- a/src/orca/scripts/web/script.py
+++ b/src/orca/scripts/web/script.py
@@ -541,6 +541,7 @@ class Script(default.Script):
             obj, characterOffset = self.utilities.getCaretContext()
         else:
             characterOffset = offset
+        priorObj, priorOffset = self.utilities.getPriorContext()
 
         self._inSayAll = True
         done = False
@@ -555,14 +556,25 @@ class Script(default.Script):
                     continue
 
                 obj, startOffset, endOffset, text = content
-                utterances = self.speechGenerator.generateContents([content], eliminatePauses=True)
+                utterances = self.speechGenerator.generateContents(
+                    [content], eliminatePauses=True, priorObj=priorObj)
+                priorObj = obj
 
                 # TODO - JD: This is sad, but it's better than the old, broken
                 # clumpUtterances(). We really need to fix the speechservers'
                 # SayAll support. In the meantime, the generators should be
                 # providing one ACSS per string.
-                elements = list(filter(lambda x: isinstance(x, str), utterances[0]))
-                voices = list(filter(lambda x: isinstance(x, ACSS), utterances[0]))
+                utterance = utterances[0]
+                elements, voices = [], []
+                for u in utterance:
+                    if isinstance(u, list):
+                        elements.extend(filter(lambda x: isinstance(x, str), u))
+                        voices.extend(filter(lambda x: isinstance(x, ACSS), u))
+                    elif isinstance(u, str):
+                        elements.append(u)
+                    elif isinstance(u, ACSS):
+                        voices.append(u)
+
                 if len(elements) != len(voices):
                     continue
 
@@ -722,10 +734,10 @@ class Script(default.Script):
 
         return self.utilities.isFocusModeWidget(obj)
 
-    def speakContents(self, contents):
+    def speakContents(self, contents, **args):
         """Speaks the specified contents."""
 
-        utterances = self.speechGenerator.generateContents(contents)
+        utterances = self.speechGenerator.generateContents(contents, **args)
         speech.speak(utterances)
 
     def sayCharacter(self, obj):
@@ -776,15 +788,24 @@ class Script(default.Script):
             super().sayLine(obj)
             return
 
+        priorObj = None
+        if self._lastCommandWasCaretNav:
+            priorObj, priorOffset = self.utilities.getPriorContext()
+
         obj, offset = self.utilities.getCaretContext(documentFrame=None)
-        self.speakContents(self.utilities.getLineContentsAtOffset(obj, offset))
+        contents = self.utilities.getLineContentsAtOffset(obj, offset)
+        self.speakContents(contents, priorObj=priorObj)
 
     def presentObject(self, obj, **args):
+        priorObj = None
+        if self._lastCommandWasCaretNav:
+            priorObj, priorOffset = self.utilities.getPriorContext()
+
         offset = args.get("offset", 0)
         contents = self.utilities.getObjectContentsAtOffset(obj, offset)
         self.displayContents(contents)
-        self.speakContents(contents)
-
+        self.speakContents(contents, priorObj=priorObj)
+ 
     def updateBraille(self, obj, **args):
         """Updates the braille display to show the given object."""
 
@@ -1260,8 +1281,8 @@ class Script(default.Script):
         if self._lastCommandWasMouseButton:
             msg = "WEB: Event handled: Last command was mouse button"
             debug.println(debug.LEVEL_INFO, msg, True)
-            orca.setLocusOfFocus(event, event.source)
             self.utilities.setCaretContext(event.source, event.detail1)
+            orca.setLocusOfFocus(event, event.source)
             return True
 
         if self.utilities.inFindToolbar():
@@ -1296,24 +1317,24 @@ class Script(default.Script):
         if self.utilities.caretMovedToSamePageFragment(event):
             msg = "WEB: Event handled: Caret moved to fragment"
             debug.println(debug.LEVEL_INFO, msg, True)
-            orca.setLocusOfFocus(event, obj)
             self.utilities.setCaretContext(obj, offset)
+            orca.setLocusOfFocus(event, obj)
             return True
 
         if self.utilities.lastInputEventWasPageNav() \
            and not self.utilities.isLink(event.source):
             msg = "WEB: Event handled: Caret moved due to scrolling"
             debug.println(debug.LEVEL_INFO, msg, True)
-            orca.setLocusOfFocus(event, obj)
             self.utilities.setCaretContext(obj, offset)
+            orca.setLocusOfFocus(event, obj)
             return True
 
         if self.utilities.isContentEditableWithEmbeddedObjects(event.source):
             msg = "WEB: In content editable with embedded objects"
             debug.println(debug.LEVEL_INFO, msg, True)
             notify = orca_state.locusOfFocus == orca_state.activeWindow
-            orca.setLocusOfFocus(event, event.source, notify)
             self.utilities.setCaretContext(obj, offset)
+            orca.setLocusOfFocus(event, event.source, notify)
             return False
 
         text = self.utilities.queryNonEmptyText(event.source)
@@ -1321,8 +1342,8 @@ class Script(default.Script):
             if event.source.getRole() == pyatspi.ROLE_LINK:
                 msg = "WEB: Event handled: Was for non-text link"
                 debug.println(debug.LEVEL_INFO, msg, True)
-                orca.setLocusOfFocus(event, event.source)
                 self.utilities.setCaretContext(event.source, event.detail1)
+                orca.setLocusOfFocus(event, event.source)
             else:
                 msg = "WEB: Event ignored: Was for non-text non-link"
                 debug.println(debug.LEVEL_INFO, msg, True)
@@ -1347,8 +1368,8 @@ class Script(default.Script):
 
             msg = "WEB: Setting locusOfFocus, context to: %s, %i" % (obj, offset)
             debug.println(debug.LEVEL_INFO, msg, True)
-            orca.setLocusOfFocus(event, obj)
             self.utilities.setCaretContext(obj, offset)
+            orca.setLocusOfFocus(event, obj)
             return True
 
         if self.utilities.treatEventAsSpinnerValueChange(event):
@@ -1360,8 +1381,8 @@ class Script(default.Script):
 
         if not _settingsManager.getSetting('caretNavigationEnabled') \
            or self._inFocusMode or isEditable:
-            orca.setLocusOfFocus(event, event.source, False)
             self.utilities.setCaretContext(event.source, event.detail1)
+            orca.setLocusOfFocus(event, event.source, False)
             msg = "WEB: Setting locusOfFocus, context to: %s, %i" % \
                   (event.source, event.detail1)
             debug.println(debug.LEVEL_INFO, msg, True)
diff --git a/src/orca/scripts/web/script_utilities.py b/src/orca/scripts/web/script_utilities.py
index 9e11ff7..c839c4f 100644
--- a/src/orca/scripts/web/script_utilities.py
+++ b/src/orca/scripts/web/script_utilities.py
@@ -48,6 +48,7 @@ class Utilities(script_utilities.Utilities):
 
         self._currentAttrs = {}
         self._caretContexts = {}
+        self._priorContexts = {}
         self._contextPathsRolesAndNames = {}
         self._paths = {}
         self._inDocumentContent = {}
@@ -151,6 +152,7 @@ class Utilities(script_utilities.Utilities):
         self._paths = {}
         self._contextPathsRolesAndNames = {}
         self._cleanupContexts()
+        self._priorContexts = {}
 
     def clearContentCache(self):
         self._currentObjectContents = None
@@ -1663,6 +1665,12 @@ class Utilities(script_utilities.Utilities):
         self._treatAsDiv[hash(obj)] = rv
         return rv
 
+    def isBlockquote(self, obj):
+        if super().isBlockquote(obj):
+            return True
+
+        return self._getTag(obj) == 'blockquote'
+
     def speakMathSymbolNames(self, obj=None):
         obj = obj or orca_state.locusOfFocus
         return self.isMath(obj)
@@ -3051,6 +3059,7 @@ class Utilities(script_utilities.Utilities):
 
         parent = documentFrame.parent
         self._caretContexts.pop(hash(parent), None)
+        self._priorContexts.pop(hash(parent), None)
 
     def findContextReplicant(self, documentFrame=None, matchRole=True, matchName=True):
         path, oldRole, oldName = self._getCaretContextPathRoleAndName(documentFrame)
@@ -3069,6 +3078,17 @@ class Utilities(script_utilities.Utilities):
         debug.println(debug.LEVEL_INFO, msg, True)
         return obj, offset
 
+    def getPriorContext(self, documentFrame=None):
+        if not documentFrame or self.isZombie(documentFrame):
+            documentFrame = self.documentFrame()
+
+        if documentFrame:
+            context = self._priorContexts.get(hash(documentFrame.parent))
+            if context:
+                return context
+
+        return None, -1
+
     def _getPath(self, obj):
         rv = self._paths.get(hash(obj))
         if rv is not None:
@@ -3090,6 +3110,8 @@ class Utilities(script_utilities.Utilities):
             return
 
         parent = documentFrame.parent
+        oldObj, oldOffset = self._caretContexts.get(hash(parent), (obj, offset))
+        self._priorContexts[hash(parent)] = oldObj, oldOffset
         self._caretContexts[hash(parent)] = obj, offset
 
         path = self._getPath(obj)
diff --git a/src/orca/scripts/web/speech_generator.py b/src/orca/scripts/web/speech_generator.py
index 514fb11..a5d3630 100644
--- a/src/orca/scripts/web/speech_generator.py
+++ b/src/orca/scripts/web/speech_generator.py
@@ -54,7 +54,7 @@ class SpeechGenerator(speech_generator.SpeechGenerator):
         if priorObj and self._script.utilities.inDocumentContent(priorObj):
             priorDoc = self._script.utilities.getDocumentForObject(priorObj)
             doc = self._script.utilities.getDocumentForObject(obj)
-            if priorDoc != doc:
+            if priorDoc != doc and not self._script.utilities.getDocumentForObject(doc):
                 result = [super()._generateName(doc)]
 
         if self._script.utilities.isLink(obj) \
@@ -72,6 +72,7 @@ class SpeechGenerator(speech_generator.SpeechGenerator):
                                pyatspi.ROLE_TOOL_BAR]
         args['skipRoles'] = [pyatspi.ROLE_PARAGRAPH,
                              pyatspi.ROLE_LABEL,
+                             pyatspi.ROLE_LINK,
                              pyatspi.ROLE_LIST_ITEM,
                              pyatspi.ROLE_TEXT]
 
@@ -250,8 +251,11 @@ class SpeechGenerator(speech_generator.SpeechGenerator):
             return result
 
         role = args.get('role', obj.getRole())
-        force = args.get('force', False)
+        enabled, disabled = self._getEnabledAndDisabledContextRoles()
+        if role in disabled:
+            return []
 
+        force = args.get('force', False)
         start = args.get('startOffset')
         end = args.get('endOffset')
 
@@ -313,7 +317,7 @@ class SpeechGenerator(speech_generator.SpeechGenerator):
                 result.append(self.getLocalizedRoleName(obj, **args))
                 result.extend(acss)
 
-        elif role not in doNotSpeak:
+        elif role not in doNotSpeak and args.get('priorObj') != obj:
             result.append(self.getLocalizedRoleName(obj, **args))
             result.extend(acss)
 
@@ -470,6 +474,9 @@ class SpeechGenerator(speech_generator.SpeechGenerator):
         else:
             oldRole = self._overrideRole(self._getAlternativeRole(obj, **args), args)
 
+        if not 'priorObj' in args:
+            args['priorObj'] = self._script.utilities.getPriorContext()[0]
+
         result.extend(super().generateSpeech(obj, **args))
         result = list(filter(lambda x: x, result))
         self._restoreRole(oldRole, args)
@@ -499,6 +506,7 @@ class SpeechGenerator(speech_generator.SpeechGenerator):
                 index=i, total=len(contents), **args)
             if utterance and utterance[0]:
                 result.append(utterance)
+                args['priorObj'] = obj
 
         if not result:
             if self._script.inSayAll():
diff --git a/src/orca/settings.py b/src/orca/settings.py
index 63b09aa..67cde55 100644
--- a/src/orca/settings.py
+++ b/src/orca/settings.py
@@ -130,7 +130,13 @@ userCustomizableSettings = [
     "caretNavTriggersFocusMode",
     "layoutMode",
     "rewindAndFastForwardInSayAll",
-    "structNavInSayAll"
+    "structNavInSayAll",
+    "speakContextBlockquote",
+    "speakContextList",
+    "speakContextTable",
+    "sayAllContextBlockquote",
+    "sayAllContextList",
+    "sayAllContextTable"
 ]
 
 GENERAL_KEYBOARD_LAYOUT_DESKTOP = 1
@@ -231,6 +237,12 @@ verbalizePunctuationStyle    = PUNCTUATION_STYLE_MOST
 speechVerbosityLevel         = VERBOSITY_LEVEL_VERBOSE
 messagesAreDetailed          = True
 enablePauseBreaks            = True
+speakContextBlockquote       = True
+speakContextList             = True
+speakContextTable            = True
+sayAllContextBlockquote      = True
+sayAllContextList            = True
+sayAllContextTable           = True
 
 # Braille
 tty = 7
diff --git a/src/orca/speech_generator.py b/src/orca/speech_generator.py
index efb7cfa..e2888c2 100644
--- a/src/orca/speech_generator.py
+++ b/src/orca/speech_generator.py
@@ -286,7 +286,12 @@ class SpeechGenerator(generator.Generator):
         if _settingsManager.getSetting('onlySpeakDisplayedText'):
             return []
 
-        if _settingsManager.getSetting('speechVerbosityLevel') == \
+        if self._script.utilities.isTextDocumentTable(obj):
+            role = args.get('role', obj.getRole())
+            enabled, disabled = self._getEnabledAndDisabledContextRoles()
+            if role in disabled:
+                return []
+        elif _settingsManager.getSetting('speechVerbosityLevel') == \
            settings.VERBOSITY_LEVEL_BRIEF:
             return []
 
@@ -1498,6 +1503,51 @@ class SpeechGenerator(generator.Generator):
             result.extend(acss)
         return result
 
+    def _getEnabledAndDisabledContextRoles(self):
+        allRoles = [pyatspi.ROLE_BLOCK_QUOTE,
+                    pyatspi.ROLE_LIST,
+                    pyatspi.ROLE_TABLE]
+
+        enabled, disabled = [], []
+        if self._script.inSayAll():
+            if _settingsManager.getSetting('sayAllContextBlockquote'):
+                enabled.append(pyatspi.ROLE_BLOCK_QUOTE)
+            if _settingsManager.getSetting('sayAllContextList'):
+                enabled.append(pyatspi.ROLE_LIST)
+            if _settingsManager.getSetting('sayAllContextTable'):
+                enabled.append(pyatspi.ROLE_TABLE)
+        else:
+            if _settingsManager.getSetting('speakContextBlockquote'):
+                enabled.append(pyatspi.ROLE_BLOCK_QUOTE)
+            if _settingsManager.getSetting('speakContextList'):
+                enabled.append(pyatspi.ROLE_LIST)
+            if _settingsManager.getSetting('speakContextTable'):
+                enabled.append(pyatspi.ROLE_TABLE)
+
+        disabled = list(set(allRoles).symmetric_difference(enabled))
+        return enabled, disabled
+
+    def _generateLeaving(self, obj, **args):
+        if not args.get('leaving'):
+            return []
+
+        role = args.get('role', obj.getRole)
+        enabled, disabled = self._getEnabledAndDisabledContextRoles()
+        if not role in enabled:
+            return []
+
+        result = []
+        if role == pyatspi.ROLE_BLOCK_QUOTE:
+            result.append(messages.LEAVING_BLOCKQUOTE)
+        elif role == pyatspi.ROLE_LIST and self._script.utilities.isDocumentList(obj):
+            result.append(messages.LEAVING_LIST)
+        elif role == pyatspi.ROLE_TABLE and self._script.utilities.isTextDocumentTable(obj):
+            result.append(messages.LEAVING_TABLE)
+        if result:
+            result.extend(self.voice(SYSTEM))
+
+        return result
+
     def _generateAncestors(self, obj, **args):
         """Returns an array of strings (and possibly voice and audio
         specifications) that represent the text of the ancestors for
@@ -1510,7 +1560,14 @@ class SpeechGenerator(generator.Generator):
         previous object with focus.
         """
         result = []
-        priorObj = args.get('priorObj', None)
+
+        leaving = args.get('leaving')
+        if leaving and args.get('priorObj'):
+              priorObj = obj
+              obj = args.get('priorObj')
+        else:
+              priorObj = args.get('priorObj')
+
         if priorObj and priorObj.getRole() == pyatspi.ROLE_TOOL_TIP:
             return []
 
@@ -1533,10 +1590,16 @@ class SpeechGenerator(generator.Generator):
                 return False
             return x and x.getRole() == role and x.name == name
 
+        includeOnly = args.get('includeOnly', [])
+
         skipRoles = args.get('skipRoles', [])
         skipRoles.append(pyatspi.ROLE_TREE_ITEM)
+        enabled, disabled = self._getEnabledAndDisabledContextRoles()
+        skipRoles.extend(disabled)
+
         stopAtRoles = args.get('stopAtRoles', [])
         stopAtRoles.append(pyatspi.ROLE_APPLICATION)
+
         if obj != commonAncestor:
             parent = obj.parent
             while parent and not parent in [commonAncestor, parent.parent]:
@@ -1546,10 +1609,18 @@ class SpeechGenerator(generator.Generator):
                 parentRole = parent.getRole()
                 if parentRole in stopAtRoles:
                     break
-                if parentRole not in skipRoles \
-                   and not self._script.utilities.isLayoutOnly(parent):
-                    result.append(self.generate(parent, formatType='focused'))
+                if parentRole in skipRoles:
+                    pass
+                elif includeOnly and parentRole not in includeOnly:
+                    pass
+                elif not self._script.utilities.isLayoutOnly(parent):
+                    oldRole = self._getAlternativeRole(parent)
+                    self._overrideRole(oldRole, args)
+                    result.append(self.generate(parent, formatType='focused',
+                                                role=oldRole, leaving=leaving))
+                    self._restoreRole(oldRole, args)
                 parent = parent.parent
+
         result.reverse()
         return result
 
@@ -1558,7 +1629,39 @@ class SpeechGenerator(generator.Generator):
         specifications) that represent the text of the ancestors for
         the object being left."""
 
-        return []
+        if _settingsManager.getSetting('onlySpeakDisplayedText'):
+            return []
+
+        if self._script.utilities.inFindToolbar():
+            return []
+
+        priorObj = args.get('priorObj')
+        if not priorObj or obj == priorObj:
+            return []
+
+        if obj.getApplication() != priorObj.getApplication() \
+           or pyatspi.findAncestor(obj, lambda x: x == priorObj):
+            return []
+
+        args['leaving'] = True
+        args['includeOnly'] = [pyatspi.ROLE_BLOCK_QUOTE,
+                               pyatspi.ROLE_LIST,
+                               pyatspi.ROLE_SECTION,
+                               pyatspi.ROLE_TABLE]
+
+        result = []
+        if self._script.utilities.isBlockquote(priorObj):
+            oldRole = self._getAlternativeRole(priorObj)
+            self._overrideRole(oldRole, args)
+            result.extend(self.generate(
+                priorObj, role=oldRole, formatType='focused', leaving=True))
+            self._restoreRole(oldRole, args)
+
+        result.extend(self._generateAncestors(obj, **args))
+        args.pop('leaving')
+        args.pop('includeOnly')
+
+        return result
 
     def _generateNewAncestors(self, obj, **args):
         """Returns an array of strings (and possibly voice and audio
@@ -1573,15 +1676,17 @@ class SpeechGenerator(generator.Generator):
         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:
+        if _settingsManager.getSetting('onlySpeakDisplayedText'):
+            return []
+
+        if self._script.utilities.inFindToolbar():
             return []
 
-        result = []
         priorObj = args.get('priorObj')
+        if priorObj == obj:
+            return []
+
+        result = []
         if obj.getRole() == pyatspi.ROLE_MENU_ITEM \
            and (not priorObj or priorObj.getRole() == pyatspi.ROLE_WINDOW):
             return result
@@ -1592,6 +1697,14 @@ class SpeechGenerator(generator.Generator):
             result = self._generateAncestors(obj, **args)
         return result
 
+    def generateContext(self, obj, **args):
+        if args.get('priorObj') == obj:
+            return []
+
+        result = self._generateOldAncestors(obj, **args)
+        result.append(self._generateNewAncestors(obj, **args))
+        return result
+
     def _generateParentRoleName(self, obj, **args):
         """Returns an array of strings (and possibly voice and audio
         specifications) containing the role name of the parent of obj.
diff --git a/src/orca/structural_navigation.py b/src/orca/structural_navigation.py
index 543391c..3aae742 100644
--- a/src/orca/structural_navigation.py
+++ b/src/orca/structural_navigation.py
@@ -950,6 +950,13 @@ class StructuralNavigation:
     #                                                                       #
     #########################################################################
 
+    def _getListDescription(self, obj):
+        children = [x for x in obj if x.getRole() == pyatspi.ROLE_LIST_ITEM]
+        if not children:
+            return ""
+
+        return messages.listItemCount(len(children))
+
     def _getTableCaption(self, obj):
         """Returns a string which contains the table caption, or
         None if a caption could not be found.
@@ -1323,16 +1330,7 @@ class StructuralNavigation:
           the criteria (e.g. the level of a heading).
         """
 
-        if not obj:
-            return False
-
-        attributes = obj.getAttributes()
-        if attributes:
-            for attribute in attributes:
-                if attribute == "tag:BLOCKQUOTE":
-                    return True
-
-        return False
+        return self._script.utilities.isBlockquote(obj)
 
     def _blockquotePresentation(self, obj, arg=None):
         """Presents the blockquote or indicates that one was not found.
@@ -2264,7 +2262,7 @@ class StructuralNavigation:
         """
 
         if obj:
-            speech.speak(self._script.speechGenerator.generateSpeech(obj))
+            self._script.speakMessage(self._getListDescription(obj))
             [obj, characterOffset] = self._getCaretPosition(obj)
             self._setCaretPosition(obj, characterOffset)
             self._presentLine(obj, characterOffset)
diff --git a/test/keystrokes/firefox/html_access_keys.py b/test/keystrokes/firefox/html_access_keys.py
index 0cd6aec..b3f0a9d 100644
--- a/test/keystrokes/firefox/html_access_keys.py
+++ b/test/keystrokes/firefox/html_access_keys.py
@@ -35,7 +35,7 @@ sequence.append(utils.AssertPresentationAction(
      "     VISIBLE:  'accesskeys', cursor=1",
      "BRAILLE LINE:  'Form! h1'",
      "     VISIBLE:  'Form! h1', cursor=1",
-     "SPEECH OUTPUT: 'accesskeys visited link.'",
+     "SPEECH OUTPUT: 'accesskeys link.'",
      "SPEECH OUTPUT: 'Form! heading level 1'"]))
 
 sequence.append(utils.StartRecordingAction())
diff --git a/test/keystrokes/firefox/html_struct_nav_activate_link.py 
b/test/keystrokes/firefox/html_struct_nav_activate_link.py
index 2a1b507..b0a7bab 100644
--- a/test/keystrokes/firefox/html_struct_nav_activate_link.py
+++ b/test/keystrokes/firefox/html_struct_nav_activate_link.py
@@ -32,11 +32,10 @@ sequence.append(utils.AssertPresentationAction(
      "     VISIBLE:  'Page has 16 unvisited links.', 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: 'Page has 16 unvisited links.' voice=system",
     "SPEECH OUTPUT: 'Here are some of our local test files:'",
+    "SPEECH OUTPUT: 'List with 16 items'",
     "SPEECH OUTPUT: '•'",
     "SPEECH OUTPUT: 'anchors.html'",
     "SPEECH OUTPUT: 'link'",
@@ -84,8 +83,7 @@ sequence.append(utils.AssertPresentationAction(
     "SPEECH OUTPUT: 'link'",
     "SPEECH OUTPUT: '•'",
     "SPEECH OUTPUT: 'textattributes.html'",
-    "SPEECH OUTPUT: 'link'",
-    "SPEECH OUTPUT: 'Here are some of our local test files:'"]))
+    "SPEECH OUTPUT: 'link'"]))
 
 sequence.append(utils.AssertionSummaryAction())
 sequence.start()
diff --git a/test/keystrokes/firefox/html_struct_nav_large_obj.py 
b/test/keystrokes/firefox/html_struct_nav_large_obj.py
index 8b6201b..7d92db4 100644
--- a/test/keystrokes/firefox/html_struct_nav_large_obj.py
+++ b/test/keystrokes/firefox/html_struct_nav_large_obj.py
@@ -163,6 +163,7 @@ sequence.append(utils.AssertPresentationAction(
      "There's no other buyer likely to turn up.'",
      "     VISIBLE:  'I am a tranquilizer. ",
      "I am effec', cursor=1",
+     "SPEECH OUTPUT: 'block quote.'",
      "SPEECH OUTPUT: 'I am a tranquilizer. ",
      "I am effective at home, ",
      "I work well at the office, ",
diff --git a/test/keystrokes/firefox/html_struct_nav_list_item.py 
b/test/keystrokes/firefox/html_struct_nav_list_item.py
index 49f9920..2426d30 100644
--- a/test/keystrokes/firefox/html_struct_nav_list_item.py
+++ b/test/keystrokes/firefox/html_struct_nav_list_item.py
@@ -17,7 +17,7 @@ sequence.append(utils.AssertPresentationAction(
     "1. l to first list",
     ["BRAILLE LINE:  '1. remember what the heck we are doing each day'",
      "     VISIBLE:  '1. remember what the heck we are', cursor=1",
-     "SPEECH OUTPUT: 'List with 4 items.'",
+     "SPEECH OUTPUT: 'List with 4 items' voice=system",
      "SPEECH OUTPUT: '1. remember what the heck we are doing each day.'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -27,7 +27,7 @@ sequence.append(utils.AssertPresentationAction(
     ["KNOWN ISSUE: Gecko is not exposing this as a roman numeral.",
      "BRAILLE LINE:  '6. And use roman numerals,'",
      "     VISIBLE:  '6. And use roman numerals,', cursor=1",
-     "SPEECH OUTPUT: 'List with 6 items.'",
+     "SPEECH OUTPUT: 'List with 6 items' voice=system",
      "SPEECH OUTPUT: '6. And use roman numerals,.'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -36,7 +36,7 @@ sequence.append(utils.AssertPresentationAction(
     "3. l to third list (3) landing on the first item (3.1)",
     ["BRAILLE LINE:  '• listing item'",
      "     VISIBLE:  '• listing item', cursor=1",
-     "SPEECH OUTPUT: 'List with 2 items.'",
+     "SPEECH OUTPUT: 'List with 2 items' voice=system",
      "SPEECH OUTPUT: '• listing item.'"]))
 
 sequence.append(utils.StartRecordingAction())
diff --git a/test/keystrokes/firefox/html_struct_nav_lists.py 
b/test/keystrokes/firefox/html_struct_nav_lists.py
index 9e9f34f..0db482a 100644
--- a/test/keystrokes/firefox/html_struct_nav_lists.py
+++ b/test/keystrokes/firefox/html_struct_nav_lists.py
@@ -9,8 +9,8 @@ sequence = MacroSequence()
 
 #sequence.append(WaitForDocLoad())
 sequence.append(PauseAction(5000))
-sequence.append(PauseAction(3000))
 sequence.append(KeyComboAction("<Control>Home"))
+sequence.append(PauseAction(3000))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("l"))
@@ -18,7 +18,7 @@ sequence.append(utils.AssertPresentationAction(
     "1. l to first list",
     ["BRAILLE LINE:  '1. remember what the heck we are doing each day'",
      "     VISIBLE:  '1. remember what the heck we are', cursor=1",
-     "SPEECH OUTPUT: 'List with 4 items.'",
+     "SPEECH OUTPUT: 'List with 4 items' voice=system",
      "SPEECH OUTPUT: '1. remember what the heck we are doing each day.'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -28,7 +28,7 @@ sequence.append(utils.AssertPresentationAction(
     ["KNOWN ISSUE: Gecko is not exposing this as a roman numeral.",
      "BRAILLE LINE:  '6. And use roman numerals,'",
      "     VISIBLE:  '6. And use roman numerals,', cursor=1",
-     "SPEECH OUTPUT: 'List with 6 items.'",
+     "SPEECH OUTPUT: 'List with 6 items' voice=system",
      "SPEECH OUTPUT: '6. And use roman numerals,.'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -37,7 +37,7 @@ sequence.append(utils.AssertPresentationAction(
     "3. l to third list",
     ["BRAILLE LINE:  '• listing item'",
      "     VISIBLE:  '• listing item', cursor=1",
-     "SPEECH OUTPUT: 'List with 2 items.'",
+     "SPEECH OUTPUT: 'List with 2 items' voice=system",
      "SPEECH OUTPUT: '• listing item.'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -46,7 +46,7 @@ sequence.append(utils.AssertPresentationAction(
     "4. l to third list's first sub list",
     ["BRAILLE LINE:  '◦ first sublevel'",
      "     VISIBLE:  '◦ first sublevel', cursor=1",
-     "SPEECH OUTPUT: 'List with 2 items.'",
+     "SPEECH OUTPUT: 'List with 2 items' voice=system",
      "SPEECH OUTPUT: '◦ first sublevel.'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -55,7 +55,7 @@ sequence.append(utils.AssertPresentationAction(
     "5. l to third list's first sub list's first list",
     ["BRAILLE LINE:  '◾ look for the bullet on'",
      "     VISIBLE:  '◾ look for the bullet on', cursor=1",
-     "SPEECH OUTPUT: 'List with 2 items.'",
+     "SPEECH OUTPUT: 'List with 2 items' voice=system",
      "SPEECH OUTPUT: '◾ look for the bullet on.'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -64,7 +64,7 @@ sequence.append(utils.AssertPresentationAction(
     "6. l to third list's inner-most list",
     ["BRAILLE LINE:  '◾ each sublevel'",
      "     VISIBLE:  '◾ each sublevel', cursor=1",
-     "SPEECH OUTPUT: 'List with 2 items.'",
+     "SPEECH OUTPUT: 'List with 2 items' voice=system",
      "SPEECH OUTPUT: '◾ each sublevel.'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -73,7 +73,7 @@ sequence.append(utils.AssertPresentationAction(
     "7. l to next sub list in the third list",
     ["BRAILLE LINE:  '◦ if your TYPE is circle'",
      "     VISIBLE:  '◦ if your TYPE is circle', cursor=1",
-     "SPEECH OUTPUT: 'List with 2 items.'",
+     "SPEECH OUTPUT: 'List with 2 items' voice=system",
      "SPEECH OUTPUT: '◦ if your TYPE is circle.'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -82,7 +82,7 @@ sequence.append(utils.AssertPresentationAction(
     "8. l to next sub list in the third list",
     ["BRAILLE LINE:  '◦ was a composer who was not square'",
      "     VISIBLE:  '◦ was a composer who was not squ', cursor=1",
-     "SPEECH OUTPUT: 'List with 2 items.'",
+     "SPEECH OUTPUT: 'List with 2 items' voice=system",
      "SPEECH OUTPUT: '◦ was a composer who was not square.'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -91,7 +91,7 @@ sequence.append(utils.AssertPresentationAction(
     "9. l to the fourth list",
     ["BRAILLE LINE:  '◦ feeling listless'",
      "     VISIBLE:  '◦ feeling listless', cursor=1",
-     "SPEECH OUTPUT: 'List with 3 items.'",
+     "SPEECH OUTPUT: 'List with 3 items' voice=system",
      "SPEECH OUTPUT: '◦ feeling listless.'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -103,7 +103,7 @@ sequence.append(utils.AssertPresentationAction(
      "BRAILLE LINE:  '1. remember what the heck we are doing each day'",
      "     VISIBLE:  '1. remember what the heck we are', cursor=1",
      "SPEECH OUTPUT: 'Wrapping to top.' voice=system",
-     "SPEECH OUTPUT: 'List with 4 items.'",
+     "SPEECH OUTPUT: 'List with 4 items' voice=system",
      "SPEECH OUTPUT: '1. remember what the heck we are doing each day.'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -115,7 +115,7 @@ sequence.append(utils.AssertPresentationAction(
      "BRAILLE LINE:  '◦ feeling listless'",
      "     VISIBLE:  '◦ feeling listless', cursor=1",
      "SPEECH OUTPUT: 'Wrapping to bottom.' voice=system",
-     "SPEECH OUTPUT: 'List with 3 items.'",
+     "SPEECH OUTPUT: 'List with 3 items' voice=system",
      "SPEECH OUTPUT: '◦ feeling listless.'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -124,7 +124,7 @@ sequence.append(utils.AssertPresentationAction(
     "12. shift + l",
     ["BRAILLE LINE:  '◦ was a composer who was not square'",
      "     VISIBLE:  '◦ was a composer who was not squ', cursor=1",
-     "SPEECH OUTPUT: 'List with 2 items.'",
+     "SPEECH OUTPUT: 'List with 2 items' voice=system",
      "SPEECH OUTPUT: '◦ was a composer who was not square.'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -133,7 +133,7 @@ sequence.append(utils.AssertPresentationAction(
     "13. shift + l",
     ["BRAILLE LINE:  '◦ if your TYPE is circle'",
      "     VISIBLE:  '◦ if your TYPE is circle', cursor=1",
-     "SPEECH OUTPUT: 'List with 2 items.'",
+     "SPEECH OUTPUT: 'List with 2 items' voice=system",
      "SPEECH OUTPUT: '◦ if your TYPE is circle.'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -142,7 +142,7 @@ sequence.append(utils.AssertPresentationAction(
     "14. shift + l",
     ["BRAILLE LINE:  '◾ each sublevel'",
      "     VISIBLE:  '◾ each sublevel', cursor=1",
-     "SPEECH OUTPUT: 'List with 2 items.'",
+     "SPEECH OUTPUT: 'List with 2 items' voice=system",
      "SPEECH OUTPUT: '◾ each sublevel.'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -151,7 +151,7 @@ sequence.append(utils.AssertPresentationAction(
     "15. shift + l",
     ["BRAILLE LINE:  '◾ look for the bullet on'",
      "     VISIBLE:  '◾ look for the bullet on', cursor=1",
-     "SPEECH OUTPUT: 'List with 2 items.'",
+     "SPEECH OUTPUT: 'List with 2 items' voice=system",
      "SPEECH OUTPUT: '◾ look for the bullet on.'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -160,7 +160,7 @@ sequence.append(utils.AssertPresentationAction(
     "16. shift + l",
     ["BRAILLE LINE:  '◦ first sublevel'",
      "     VISIBLE:  '◦ first sublevel', cursor=1",
-     "SPEECH OUTPUT: 'List with 2 items.'",
+     "SPEECH OUTPUT: 'List with 2 items' voice=system",
      "SPEECH OUTPUT: '◦ first sublevel.'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -169,7 +169,7 @@ sequence.append(utils.AssertPresentationAction(
     "17. shift + l",
     ["BRAILLE LINE:  '• listing item'",
      "     VISIBLE:  '• listing item', cursor=1",
-     "SPEECH OUTPUT: 'List with 2 items.'",
+     "SPEECH OUTPUT: 'List with 2 items' voice=system",
      "SPEECH OUTPUT: '• listing item.'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -179,7 +179,7 @@ sequence.append(utils.AssertPresentationAction(
     ["KNOWN ISSUE: Gecko is not exposing this as a roman numeral.",
      "BRAILLE LINE:  '6. And use roman numerals,'",
      "     VISIBLE:  '6. And use roman numerals,', cursor=1",
-     "SPEECH OUTPUT: 'List with 6 items.'",
+     "SPEECH OUTPUT: 'List with 6 items' voice=system",
      "SPEECH OUTPUT: '6. And use roman numerals,.'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -188,7 +188,7 @@ sequence.append(utils.AssertPresentationAction(
     "19. shift + l",
     ["BRAILLE LINE:  '1. remember what the heck we are doing each day'",
      "     VISIBLE:  '1. remember what the heck we are', cursor=1",
-     "SPEECH OUTPUT: 'List with 4 items.'",
+     "SPEECH OUTPUT: 'List with 4 items' voice=system",
      "SPEECH OUTPUT: '1. remember what the heck we are doing each day.'"]))
 
 sequence.append(utils.AssertionSummaryAction())
diff --git a/test/keystrokes/firefox/line_nav_broken_list.py b/test/keystrokes/firefox/line_nav_broken_list.py
index 80b4da7..48cdde0 100644
--- a/test/keystrokes/firefox/line_nav_broken_list.py
+++ b/test/keystrokes/firefox/line_nav_broken_list.py
@@ -21,6 +21,7 @@ sequence.append(utils.AssertPresentationAction(
     "1. Line Down",
     ["BRAILLE LINE:  '1. item'",
      "     VISIBLE:  '1. item', cursor=1",
+     "SPEECH OUTPUT: 'List with 3 items'",
      "SPEECH OUTPUT: '1. item.'"]))
 
 sequence.append(utils.StartRecordingAction())
diff --git a/test/keystrokes/firefox/line_nav_bug_552887a.py b/test/keystrokes/firefox/line_nav_bug_552887a.py
index 1dc0cf6..c19af0a 100644
--- a/test/keystrokes/firefox/line_nav_bug_552887a.py
+++ b/test/keystrokes/firefox/line_nav_bug_552887a.py
@@ -19,7 +19,8 @@ sequence.append(KeyComboAction("<Control>Home"))
 sequence.append(utils.AssertPresentationAction(
     "1. Top of file",
     ["BRAILLE LINE:  ''",
-     "     VISIBLE:  '', cursor=1"]))
+     "     VISIBLE:  '', cursor=1",
+     "SPEECH OUTPUT: 'blank'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
diff --git a/test/keystrokes/firefox/line_nav_bug_570757.py b/test/keystrokes/firefox/line_nav_bug_570757.py
index 68dd683..24c3032 100644
--- a/test/keystrokes/firefox/line_nav_bug_570757.py
+++ b/test/keystrokes/firefox/line_nav_bug_570757.py
@@ -24,6 +24,7 @@ sequence.append(utils.AssertPresentationAction(
     "2. Line Down",
     ["BRAILLE LINE:  'Solution'",
      "     VISIBLE:  'Solution', cursor=1",
+     "SPEECH OUTPUT: 'Solution panel'",
      "SPEECH OUTPUT: 'Solution'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -32,7 +33,7 @@ sequence.append(utils.AssertPresentationAction(
     "3. Line Down",
     ["BRAILLE LINE:  'Solution  Here is a step-by-step tutorial:'",
      "     VISIBLE:  'Solution  Here is a step-by-step', cursor=11",
-     "SPEECH OUTPUT: 'Here is a step-by-step tutorial: panel.'"]))
+     "SPEECH OUTPUT: 'Here is a step-by-step tutorial:.'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
@@ -40,6 +41,7 @@ sequence.append(utils.AssertPresentationAction(
     "4. Line Down",
     ["BRAILLE LINE:  '• Do this thing'",
      "     VISIBLE:  '• Do this thing', cursor=1",
+     "SPEECH OUTPUT: 'List with 2 items'",
      "SPEECH OUTPUT: '• Do this thing.'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -64,7 +66,8 @@ sequence.append(utils.AssertPresentationAction(
     "7. Line Up",
     ["BRAILLE LINE:  'Solution  Here is a step-by-step tutorial:'",
      "     VISIBLE:  'Solution  Here is a step-by-step', cursor=11",
-     "SPEECH OUTPUT: 'Here is a step-by-step tutorial: panel.'"]))
+     "SPEECH OUTPUT: 'leaving list.'",
+     "SPEECH OUTPUT: 'Here is a step-by-step tutorial:.'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
diff --git a/test/keystrokes/firefox/line_nav_bug_570757.settings 
b/test/keystrokes/firefox/line_nav_bug_570757.settings
new file mode 100644
index 0000000..7efb046
--- /dev/null
+++ b/test/keystrokes/firefox/line_nav_bug_570757.settings
@@ -0,0 +1,165 @@
+{
+    "general": {
+        "enabledSpokenTextAttributes": "size:; family-name:; weight:400; indent:0; underline:none; 
strikethrough:false; justification:left; style:normal; paragraph-style:; text-spelling:none; fg-color:; 
bg-color:;",
+        "orcaModifierKeys": [
+            "Insert",
+            "KP_Insert"
+        ],
+        "skipBlankCells": false,
+        "onlySpeakDisplayedText": false,
+        "enableMnemonicSpeaking": false,
+        "chatAnnounceBuddyTyping": false,
+        "messagesAreDetailed": true,
+        "speakProgressBarUpdates": true,
+        "speakCellCoordinates": true,
+        "enableAlphabeticKeys": true,
+        "enableBraille": false,
+        "brailleAlignmentStyle": 0,
+        "playSoundForPositionInSet": false,
+        "sayAllStyle": 1,
+        "enableEchoBySentence": false,
+        "chatSpeakRoomName": false,
+        "soundVolume": 0.5,
+        "activeProfile": [
+            "Default",
+            "default"
+        ],
+        "brailleVerbosityLevel": 1,
+        "sayAllContextTable": true,
+        "enableTutorialMessages": false,
+        "wrappedStructuralNavigation": true,
+        "capitalizationStyle": "none",
+        "findResultsMinimumLength": 4,
+        "enableContractedBraille": false,
+        "presentDateFormat": "%x",
+        "enableSpeechIndentation": false,
+        "brailleContractionTable": "",
+        "structNavTriggersFocusMode": false,
+        "enablePauseBreaks": true,
+        "speakNumbersAsDigits": false,
+        "spellcheckSpellError": true,
+        "useColorNames": true,
+        "speakContextTable": true,
+        "readFullRowInGUITable": true,
+        "enabledBrailledTextAttributes": "size:; family-name:; weight:400; indent:0; underline:none; 
strikethrough:false; justification:left; style:normal; text-spelling:none;",
+        "enableSpace": true,
+        "brailleSelectorIndicator": 192,
+        "profile": [
+            "Default",
+            "default"
+        ],
+        "verbalizePunctuationStyle": 1,
+        "enableBrailleContext": true,
+        "enableNavigationKeys": false,
+        "structNavInSayAll": false,
+        "enableSound": true,
+        "speakCellSpan": true,
+        "speechVerbosityLevel": 1,
+        "brailleRolenameStyle": 1,
+        "mouseDwellDelay": null,
+        "enableSpeech": true,
+        "caretNavTriggersFocusMode": false,
+        "enableDiacriticalKeys": false,
+        "findResultsVerbosity": 2,
+        "sayAllContextBlockquote": true,
+        "speakBlankLines": true,
+        "speakSpreadsheetCoordinates": true,
+        "flashIsPersistent": false,
+        "enableNumericKeys": true,
+        "enableFlashMessages": true,
+        "progressBarVerbosity": 1,
+        "brailleLinkIndicator": 192,
+        "presentTimeFormat": "%X",
+        "enablePunctuationKeys": true,
+        "enableKeyEcho": false,
+        "playSoundForState": false,
+        "beepProgressBarUpdates": false,
+        "enableFunctionKeys": true,
+        "speakMisspelledIndicator": true,
+        "textAttributesBrailleIndicator": 0,
+        "voices": {
+            "default": {
+                "established": false
+            },
+            "system": {
+                "established": false
+            },
+            "uppercase": {
+                "average-pitch": 7.0
+            },
+            "hyperlink": {
+                "established": false
+            }
+        },
+        "enableBrailleMonitor": true,
+        "layoutMode": true,
+        "brailleFlashTime": 5000,
+        "largeObjectTextLength": 75,
+        "speakContextList": true,
+        "ignoreStatusBarProgressBars": true,
+        "keyboardLayout": 1,
+        "brailleProgressBarUpdates": false,
+        "readFullRowInSpreadSheet": false,
+        "enableActionKeys": true,
+        "enablePositionSpeaking": false,
+        "structuralNavigationEnabled": true,
+        "playSoundForRole": false,
+        "disableBrailleEOL": false,
+        "presentToolTips": false,
+        "enableMouseReview": false,
+        "speechServerFactory": "speechdispatcherfactory",
+        "chatMessageVerbosity": 0,
+        "enableEchoByWord": false,
+        "spellcheckSpellSuggestion": true,
+        "enableModifierKeys": true,
+        "speakMultiCaseStringsAsWords": false,
+        "flashIsDetailed": true,
+        "speakCellHeaders": true,
+        "rewindAndFastForwardInSayAll": false,
+        "sayAllContextList": true,
+        "speakContextBlockquote": true,
+        "enableEchoByCharacter": false,
+        "playSoundForValue": false,
+        "progressBarUpdateInterval": 10,
+        "spellcheckPresentContext": true,
+        "speechServerInfo": null,
+        "chatRoomHistories": false,
+        "readFullRowInDocumentTable": true,
+        "startingProfile": [
+            "Default",
+            "default"
+        ]
+    },
+    "keybindings": {},
+    "profiles": {
+        "default": {
+            "profile": [
+                "Default",
+                "default"
+            ],
+            "brailleContractionTable": "/usr/share/liblouis/tables/en-us-compbrl.ctb",
+            "voices": {
+                "default": {
+                    "established": false
+                },
+                "system": {
+                    "established": false
+                },
+                "uppercase": {
+                    "average-pitch": 7.0
+                },
+                "hyperlink": {
+                    "established": false
+                }
+            },
+            "pronunciations": {},
+            "speechServerInfo": [
+                "Default Synthesizer",
+                "default"
+            ],
+            "keybindings": {},
+            "speechServerFactory": "orca.speechdispatcherfactory"
+        }
+    },
+    "pronunciations": {}
+}
\ No newline at end of file
diff --git a/test/keystrokes/firefox/line_nav_bug_570757_no_context.params 
b/test/keystrokes/firefox/line_nav_bug_570757_no_context.params
new file mode 100644
index 0000000..ddc59d1
--- /dev/null
+++ b/test/keystrokes/firefox/line_nav_bug_570757_no_context.params
@@ -0,0 +1 @@
+PARAMS=$TEST_DIR/../../html/bug-570757.html
diff --git a/test/keystrokes/firefox/line_nav_bug_570757_no_context.py 
b/test/keystrokes/firefox/line_nav_bug_570757_no_context.py
new file mode 100644
index 0000000..c8a83d8
--- /dev/null
+++ b/test/keystrokes/firefox/line_nav_bug_570757_no_context.py
@@ -0,0 +1,87 @@
+#!/usr/bin/python
+
+"""Test of line navigation output of Firefox."""
+
+from macaroon.playback import *
+import utils
+
+sequence = MacroSequence()
+
+#sequence.append(WaitForDocLoad())
+sequence.append(PauseAction(5000))
+
+sequence.append(utils.StartRecordingAction())
+sequence.append(KeyComboAction("<Control>Home"))
+sequence.append(utils.AssertPresentationAction(
+    "1. Top of file",
+    ["BRAILLE LINE:  'This is a test.'",
+     "     VISIBLE:  'This is a test.', cursor=1",
+     "SPEECH OUTPUT: 'This is a test.'"]))
+
+sequence.append(utils.StartRecordingAction())
+sequence.append(KeyComboAction("Down"))
+sequence.append(utils.AssertPresentationAction(
+    "2. Line Down",
+    ["BRAILLE LINE:  'Solution'",
+     "     VISIBLE:  'Solution', cursor=1",
+     "SPEECH OUTPUT: 'Solution panel'",
+     "SPEECH OUTPUT: 'Solution'"]))
+
+sequence.append(utils.StartRecordingAction())
+sequence.append(KeyComboAction("Down"))
+sequence.append(utils.AssertPresentationAction(
+    "3. Line Down",
+    ["BRAILLE LINE:  'Solution  Here is a step-by-step tutorial:'",
+     "     VISIBLE:  'Solution  Here is a step-by-step', cursor=11",
+     "SPEECH OUTPUT: 'Here is a step-by-step tutorial:.'"]))
+
+sequence.append(utils.StartRecordingAction())
+sequence.append(KeyComboAction("Down"))
+sequence.append(utils.AssertPresentationAction(
+    "4. Line Down",
+    ["BRAILLE LINE:  '• Do this thing'",
+     "     VISIBLE:  '• Do this thing', cursor=1",
+     "SPEECH OUTPUT: '• Do this thing.'"]))
+
+sequence.append(utils.StartRecordingAction())
+sequence.append(KeyComboAction("Down"))
+sequence.append(utils.AssertPresentationAction(
+    "5. Line Down",
+    ["BRAILLE LINE:  '• Do this other thing'",
+     "     VISIBLE:  '• Do this other thing', cursor=1",
+     "SPEECH OUTPUT: '• Do this other thing.'"]))
+
+sequence.append(utils.StartRecordingAction())
+sequence.append(KeyComboAction("Up"))
+sequence.append(utils.AssertPresentationAction(
+    "6. Line Up",
+    ["BRAILLE LINE:  '• Do this thing'",
+     "     VISIBLE:  '• Do this thing', cursor=1",
+     "SPEECH OUTPUT: '• Do this thing.'"]))
+
+sequence.append(utils.StartRecordingAction())
+sequence.append(KeyComboAction("Up"))
+sequence.append(utils.AssertPresentationAction(
+    "7. Line Up",
+    ["BRAILLE LINE:  'Solution  Here is a step-by-step tutorial:'",
+     "     VISIBLE:  'Solution  Here is a step-by-step', cursor=11",
+     "SPEECH OUTPUT: 'Here is a step-by-step tutorial:.'"]))
+
+sequence.append(utils.StartRecordingAction())
+sequence.append(KeyComboAction("Up"))
+sequence.append(utils.AssertPresentationAction(
+    "8. Line Up",
+    ["BRAILLE LINE:  'Solution'",
+     "     VISIBLE:  'Solution', cursor=1",
+     "SPEECH OUTPUT: 'Solution'"]))
+
+sequence.append(utils.StartRecordingAction())
+sequence.append(KeyComboAction("Up"))
+sequence.append(utils.AssertPresentationAction(
+    "9. Line Up",
+    ["BRAILLE LINE:  'This is a test.'",
+     "     VISIBLE:  'This is a test.', cursor=1",
+     "SPEECH OUTPUT: 'This is a test.'"]))
+
+sequence.append(utils.AssertionSummaryAction())
+sequence.start()
diff --git a/test/keystrokes/firefox/line_nav_bug_570757_no_context.settings 
b/test/keystrokes/firefox/line_nav_bug_570757_no_context.settings
new file mode 100644
index 0000000..39c1cea
--- /dev/null
+++ b/test/keystrokes/firefox/line_nav_bug_570757_no_context.settings
@@ -0,0 +1,165 @@
+{
+    "general": {
+        "enabledSpokenTextAttributes": "size:; family-name:; weight:400; indent:0; underline:none; 
strikethrough:false; justification:left; style:normal; paragraph-style:; text-spelling:none; fg-color:; 
bg-color:;",
+        "orcaModifierKeys": [
+            "Insert",
+            "KP_Insert"
+        ],
+        "skipBlankCells": false,
+        "onlySpeakDisplayedText": false,
+        "enableMnemonicSpeaking": false,
+        "chatAnnounceBuddyTyping": false,
+        "messagesAreDetailed": true,
+        "speakProgressBarUpdates": true,
+        "speakCellCoordinates": true,
+        "enableAlphabeticKeys": true,
+        "enableBraille": false,
+        "brailleAlignmentStyle": 0,
+        "playSoundForPositionInSet": false,
+        "sayAllStyle": 1,
+        "enableEchoBySentence": false,
+        "chatSpeakRoomName": false,
+        "soundVolume": 0.5,
+        "activeProfile": [
+            "Default",
+            "default"
+        ],
+        "brailleVerbosityLevel": 1,
+        "sayAllContextTable": false,
+        "enableTutorialMessages": false,
+        "wrappedStructuralNavigation": true,
+        "capitalizationStyle": "none",
+        "findResultsMinimumLength": 4,
+        "enableContractedBraille": false,
+        "presentDateFormat": "%x",
+        "enableSpeechIndentation": false,
+        "brailleContractionTable": "",
+        "structNavTriggersFocusMode": false,
+        "enablePauseBreaks": true,
+        "speakNumbersAsDigits": false,
+        "spellcheckSpellError": true,
+        "useColorNames": true,
+        "speakContextTable": false,
+        "readFullRowInGUITable": true,
+        "enabledBrailledTextAttributes": "size:; family-name:; weight:400; indent:0; underline:none; 
strikethrough:false; justification:left; style:normal; text-spelling:none;",
+        "enableSpace": true,
+        "brailleSelectorIndicator": 192,
+        "profile": [
+            "Default",
+            "default"
+        ],
+        "verbalizePunctuationStyle": 1,
+        "enableBrailleContext": true,
+        "enableNavigationKeys": false,
+        "structNavInSayAll": false,
+        "enableSound": true,
+        "speakCellSpan": true,
+        "speechVerbosityLevel": 1,
+        "brailleRolenameStyle": 1,
+        "mouseDwellDelay": null,
+        "enableSpeech": true,
+        "caretNavTriggersFocusMode": false,
+        "enableDiacriticalKeys": false,
+        "findResultsVerbosity": 2,
+        "sayAllContextBlockquote": false,
+        "speakBlankLines": true,
+        "speakSpreadsheetCoordinates": true,
+        "flashIsPersistent": false,
+        "enableNumericKeys": true,
+        "enableFlashMessages": true,
+        "progressBarVerbosity": 1,
+        "brailleLinkIndicator": 192,
+        "presentTimeFormat": "%X",
+        "enablePunctuationKeys": true,
+        "enableKeyEcho": false,
+        "playSoundForState": false,
+        "beepProgressBarUpdates": false,
+        "enableFunctionKeys": true,
+        "speakMisspelledIndicator": true,
+        "textAttributesBrailleIndicator": 0,
+        "voices": {
+            "default": {
+                "established": false
+            },
+            "system": {
+                "established": false
+            },
+            "uppercase": {
+                "average-pitch": 7.0
+            },
+            "hyperlink": {
+                "established": false
+            }
+        },
+        "enableBrailleMonitor": true,
+        "layoutMode": true,
+        "brailleFlashTime": 5000,
+        "largeObjectTextLength": 75,
+        "speakContextList": false,
+        "ignoreStatusBarProgressBars": true,
+        "keyboardLayout": 1,
+        "brailleProgressBarUpdates": false,
+        "readFullRowInSpreadSheet": false,
+        "enableActionKeys": true,
+        "enablePositionSpeaking": false,
+        "structuralNavigationEnabled": true,
+        "playSoundForRole": false,
+        "disableBrailleEOL": false,
+        "presentToolTips": false,
+        "enableMouseReview": false,
+        "speechServerFactory": "speechdispatcherfactory",
+        "chatMessageVerbosity": 0,
+        "enableEchoByWord": false,
+        "spellcheckSpellSuggestion": true,
+        "enableModifierKeys": true,
+        "speakMultiCaseStringsAsWords": false,
+        "flashIsDetailed": true,
+        "speakCellHeaders": true,
+        "rewindAndFastForwardInSayAll": false,
+        "sayAllContextList": false,
+        "speakContextBlockquote": false,
+        "enableEchoByCharacter": false,
+        "playSoundForValue": false,
+        "progressBarUpdateInterval": 10,
+        "spellcheckPresentContext": true,
+        "speechServerInfo": null,
+        "chatRoomHistories": false,
+        "readFullRowInDocumentTable": true,
+        "startingProfile": [
+            "Default",
+            "default"
+        ]
+    },
+    "keybindings": {},
+    "profiles": {
+        "default": {
+            "profile": [
+                "Default",
+                "default"
+            ],
+            "brailleContractionTable": "/usr/share/liblouis/tables/en-us-compbrl.ctb",
+            "voices": {
+                "default": {
+                    "established": false
+                },
+                "system": {
+                    "established": false
+                },
+                "uppercase": {
+                    "average-pitch": 7.0
+                },
+                "hyperlink": {
+                    "established": false
+                }
+            },
+            "pronunciations": {},
+            "speechServerInfo": [
+                "Default Synthesizer",
+                "default"
+            ],
+            "keybindings": {},
+            "speechServerFactory": "orca.speechdispatcherfactory"
+        }
+    },
+    "pronunciations": {}
+}
\ No newline at end of file
diff --git a/test/keystrokes/firefox/line_nav_bug_577239.py b/test/keystrokes/firefox/line_nav_bug_577239.py
index 6848613..4f5941d 100644
--- a/test/keystrokes/firefox/line_nav_bug_577239.py
+++ b/test/keystrokes/firefox/line_nav_bug_577239.py
@@ -32,6 +32,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: 'List with 2 items'",
      "SPEECH OUTPUT: '1. This is a short list item.'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -64,6 +65,7 @@ sequence.append(utils.AssertPresentationAction(
     "7. Line Down",
     ["BRAILLE LINE:  'This is an example of an unordered list:'",
      "     VISIBLE:  'This is an example of an unorder', cursor=1",
+     "SPEECH OUTPUT: 'leaving list.'",
      "SPEECH OUTPUT: 'This is an example of an unordered list:'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -71,7 +73,8 @@ sequence.append(KeyComboAction("Down"))
 sequence.append(utils.AssertPresentationAction(
     "8. Line Down",
     ["BRAILLE LINE:  '• This is a short list item.'",
-     "     VISIBLE:  '• This is a short list item.', cursor=30",
+     "     VISIBLE:  '• This is a short list item.', cursor=1",
+     "SPEECH OUTPUT: 'List with 2 items'",
      "SPEECH OUTPUT: '• This is a short list item.'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -112,6 +115,7 @@ sequence.append(utils.AssertPresentationAction(
     "13. Line Up",
     ["BRAILLE LINE:  'This is an example of an unordered list:'",
      "     VISIBLE:  'This is an example of an unorder', cursor=1",
+     "SPEECH OUTPUT: 'leaving list.'",
      "SPEECH OUTPUT: 'This is an example of an unordered list:'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -120,6 +124,7 @@ sequence.append(utils.AssertPresentationAction(
     "14. Line Up",
     ["BRAILLE LINE:  'should probably be put out of its misery.'",
      "     VISIBLE:  'should probably be put out of it', cursor=1",
+     "SPEECH OUTPUT: 'List with 2 items'",
      "SPEECH OUTPUT: 'should probably be put out of its misery.'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -152,6 +157,7 @@ sequence.append(utils.AssertPresentationAction(
     "18. Line Up",
     ["BRAILLE LINE:  'this is an ordered list:'",
      "     VISIBLE:  'this is an ordered list:', cursor=1",
+     "SPEECH OUTPUT: 'leaving list.'",
      "SPEECH OUTPUT: 'this is an ordered list:'"]))
 
 sequence.append(utils.AssertionSummaryAction())
diff --git a/test/keystrokes/firefox/line_nav_bug_577239.settings 
b/test/keystrokes/firefox/line_nav_bug_577239.settings
new file mode 100644
index 0000000..7efb046
--- /dev/null
+++ b/test/keystrokes/firefox/line_nav_bug_577239.settings
@@ -0,0 +1,165 @@
+{
+    "general": {
+        "enabledSpokenTextAttributes": "size:; family-name:; weight:400; indent:0; underline:none; 
strikethrough:false; justification:left; style:normal; paragraph-style:; text-spelling:none; fg-color:; 
bg-color:;",
+        "orcaModifierKeys": [
+            "Insert",
+            "KP_Insert"
+        ],
+        "skipBlankCells": false,
+        "onlySpeakDisplayedText": false,
+        "enableMnemonicSpeaking": false,
+        "chatAnnounceBuddyTyping": false,
+        "messagesAreDetailed": true,
+        "speakProgressBarUpdates": true,
+        "speakCellCoordinates": true,
+        "enableAlphabeticKeys": true,
+        "enableBraille": false,
+        "brailleAlignmentStyle": 0,
+        "playSoundForPositionInSet": false,
+        "sayAllStyle": 1,
+        "enableEchoBySentence": false,
+        "chatSpeakRoomName": false,
+        "soundVolume": 0.5,
+        "activeProfile": [
+            "Default",
+            "default"
+        ],
+        "brailleVerbosityLevel": 1,
+        "sayAllContextTable": true,
+        "enableTutorialMessages": false,
+        "wrappedStructuralNavigation": true,
+        "capitalizationStyle": "none",
+        "findResultsMinimumLength": 4,
+        "enableContractedBraille": false,
+        "presentDateFormat": "%x",
+        "enableSpeechIndentation": false,
+        "brailleContractionTable": "",
+        "structNavTriggersFocusMode": false,
+        "enablePauseBreaks": true,
+        "speakNumbersAsDigits": false,
+        "spellcheckSpellError": true,
+        "useColorNames": true,
+        "speakContextTable": true,
+        "readFullRowInGUITable": true,
+        "enabledBrailledTextAttributes": "size:; family-name:; weight:400; indent:0; underline:none; 
strikethrough:false; justification:left; style:normal; text-spelling:none;",
+        "enableSpace": true,
+        "brailleSelectorIndicator": 192,
+        "profile": [
+            "Default",
+            "default"
+        ],
+        "verbalizePunctuationStyle": 1,
+        "enableBrailleContext": true,
+        "enableNavigationKeys": false,
+        "structNavInSayAll": false,
+        "enableSound": true,
+        "speakCellSpan": true,
+        "speechVerbosityLevel": 1,
+        "brailleRolenameStyle": 1,
+        "mouseDwellDelay": null,
+        "enableSpeech": true,
+        "caretNavTriggersFocusMode": false,
+        "enableDiacriticalKeys": false,
+        "findResultsVerbosity": 2,
+        "sayAllContextBlockquote": true,
+        "speakBlankLines": true,
+        "speakSpreadsheetCoordinates": true,
+        "flashIsPersistent": false,
+        "enableNumericKeys": true,
+        "enableFlashMessages": true,
+        "progressBarVerbosity": 1,
+        "brailleLinkIndicator": 192,
+        "presentTimeFormat": "%X",
+        "enablePunctuationKeys": true,
+        "enableKeyEcho": false,
+        "playSoundForState": false,
+        "beepProgressBarUpdates": false,
+        "enableFunctionKeys": true,
+        "speakMisspelledIndicator": true,
+        "textAttributesBrailleIndicator": 0,
+        "voices": {
+            "default": {
+                "established": false
+            },
+            "system": {
+                "established": false
+            },
+            "uppercase": {
+                "average-pitch": 7.0
+            },
+            "hyperlink": {
+                "established": false
+            }
+        },
+        "enableBrailleMonitor": true,
+        "layoutMode": true,
+        "brailleFlashTime": 5000,
+        "largeObjectTextLength": 75,
+        "speakContextList": true,
+        "ignoreStatusBarProgressBars": true,
+        "keyboardLayout": 1,
+        "brailleProgressBarUpdates": false,
+        "readFullRowInSpreadSheet": false,
+        "enableActionKeys": true,
+        "enablePositionSpeaking": false,
+        "structuralNavigationEnabled": true,
+        "playSoundForRole": false,
+        "disableBrailleEOL": false,
+        "presentToolTips": false,
+        "enableMouseReview": false,
+        "speechServerFactory": "speechdispatcherfactory",
+        "chatMessageVerbosity": 0,
+        "enableEchoByWord": false,
+        "spellcheckSpellSuggestion": true,
+        "enableModifierKeys": true,
+        "speakMultiCaseStringsAsWords": false,
+        "flashIsDetailed": true,
+        "speakCellHeaders": true,
+        "rewindAndFastForwardInSayAll": false,
+        "sayAllContextList": true,
+        "speakContextBlockquote": true,
+        "enableEchoByCharacter": false,
+        "playSoundForValue": false,
+        "progressBarUpdateInterval": 10,
+        "spellcheckPresentContext": true,
+        "speechServerInfo": null,
+        "chatRoomHistories": false,
+        "readFullRowInDocumentTable": true,
+        "startingProfile": [
+            "Default",
+            "default"
+        ]
+    },
+    "keybindings": {},
+    "profiles": {
+        "default": {
+            "profile": [
+                "Default",
+                "default"
+            ],
+            "brailleContractionTable": "/usr/share/liblouis/tables/en-us-compbrl.ctb",
+            "voices": {
+                "default": {
+                    "established": false
+                },
+                "system": {
+                    "established": false
+                },
+                "uppercase": {
+                    "average-pitch": 7.0
+                },
+                "hyperlink": {
+                    "established": false
+                }
+            },
+            "pronunciations": {},
+            "speechServerInfo": [
+                "Default Synthesizer",
+                "default"
+            ],
+            "keybindings": {},
+            "speechServerFactory": "orca.speechdispatcherfactory"
+        }
+    },
+    "pronunciations": {}
+}
\ No newline at end of file
diff --git a/test/keystrokes/firefox/line_nav_bug_577239_no_context.params 
b/test/keystrokes/firefox/line_nav_bug_577239_no_context.params
new file mode 100644
index 0000000..c8ba5dc
--- /dev/null
+++ b/test/keystrokes/firefox/line_nav_bug_577239_no_context.params
@@ -0,0 +1 @@
+PARAMS=$TEST_DIR/../../html/bug-577239.html
diff --git a/test/keystrokes/firefox/line_nav_bug_577239_no_context.py 
b/test/keystrokes/firefox/line_nav_bug_577239_no_context.py
new file mode 100644
index 0000000..e28f2e8
--- /dev/null
+++ b/test/keystrokes/firefox/line_nav_bug_577239_no_context.py
@@ -0,0 +1,158 @@
+#!/usr/bin/python
+
+"""Test of line navigation output of Firefox."""
+
+from macaroon.playback import *
+import utils
+
+sequence = MacroSequence()
+
+#sequence.append(WaitForDocLoad())
+sequence.append(PauseAction(5000))
+
+sequence.append(utils.StartRecordingAction())
+sequence.append(KeyComboAction("<Control>Home"))
+sequence.append(utils.AssertPresentationAction(
+    "1. Top of file",
+    ["BRAILLE LINE:  'this is a page to test how well Orca works with list items.'",
+     "     VISIBLE:  'this is a page to test how well ', cursor=1",
+     "SPEECH OUTPUT: 'this is a page to test how well Orca works with list items.'"]))
+
+sequence.append(utils.StartRecordingAction())
+sequence.append(KeyComboAction("Down"))
+sequence.append(utils.AssertPresentationAction(
+    "2. Line Down",
+    ["BRAILLE LINE:  'this is an ordered list:'",
+     "     VISIBLE:  'this is an ordered list:', cursor=1",
+     "SPEECH OUTPUT: 'this is an ordered list:'"]))
+
+sequence.append(utils.StartRecordingAction())
+sequence.append(KeyComboAction("Down"))
+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.'"]))
+
+sequence.append(utils.StartRecordingAction())
+sequence.append(KeyComboAction("Down"))
+sequence.append(utils.AssertPresentationAction(
+    "4. Line Down",
+    ["BRAILLE LINE:  '2. This is a list item that spans multiple lines. If Orca can successfully read to the 
end of this list item, it will have read'",
+     "     VISIBLE:  '2. This is a list item that span', cursor=1",
+     "SPEECH OUTPUT: '2. This is a list item that spans multiple lines. If Orca can successfully read to the 
end of this list item, it will have read.'"]))
+
+sequence.append(utils.StartRecordingAction())
+sequence.append(KeyComboAction("Down"))
+sequence.append(utils.AssertPresentationAction(
+    "5. Line Down",
+    ["BRAILLE LINE:  'several lines of text within this single item. And, yes, I realize that this is not 
deathless prose. In fact, it is prose that'",
+     "     VISIBLE:  'several lines of text within thi', cursor=1",
+     "SPEECH OUTPUT: 'several lines of text within this single item. And, yes, I realize that this is not 
deathless prose. In fact, it is prose that.'"]))
+
+sequence.append(utils.StartRecordingAction())
+sequence.append(KeyComboAction("Down"))
+sequence.append(utils.AssertPresentationAction(
+    "6. Line Down",
+    ["BRAILLE LINE:  'should probably be put out of its misery.'",
+     "     VISIBLE:  'should probably be put out of it', cursor=1",
+     "SPEECH OUTPUT: 'should probably be put out of its misery.'"]))
+
+sequence.append(utils.StartRecordingAction())
+sequence.append(KeyComboAction("Down"))
+sequence.append(utils.AssertPresentationAction(
+    "7. Line Down",
+    ["BRAILLE LINE:  'This is an example of an unordered list:'",
+     "     VISIBLE:  'This is an example of an unorder', cursor=1",
+     "SPEECH OUTPUT: 'This is an example of an unordered list:'"]))
+
+sequence.append(utils.StartRecordingAction())
+sequence.append(KeyComboAction("Down"))
+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.'"]))
+
+sequence.append(utils.StartRecordingAction())
+sequence.append(KeyComboAction("Down"))
+sequence.append(utils.AssertPresentationAction(
+    "9. Line Down",
+    ["BRAILLE LINE:  '• This is a list item that spans multiple lines. If Orca can successfully read to the 
end of this list item, it will have read'",
+     "     VISIBLE:  '• This is a list item that spans', cursor=1",
+     "SPEECH OUTPUT: '• This is a list item that spans multiple lines. If Orca can successfully read to the 
end of this list item, it will have read.'"]))
+
+sequence.append(utils.StartRecordingAction())
+sequence.append(KeyComboAction("Down"))
+sequence.append(utils.AssertPresentationAction(
+    "10. Line Down",
+    ["BRAILLE LINE:  'several lines of text within this single item. And, yes, I realize that this is not 
deathless prose. In fact, it is prose that'",
+     "     VISIBLE:  'several lines of text within thi', cursor=1",
+     "SPEECH OUTPUT: 'several lines of text within this single item. And, yes, I realize that this is not 
deathless prose. In fact, it is prose that.'"]))
+
+sequence.append(utils.StartRecordingAction())
+sequence.append(KeyComboAction("Up"))
+sequence.append(utils.AssertPresentationAction(
+    "11. Line Up",
+    ["BRAILLE LINE:  '• This is a list item that spans multiple lines. If Orca can successfully read to the 
end of this list item, it will have read'",
+     "     VISIBLE:  '• This is a list item that spans', cursor=1",
+     "SPEECH OUTPUT: '• This is a list item that spans multiple lines. If Orca can successfully read to the 
end of this list item, it will have read.'"]))
+
+sequence.append(utils.StartRecordingAction())
+sequence.append(KeyComboAction("Up"))
+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.'"]))
+
+sequence.append(utils.StartRecordingAction())
+sequence.append(KeyComboAction("Up"))
+sequence.append(utils.AssertPresentationAction(
+    "13. Line Up",
+    ["BRAILLE LINE:  'This is an example of an unordered list:'",
+     "     VISIBLE:  'This is an example of an unorder', cursor=1",
+     "SPEECH OUTPUT: 'This is an example of an unordered list:'"]))
+
+sequence.append(utils.StartRecordingAction())
+sequence.append(KeyComboAction("Up"))
+sequence.append(utils.AssertPresentationAction(
+    "14. Line Up",
+    ["BRAILLE LINE:  'should probably be put out of its misery.'",
+     "     VISIBLE:  'should probably be put out of it', cursor=1",
+     "SPEECH OUTPUT: 'should probably be put out of its misery.'"]))
+
+sequence.append(utils.StartRecordingAction())
+sequence.append(KeyComboAction("Up"))
+sequence.append(utils.AssertPresentationAction(
+    "15. Line Up",
+    ["BRAILLE LINE:  'several lines of text within this single item. And, yes, I realize that this is not 
deathless prose. In fact, it is prose that'",
+     "     VISIBLE:  'several lines of text within thi', cursor=1",
+     "SPEECH OUTPUT: 'several lines of text within this single item. And, yes, I realize that this is not 
deathless prose. In fact, it is prose that.'"]))
+
+sequence.append(utils.StartRecordingAction())
+sequence.append(KeyComboAction("Up"))
+sequence.append(utils.AssertPresentationAction(
+    "16. Line Up",
+    ["BRAILLE LINE:  '2. This is a list item that spans multiple lines. If Orca can successfully read to the 
end of this list item, it will have read'",
+     "     VISIBLE:  '2. This is a list item that span', cursor=1",
+     "SPEECH OUTPUT: '2. This is a list item that spans multiple lines. If Orca can successfully read to the 
end of this list item, it will have read.'"]))
+
+sequence.append(utils.StartRecordingAction())
+sequence.append(KeyComboAction("Up"))
+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.'"]))
+
+sequence.append(utils.StartRecordingAction())
+sequence.append(KeyComboAction("Up"))
+sequence.append(utils.AssertPresentationAction(
+    "18. Line Up",
+    ["BRAILLE LINE:  'this is an ordered list:'",
+     "     VISIBLE:  'this is an ordered list:', cursor=1",
+     "SPEECH OUTPUT: 'this is an ordered list:'"]))
+
+sequence.append(utils.AssertionSummaryAction())
+sequence.start()
diff --git a/test/keystrokes/firefox/line_nav_bug_577239_no_context.settings 
b/test/keystrokes/firefox/line_nav_bug_577239_no_context.settings
new file mode 100644
index 0000000..39c1cea
--- /dev/null
+++ b/test/keystrokes/firefox/line_nav_bug_577239_no_context.settings
@@ -0,0 +1,165 @@
+{
+    "general": {
+        "enabledSpokenTextAttributes": "size:; family-name:; weight:400; indent:0; underline:none; 
strikethrough:false; justification:left; style:normal; paragraph-style:; text-spelling:none; fg-color:; 
bg-color:;",
+        "orcaModifierKeys": [
+            "Insert",
+            "KP_Insert"
+        ],
+        "skipBlankCells": false,
+        "onlySpeakDisplayedText": false,
+        "enableMnemonicSpeaking": false,
+        "chatAnnounceBuddyTyping": false,
+        "messagesAreDetailed": true,
+        "speakProgressBarUpdates": true,
+        "speakCellCoordinates": true,
+        "enableAlphabeticKeys": true,
+        "enableBraille": false,
+        "brailleAlignmentStyle": 0,
+        "playSoundForPositionInSet": false,
+        "sayAllStyle": 1,
+        "enableEchoBySentence": false,
+        "chatSpeakRoomName": false,
+        "soundVolume": 0.5,
+        "activeProfile": [
+            "Default",
+            "default"
+        ],
+        "brailleVerbosityLevel": 1,
+        "sayAllContextTable": false,
+        "enableTutorialMessages": false,
+        "wrappedStructuralNavigation": true,
+        "capitalizationStyle": "none",
+        "findResultsMinimumLength": 4,
+        "enableContractedBraille": false,
+        "presentDateFormat": "%x",
+        "enableSpeechIndentation": false,
+        "brailleContractionTable": "",
+        "structNavTriggersFocusMode": false,
+        "enablePauseBreaks": true,
+        "speakNumbersAsDigits": false,
+        "spellcheckSpellError": true,
+        "useColorNames": true,
+        "speakContextTable": false,
+        "readFullRowInGUITable": true,
+        "enabledBrailledTextAttributes": "size:; family-name:; weight:400; indent:0; underline:none; 
strikethrough:false; justification:left; style:normal; text-spelling:none;",
+        "enableSpace": true,
+        "brailleSelectorIndicator": 192,
+        "profile": [
+            "Default",
+            "default"
+        ],
+        "verbalizePunctuationStyle": 1,
+        "enableBrailleContext": true,
+        "enableNavigationKeys": false,
+        "structNavInSayAll": false,
+        "enableSound": true,
+        "speakCellSpan": true,
+        "speechVerbosityLevel": 1,
+        "brailleRolenameStyle": 1,
+        "mouseDwellDelay": null,
+        "enableSpeech": true,
+        "caretNavTriggersFocusMode": false,
+        "enableDiacriticalKeys": false,
+        "findResultsVerbosity": 2,
+        "sayAllContextBlockquote": false,
+        "speakBlankLines": true,
+        "speakSpreadsheetCoordinates": true,
+        "flashIsPersistent": false,
+        "enableNumericKeys": true,
+        "enableFlashMessages": true,
+        "progressBarVerbosity": 1,
+        "brailleLinkIndicator": 192,
+        "presentTimeFormat": "%X",
+        "enablePunctuationKeys": true,
+        "enableKeyEcho": false,
+        "playSoundForState": false,
+        "beepProgressBarUpdates": false,
+        "enableFunctionKeys": true,
+        "speakMisspelledIndicator": true,
+        "textAttributesBrailleIndicator": 0,
+        "voices": {
+            "default": {
+                "established": false
+            },
+            "system": {
+                "established": false
+            },
+            "uppercase": {
+                "average-pitch": 7.0
+            },
+            "hyperlink": {
+                "established": false
+            }
+        },
+        "enableBrailleMonitor": true,
+        "layoutMode": true,
+        "brailleFlashTime": 5000,
+        "largeObjectTextLength": 75,
+        "speakContextList": false,
+        "ignoreStatusBarProgressBars": true,
+        "keyboardLayout": 1,
+        "brailleProgressBarUpdates": false,
+        "readFullRowInSpreadSheet": false,
+        "enableActionKeys": true,
+        "enablePositionSpeaking": false,
+        "structuralNavigationEnabled": true,
+        "playSoundForRole": false,
+        "disableBrailleEOL": false,
+        "presentToolTips": false,
+        "enableMouseReview": false,
+        "speechServerFactory": "speechdispatcherfactory",
+        "chatMessageVerbosity": 0,
+        "enableEchoByWord": false,
+        "spellcheckSpellSuggestion": true,
+        "enableModifierKeys": true,
+        "speakMultiCaseStringsAsWords": false,
+        "flashIsDetailed": true,
+        "speakCellHeaders": true,
+        "rewindAndFastForwardInSayAll": false,
+        "sayAllContextList": false,
+        "speakContextBlockquote": false,
+        "enableEchoByCharacter": false,
+        "playSoundForValue": false,
+        "progressBarUpdateInterval": 10,
+        "spellcheckPresentContext": true,
+        "speechServerInfo": null,
+        "chatRoomHistories": false,
+        "readFullRowInDocumentTable": true,
+        "startingProfile": [
+            "Default",
+            "default"
+        ]
+    },
+    "keybindings": {},
+    "profiles": {
+        "default": {
+            "profile": [
+                "Default",
+                "default"
+            ],
+            "brailleContractionTable": "/usr/share/liblouis/tables/en-us-compbrl.ctb",
+            "voices": {
+                "default": {
+                    "established": false
+                },
+                "system": {
+                    "established": false
+                },
+                "uppercase": {
+                    "average-pitch": 7.0
+                },
+                "hyperlink": {
+                    "established": false
+                }
+            },
+            "pronunciations": {},
+            "speechServerInfo": [
+                "Default Synthesizer",
+                "default"
+            ],
+            "keybindings": {},
+            "speechServerFactory": "orca.speechdispatcherfactory"
+        }
+    },
+    "pronunciations": {}
+}
\ No newline at end of file
diff --git a/test/keystrokes/firefox/line_nav_roledescriptions.py 
b/test/keystrokes/firefox/line_nav_roledescriptions.py
index 43a42c4..a0ff9e8 100644
--- a/test/keystrokes/firefox/line_nav_roledescriptions.py
+++ b/test/keystrokes/firefox/line_nav_roledescriptions.py
@@ -60,6 +60,7 @@ sequence.append(utils.AssertPresentationAction(
     "6. Line Down",
     ["BRAILLE LINE:  'Here are some slides'",
      "     VISIBLE:  'Here are some slides', cursor=1",
+     "SPEECH OUTPUT: 'Presentation slide set'",
      "SPEECH OUTPUT: 'Here are some slides'"]))
 
 sequence.append(utils.AssertionSummaryAction())
diff --git a/test/keystrokes/firefox/line_nav_slash_test.py b/test/keystrokes/firefox/line_nav_slash_test.py
index ebcefcb..766fb91 100644
--- a/test/keystrokes/firefox/line_nav_slash_test.py
+++ b/test/keystrokes/firefox/line_nav_slash_test.py
@@ -65,6 +65,7 @@ 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: 'Log in panel'",
      "SPEECH OUTPUT: 'Nickname'",
      "SPEECH OUTPUT: 'entry.'",
      "SPEECH OUTPUT: 'Password'",
@@ -111,6 +112,7 @@ sequence.append(utils.AssertPresentationAction(
     "11. Line Up",
     ["BRAILLE LINE:  '& y Some polls radio button'",
      "     VISIBLE:  '& y Some polls radio button', cursor=1",
+     "SPEECH OUTPUT: 'Poll panel'",
      "SPEECH OUTPUT: 'Some polls.'",
      "SPEECH OUTPUT: 'not selected radio button'"]))
 
@@ -136,6 +138,7 @@ 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: 'Log in panel'",
      "SPEECH OUTPUT: 'Nickname'",
      "SPEECH OUTPUT: 'entry.'",
      "SPEECH OUTPUT: 'Password'",
diff --git a/test/keystrokes/firefox/say_all_blockquote.py b/test/keystrokes/firefox/say_all_blockquote.py
index 08c7f3a..64fbb6f 100644
--- a/test/keystrokes/firefox/say_all_blockquote.py
+++ b/test/keystrokes/firefox/say_all_blockquote.py
@@ -15,6 +15,7 @@ sequence.append(KeyComboAction("KP_Add"))
 sequence.append(utils.AssertPresentationAction(
     "1. KP_Add to do a SayAll",
     ["SPEECH OUTPUT: 'On weaponry:'",
+     "SPEECH OUTPUT: 'block quote'",
      "SPEECH OUTPUT: 'NOBODY expects the Spanish Inquisition!'",
      "SPEECH OUTPUT: 'Our chief weapon is surprise.'",
      "SPEECH OUTPUT: 'Surprise and fear.'",
@@ -30,14 +31,18 @@ sequence.append(utils.AssertPresentationAction(
      "SPEECH OUTPUT: 'I'll come in again.'",
      "SPEECH OUTPUT: 'NOBODY expects the Spanish Inquisition!'",
      "SPEECH OUTPUT: 'Amongst our weaponry are such diverse elements as: fear, surprise, ruthless 
efficiency, an almost fanatical devotion to the Pope, and nice red uniforms - Oh damn!'",
+     "SPEECH OUTPUT: 'leaving blockquote.'",
      "SPEECH OUTPUT: 'On old ladies:'",
+     "SPEECH OUTPUT: 'block quote'",
      "SPEECH OUTPUT: 'Now old lady, you have one last chance.'",
      "SPEECH OUTPUT: 'Confess the heinous sin of heresy, reject the works of the ungodly.'",
      "SPEECH OUTPUT: 'Two last chances.'",
      "SPEECH OUTPUT: 'And you shall be free.'",
      "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: 'leaving blockquote.'",
      "SPEECH OUTPUT: 'On castle decor:'",
+     "SPEECH OUTPUT: 'block quote'",
      "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_blockquote.settings 
b/test/keystrokes/firefox/say_all_blockquote.settings
new file mode 100644
index 0000000..6d6a48a
--- /dev/null
+++ b/test/keystrokes/firefox/say_all_blockquote.settings
@@ -0,0 +1,165 @@
+{
+    "general": {
+        "enabledSpokenTextAttributes": "size:; family-name:; weight:400; indent:0; underline:none; 
strikethrough:false; justification:left; style:normal; paragraph-style:; text-spelling:none; fg-color:; 
bg-color:;",
+        "orcaModifierKeys": [
+            "Insert",
+            "KP_Insert"
+        ],
+        "skipBlankCells": false,
+        "onlySpeakDisplayedText": false,
+        "enableMnemonicSpeaking": false,
+        "chatAnnounceBuddyTyping": false,
+        "messagesAreDetailed": true,
+        "speakProgressBarUpdates": true,
+        "speakCellCoordinates": true,
+        "enableAlphabeticKeys": true,
+        "enableBraille": false,
+        "brailleAlignmentStyle": 0,
+        "playSoundForPositionInSet": false,
+        "sayAllStyle": 1,
+        "enableEchoBySentence": false,
+        "chatSpeakRoomName": false,
+        "soundVolume": 0.5,
+        "activeProfile": [
+            "Default",
+            "default"
+        ],
+        "brailleVerbosityLevel": 1,
+        "sayAllContextTable": true,
+        "enableTutorialMessages": false,
+        "wrappedStructuralNavigation": true,
+        "capitalizationStyle": "none",
+        "findResultsMinimumLength": 4,
+        "enableContractedBraille": false,
+        "presentDateFormat": "%x",
+        "enableSpeechIndentation": false,
+        "brailleContractionTable": "",
+        "structNavTriggersFocusMode": false,
+        "enablePauseBreaks": true,
+        "speakNumbersAsDigits": false,
+        "spellcheckSpellError": true,
+        "useColorNames": true,
+        "speakContextTable": false,
+        "readFullRowInGUITable": true,
+        "enabledBrailledTextAttributes": "size:; family-name:; weight:400; indent:0; underline:none; 
strikethrough:false; justification:left; style:normal; text-spelling:none;",
+        "enableSpace": true,
+        "brailleSelectorIndicator": 192,
+        "profile": [
+            "Default",
+            "default"
+        ],
+        "verbalizePunctuationStyle": 1,
+        "enableBrailleContext": true,
+        "enableNavigationKeys": false,
+        "structNavInSayAll": false,
+        "enableSound": true,
+        "speakCellSpan": true,
+        "speechVerbosityLevel": 1,
+        "brailleRolenameStyle": 1,
+        "mouseDwellDelay": null,
+        "enableSpeech": true,
+        "caretNavTriggersFocusMode": false,
+        "enableDiacriticalKeys": false,
+        "findResultsVerbosity": 2,
+        "sayAllContextBlockquote": true,
+        "speakBlankLines": true,
+        "speakSpreadsheetCoordinates": true,
+        "flashIsPersistent": false,
+        "enableNumericKeys": true,
+        "enableFlashMessages": true,
+        "progressBarVerbosity": 1,
+        "brailleLinkIndicator": 192,
+        "presentTimeFormat": "%X",
+        "enablePunctuationKeys": true,
+        "enableKeyEcho": false,
+        "playSoundForState": false,
+        "beepProgressBarUpdates": false,
+        "enableFunctionKeys": true,
+        "speakMisspelledIndicator": true,
+        "textAttributesBrailleIndicator": 0,
+        "voices": {
+            "default": {
+                "established": false
+            },
+            "system": {
+                "average-pitch": 3.0
+            },
+            "uppercase": {
+                "average-pitch": 7.0
+            },
+            "hyperlink": {
+                "established": false
+            }
+        },
+        "enableBrailleMonitor": true,
+        "layoutMode": true,
+        "brailleFlashTime": 5000,
+        "largeObjectTextLength": 75,
+        "speakContextList": false,
+        "ignoreStatusBarProgressBars": true,
+        "keyboardLayout": 1,
+        "brailleProgressBarUpdates": false,
+        "readFullRowInSpreadSheet": false,
+        "enableActionKeys": true,
+        "enablePositionSpeaking": false,
+        "structuralNavigationEnabled": true,
+        "playSoundForRole": false,
+        "disableBrailleEOL": false,
+        "presentToolTips": false,
+        "enableMouseReview": false,
+        "speechServerFactory": "speechdispatcherfactory",
+        "chatMessageVerbosity": 0,
+        "enableEchoByWord": false,
+        "spellcheckSpellSuggestion": true,
+        "enableModifierKeys": true,
+        "speakMultiCaseStringsAsWords": false,
+        "flashIsDetailed": true,
+        "speakCellHeaders": true,
+        "rewindAndFastForwardInSayAll": false,
+        "sayAllContextList": true,
+        "speakContextBlockquote": false,
+        "enableEchoByCharacter": false,
+        "playSoundForValue": false,
+        "progressBarUpdateInterval": 10,
+        "spellcheckPresentContext": true,
+        "speechServerInfo": null,
+        "chatRoomHistories": false,
+        "readFullRowInDocumentTable": true,
+        "startingProfile": [
+            "Default",
+            "default"
+        ]
+    },
+    "keybindings": {},
+    "profiles": {
+        "default": {
+            "profile": [
+                "Default",
+                "default"
+            ],
+            "brailleContractionTable": "/usr/share/liblouis/tables/en-us-compbrl.ctb",
+            "voices": {
+                "default": {
+                    "established": false
+                },
+                "system": {
+                    "average-pitch": 3.0
+                },
+                "uppercase": {
+                    "average-pitch": 7.0
+                },
+                "hyperlink": {
+                    "established": false
+                }
+            },
+            "pronunciations": {},
+            "speechServerInfo": [
+                "Default Synthesizer",
+                "default"
+            ],
+            "keybindings": {},
+            "speechServerFactory": "orca.speechdispatcherfactory"
+        }
+    },
+    "pronunciations": {}
+}
\ No newline at end of file
diff --git a/test/keystrokes/firefox/say_all_blockquote_no_context.params 
b/test/keystrokes/firefox/say_all_blockquote_no_context.params
new file mode 100644
index 0000000..dad99a0
--- /dev/null
+++ b/test/keystrokes/firefox/say_all_blockquote_no_context.params
@@ -0,0 +1 @@
+PARAMS=$TEST_DIR/../../html/blockquotes.html
diff --git a/test/keystrokes/firefox/say_all_blockquote_no_context.py 
b/test/keystrokes/firefox/say_all_blockquote_no_context.py
new file mode 100644
index 0000000..08c7f3a
--- /dev/null
+++ b/test/keystrokes/firefox/say_all_blockquote_no_context.py
@@ -0,0 +1,46 @@
+#!/usr/bin/python
+
+"""Test of sayAll."""
+
+from macaroon.playback import *
+import utils
+
+sequence = MacroSequence()
+
+#sequence.append(WaitForDocLoad())
+sequence.append(PauseAction(5000))
+
+sequence.append(utils.StartRecordingAction())
+sequence.append(KeyComboAction("KP_Add"))
+sequence.append(utils.AssertPresentationAction(
+    "1. KP_Add to do a SayAll",
+    ["SPEECH OUTPUT: 'On weaponry:'",
+     "SPEECH OUTPUT: 'NOBODY expects the Spanish Inquisition!'",
+     "SPEECH OUTPUT: 'Our chief weapon is surprise.'",
+     "SPEECH OUTPUT: 'Surprise and fear.'",
+     "SPEECH OUTPUT: 'Fear and surprise.'",
+     "SPEECH OUTPUT: 'Our two weapons are fear and surprise.'",
+     "SPEECH OUTPUT: 'And ruthless efficiency.'",
+     "SPEECH OUTPUT: 'Our three weapons are fear, surprise, and ruthless efficiency.'",
+     "SPEECH OUTPUT: 'And an almost fanatical devotion to the Pope.'",
+     "SPEECH OUTPUT: 'Our four.'",
+     "SPEECH OUTPUT: 'No.'",
+     "SPEECH OUTPUT: 'Amongst our weapons.'",
+     "SPEECH OUTPUT: 'Amongst our weaponry, are such elements as fear, surprise.'",
+     "SPEECH OUTPUT: 'I'll come in again.'",
+     "SPEECH OUTPUT: 'NOBODY expects the Spanish Inquisition!'",
+     "SPEECH OUTPUT: 'Amongst our weaponry are such diverse elements as: fear, surprise, ruthless 
efficiency, an almost fanatical devotion to the Pope, and nice red uniforms - Oh damn!'",
+     "SPEECH OUTPUT: 'On old ladies:'",
+     "SPEECH OUTPUT: 'Now old lady, you have one last chance.'",
+     "SPEECH OUTPUT: 'Confess the heinous sin of heresy, reject the works of the ungodly.'",
+     "SPEECH OUTPUT: 'Two last chances.'",
+     "SPEECH OUTPUT: 'And you shall be free.'",
+     "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! She is made of harder stuff!'",
+     "SPEECH OUTPUT: 'Cardinal Fang!'",
+     "SPEECH OUTPUT: 'Fetch the COMFY CHAIR!'"]))
+
+sequence.append(utils.AssertionSummaryAction())
+sequence.start()
diff --git a/test/keystrokes/firefox/say_all_blockquote_no_context.settings 
b/test/keystrokes/firefox/say_all_blockquote_no_context.settings
new file mode 100644
index 0000000..e6a6d5c
--- /dev/null
+++ b/test/keystrokes/firefox/say_all_blockquote_no_context.settings
@@ -0,0 +1,165 @@
+{
+    "general": {
+        "enabledSpokenTextAttributes": "size:; family-name:; weight:400; indent:0; underline:none; 
strikethrough:false; justification:left; style:normal; paragraph-style:; text-spelling:none; fg-color:; 
bg-color:;",
+        "orcaModifierKeys": [
+            "Insert",
+            "KP_Insert"
+        ],
+        "skipBlankCells": false,
+        "onlySpeakDisplayedText": false,
+        "enableMnemonicSpeaking": false,
+        "chatAnnounceBuddyTyping": false,
+        "messagesAreDetailed": true,
+        "speakProgressBarUpdates": true,
+        "speakCellCoordinates": true,
+        "enableAlphabeticKeys": true,
+        "enableBraille": false,
+        "brailleAlignmentStyle": 0,
+        "playSoundForPositionInSet": false,
+        "sayAllStyle": 1,
+        "enableEchoBySentence": false,
+        "chatSpeakRoomName": false,
+        "soundVolume": 0.5,
+        "activeProfile": [
+            "Default",
+            "default"
+        ],
+        "brailleVerbosityLevel": 1,
+        "sayAllContextTable": false,
+        "enableTutorialMessages": false,
+        "wrappedStructuralNavigation": true,
+        "capitalizationStyle": "none",
+        "findResultsMinimumLength": 4,
+        "enableContractedBraille": false,
+        "presentDateFormat": "%x",
+        "enableSpeechIndentation": false,
+        "brailleContractionTable": "",
+        "structNavTriggersFocusMode": false,
+        "enablePauseBreaks": true,
+        "speakNumbersAsDigits": false,
+        "spellcheckSpellError": true,
+        "useColorNames": true,
+        "speakContextTable": false,
+        "readFullRowInGUITable": true,
+        "enabledBrailledTextAttributes": "size:; family-name:; weight:400; indent:0; underline:none; 
strikethrough:false; justification:left; style:normal; text-spelling:none;",
+        "enableSpace": true,
+        "brailleSelectorIndicator": 192,
+        "profile": [
+            "Default",
+            "default"
+        ],
+        "verbalizePunctuationStyle": 1,
+        "enableBrailleContext": true,
+        "enableNavigationKeys": false,
+        "structNavInSayAll": false,
+        "enableSound": true,
+        "speakCellSpan": true,
+        "speechVerbosityLevel": 1,
+        "brailleRolenameStyle": 1,
+        "mouseDwellDelay": null,
+        "enableSpeech": true,
+        "caretNavTriggersFocusMode": false,
+        "enableDiacriticalKeys": false,
+        "findResultsVerbosity": 2,
+        "sayAllContextBlockquote": false,
+        "speakBlankLines": true,
+        "speakSpreadsheetCoordinates": true,
+        "flashIsPersistent": false,
+        "enableNumericKeys": true,
+        "enableFlashMessages": true,
+        "progressBarVerbosity": 1,
+        "brailleLinkIndicator": 192,
+        "presentTimeFormat": "%X",
+        "enablePunctuationKeys": true,
+        "enableKeyEcho": false,
+        "playSoundForState": false,
+        "beepProgressBarUpdates": false,
+        "enableFunctionKeys": true,
+        "speakMisspelledIndicator": true,
+        "textAttributesBrailleIndicator": 0,
+        "voices": {
+            "default": {
+                "established": false
+            },
+            "system": {
+                "average-pitch": 3.0
+            },
+            "uppercase": {
+                "average-pitch": 7.0
+            },
+            "hyperlink": {
+                "established": false
+            }
+        },
+        "enableBrailleMonitor": true,
+        "layoutMode": true,
+        "brailleFlashTime": 5000,
+        "largeObjectTextLength": 75,
+        "speakContextList": false,
+        "ignoreStatusBarProgressBars": true,
+        "keyboardLayout": 1,
+        "brailleProgressBarUpdates": false,
+        "readFullRowInSpreadSheet": false,
+        "enableActionKeys": true,
+        "enablePositionSpeaking": false,
+        "structuralNavigationEnabled": true,
+        "playSoundForRole": false,
+        "disableBrailleEOL": false,
+        "presentToolTips": false,
+        "enableMouseReview": false,
+        "speechServerFactory": "speechdispatcherfactory",
+        "chatMessageVerbosity": 0,
+        "enableEchoByWord": false,
+        "spellcheckSpellSuggestion": true,
+        "enableModifierKeys": true,
+        "speakMultiCaseStringsAsWords": false,
+        "flashIsDetailed": true,
+        "speakCellHeaders": true,
+        "rewindAndFastForwardInSayAll": false,
+        "sayAllContextList": false,
+        "speakContextBlockquote": false,
+        "enableEchoByCharacter": false,
+        "playSoundForValue": false,
+        "progressBarUpdateInterval": 10,
+        "spellcheckPresentContext": true,
+        "speechServerInfo": null,
+        "chatRoomHistories": false,
+        "readFullRowInDocumentTable": true,
+        "startingProfile": [
+            "Default",
+            "default"
+        ]
+    },
+    "keybindings": {},
+    "profiles": {
+        "default": {
+            "profile": [
+                "Default",
+                "default"
+            ],
+            "brailleContractionTable": "/usr/share/liblouis/tables/en-us-compbrl.ctb",
+            "voices": {
+                "default": {
+                    "established": false
+                },
+                "system": {
+                    "average-pitch": 3.0
+                },
+                "uppercase": {
+                    "average-pitch": 7.0
+                },
+                "hyperlink": {
+                    "established": false
+                }
+            },
+            "pronunciations": {},
+            "speechServerInfo": [
+                "Default Synthesizer",
+                "default"
+            ],
+            "keybindings": {},
+            "speechServerFactory": "orca.speechdispatcherfactory"
+        }
+    },
+    "pronunciations": {}
+}
\ No newline at end of file
diff --git a/test/keystrokes/firefox/say_all_bugzilla_search.py 
b/test/keystrokes/firefox/say_all_bugzilla_search.py
index c5fc4d6..76187ce 100644
--- a/test/keystrokes/firefox/say_all_bugzilla_search.py
+++ b/test/keystrokes/firefox/say_all_bugzilla_search.py
@@ -50,6 +50,7 @@ sequence.append(utils.AssertPresentationAction(
      "SPEECH OUTPUT: 'Give me some help'",
      "SPEECH OUTPUT: 'link'",
      "SPEECH OUTPUT: '(reloads page.)'",
+     "SPEECH OUTPUT: 'table with 5 rows 4 columns'",
      "SPEECH OUTPUT: 'Summary:'",
      "SPEECH OUTPUT: 'row header'",
      "SPEECH OUTPUT: 'contains all of the words/strings'",
@@ -57,10 +58,13 @@ sequence.append(utils.AssertPresentationAction(
      "SPEECH OUTPUT: 'entry'",
      "SPEECH OUTPUT: 'Search'",
      "SPEECH OUTPUT: 'push button'",
+     "SPEECH OUTPUT: 'table with 2 rows 1 column'",
      "SPEECH OUTPUT: 'Classification:'",
      "SPEECH OUTPUT: 'column header'",
      "SPEECH OUTPUT: 'multi-select'",
      "SPEECH OUTPUT: 'List with 8 items'",
+     "SPEECH OUTPUT: 'leaving table.'",
+     "SPEECH OUTPUT: 'table with 2 rows 1 column'",
      "SPEECH OUTPUT: 'Product:'",
      "SPEECH OUTPUT: 'column header'",
      "SPEECH OUTPUT: 'multi-select'",
@@ -71,14 +75,19 @@ sequence.append(utils.AssertPresentationAction(
      "SPEECH OUTPUT: 'column header'",
      "SPEECH OUTPUT: 'multi-select'",
      "SPEECH OUTPUT: 'List with 1248 items'",
+     "SPEECH OUTPUT: 'leaving table.'",
+     "SPEECH OUTPUT: 'table with 2 rows 1 column'",
      "SPEECH OUTPUT: 'Version:'",
      "SPEECH OUTPUT: 'column header'",
      "SPEECH OUTPUT: 'multi-select'",
      "SPEECH OUTPUT: 'List with 857 items'",
+     "SPEECH OUTPUT: 'leaving table.'",
+     "SPEECH OUTPUT: 'table with 2 rows 1 column'",
      "SPEECH OUTPUT: 'Target Milestone:'",
      "SPEECH OUTPUT: 'column header'",
      "SPEECH OUTPUT: 'multi-select'",
      "SPEECH OUTPUT: 'List with 555 items'",
+     "SPEECH OUTPUT: 'leaving table.'",
      "SPEECH OUTPUT: 'A Comment:'",
      "SPEECH OUTPUT: 'row header'",
      "SPEECH OUTPUT: 'contains the string'",
@@ -96,7 +105,9 @@ sequence.append(utils.AssertPresentationAction(
      "SPEECH OUTPUT: 'contains all of the keywords'",
      "SPEECH OUTPUT: 'combo box'",
      "SPEECH OUTPUT: 'entry'",
+     "SPEECH OUTPUT: 'leaving table.'",
      "SPEECH OUTPUT: 'separator'",
+     "SPEECH OUTPUT: 'table with 2 rows 1 column'",
      "SPEECH OUTPUT: 'Status:'",
      "SPEECH OUTPUT: 'column header'",
      "SPEECH OUTPUT: 'UNCONFIRMED'",
@@ -106,22 +117,33 @@ sequence.append(utils.AssertPresentationAction(
      "SPEECH OUTPUT: 'NEEDINFO'",
      "SPEECH OUTPUT: 'multi-select'",
      "SPEECH OUTPUT: 'List with 8 items'",
+     "SPEECH OUTPUT: 'leaving table.'",
+     "SPEECH OUTPUT: 'table with 2 rows 1 column'",
      "SPEECH OUTPUT: 'Resolution:'",
      "SPEECH OUTPUT: 'column header'",
      "SPEECH OUTPUT: 'multi-select'",
      "SPEECH OUTPUT: 'List with 12 items'",
+     "SPEECH OUTPUT: 'leaving table.'",
+     "SPEECH OUTPUT: 'table with 2 rows 1 column'",
      "SPEECH OUTPUT: 'Severity:'",
      "SPEECH OUTPUT: 'column header'",
      "SPEECH OUTPUT: 'multi-select'",
      "SPEECH OUTPUT: 'List with 7 items'",
+     "SPEECH OUTPUT: 'leaving table.'",
+     "SPEECH OUTPUT: 'table with 2 rows 1 column'",
      "SPEECH OUTPUT: 'Priority:'",
      "SPEECH OUTPUT: 'column header'",
      "SPEECH OUTPUT: 'multi-select'",
      "SPEECH OUTPUT: 'List with 5 items'",
+     "SPEECH OUTPUT: 'leaving table.'",
+     "SPEECH OUTPUT: 'table with 2 rows 1 column'",
      "SPEECH OUTPUT: 'OS:'",
      "SPEECH OUTPUT: 'column header'",
      "SPEECH OUTPUT: 'multi-select'",
      "SPEECH OUTPUT: 'List with 21 items'",
+     "SPEECH OUTPUT: 'leaving table.'",
+     "SPEECH OUTPUT: 'Email and Numbering'",
+     "SPEECH OUTPUT: 'panel'",
      "SPEECH OUTPUT: 'Email and Numbering'",
      "SPEECH OUTPUT: 'Any one of:'",
      "SPEECH OUTPUT: 'check box'",
@@ -168,6 +190,9 @@ sequence.append(utils.AssertPresentationAction(
      "SPEECH OUTPUT: 'entry'",
      "SPEECH OUTPUT: '(comma-separated list)'",
      "SPEECH OUTPUT: 'Bug Changes'",
+     "SPEECH OUTPUT: 'panel'",
+     "SPEECH OUTPUT: 'Bug Changes'",
+     "SPEECH OUTPUT: 'List with 3 items'",
      "SPEECH OUTPUT: 'Only bugs changed between:'",
      "SPEECH OUTPUT: 'entry'",
      "SPEECH OUTPUT: 'and'",
@@ -179,14 +204,19 @@ sequence.append(utils.AssertPresentationAction(
      "SPEECH OUTPUT: 'List with 26 items'",
      "SPEECH OUTPUT: 'and the new value was:'",
      "SPEECH OUTPUT: 'entry'",
+     "SPEECH OUTPUT: 'leaving list.'",
+     "SPEECH OUTPUT: 'table with 2 rows 1 column'",
      "SPEECH OUTPUT: 'GNOME version:'",
      "SPEECH OUTPUT: 'column header'",
      "SPEECH OUTPUT: 'multi-select'",
      "SPEECH OUTPUT: 'List with 14 items'",
+     "SPEECH OUTPUT: 'leaving table.'",
+     "SPEECH OUTPUT: 'table with 2 rows 1 column'",
      "SPEECH OUTPUT: 'GNOME target:'",
      "SPEECH OUTPUT: 'column header'",
      "SPEECH OUTPUT: 'multi-select'",
      "SPEECH OUTPUT: 'List with 12 items'",
+     "SPEECH OUTPUT: 'leaving table.'",
      "SPEECH OUTPUT: 'Sort results by:'",
      "SPEECH OUTPUT: 'Reuse same sort as last time'",
      "SPEECH OUTPUT: 'combo box'",
diff --git a/test/keystrokes/firefox/say_all_bugzilla_search.settings 
b/test/keystrokes/firefox/say_all_bugzilla_search.settings
new file mode 100644
index 0000000..6d6a48a
--- /dev/null
+++ b/test/keystrokes/firefox/say_all_bugzilla_search.settings
@@ -0,0 +1,165 @@
+{
+    "general": {
+        "enabledSpokenTextAttributes": "size:; family-name:; weight:400; indent:0; underline:none; 
strikethrough:false; justification:left; style:normal; paragraph-style:; text-spelling:none; fg-color:; 
bg-color:;",
+        "orcaModifierKeys": [
+            "Insert",
+            "KP_Insert"
+        ],
+        "skipBlankCells": false,
+        "onlySpeakDisplayedText": false,
+        "enableMnemonicSpeaking": false,
+        "chatAnnounceBuddyTyping": false,
+        "messagesAreDetailed": true,
+        "speakProgressBarUpdates": true,
+        "speakCellCoordinates": true,
+        "enableAlphabeticKeys": true,
+        "enableBraille": false,
+        "brailleAlignmentStyle": 0,
+        "playSoundForPositionInSet": false,
+        "sayAllStyle": 1,
+        "enableEchoBySentence": false,
+        "chatSpeakRoomName": false,
+        "soundVolume": 0.5,
+        "activeProfile": [
+            "Default",
+            "default"
+        ],
+        "brailleVerbosityLevel": 1,
+        "sayAllContextTable": true,
+        "enableTutorialMessages": false,
+        "wrappedStructuralNavigation": true,
+        "capitalizationStyle": "none",
+        "findResultsMinimumLength": 4,
+        "enableContractedBraille": false,
+        "presentDateFormat": "%x",
+        "enableSpeechIndentation": false,
+        "brailleContractionTable": "",
+        "structNavTriggersFocusMode": false,
+        "enablePauseBreaks": true,
+        "speakNumbersAsDigits": false,
+        "spellcheckSpellError": true,
+        "useColorNames": true,
+        "speakContextTable": false,
+        "readFullRowInGUITable": true,
+        "enabledBrailledTextAttributes": "size:; family-name:; weight:400; indent:0; underline:none; 
strikethrough:false; justification:left; style:normal; text-spelling:none;",
+        "enableSpace": true,
+        "brailleSelectorIndicator": 192,
+        "profile": [
+            "Default",
+            "default"
+        ],
+        "verbalizePunctuationStyle": 1,
+        "enableBrailleContext": true,
+        "enableNavigationKeys": false,
+        "structNavInSayAll": false,
+        "enableSound": true,
+        "speakCellSpan": true,
+        "speechVerbosityLevel": 1,
+        "brailleRolenameStyle": 1,
+        "mouseDwellDelay": null,
+        "enableSpeech": true,
+        "caretNavTriggersFocusMode": false,
+        "enableDiacriticalKeys": false,
+        "findResultsVerbosity": 2,
+        "sayAllContextBlockquote": true,
+        "speakBlankLines": true,
+        "speakSpreadsheetCoordinates": true,
+        "flashIsPersistent": false,
+        "enableNumericKeys": true,
+        "enableFlashMessages": true,
+        "progressBarVerbosity": 1,
+        "brailleLinkIndicator": 192,
+        "presentTimeFormat": "%X",
+        "enablePunctuationKeys": true,
+        "enableKeyEcho": false,
+        "playSoundForState": false,
+        "beepProgressBarUpdates": false,
+        "enableFunctionKeys": true,
+        "speakMisspelledIndicator": true,
+        "textAttributesBrailleIndicator": 0,
+        "voices": {
+            "default": {
+                "established": false
+            },
+            "system": {
+                "average-pitch": 3.0
+            },
+            "uppercase": {
+                "average-pitch": 7.0
+            },
+            "hyperlink": {
+                "established": false
+            }
+        },
+        "enableBrailleMonitor": true,
+        "layoutMode": true,
+        "brailleFlashTime": 5000,
+        "largeObjectTextLength": 75,
+        "speakContextList": false,
+        "ignoreStatusBarProgressBars": true,
+        "keyboardLayout": 1,
+        "brailleProgressBarUpdates": false,
+        "readFullRowInSpreadSheet": false,
+        "enableActionKeys": true,
+        "enablePositionSpeaking": false,
+        "structuralNavigationEnabled": true,
+        "playSoundForRole": false,
+        "disableBrailleEOL": false,
+        "presentToolTips": false,
+        "enableMouseReview": false,
+        "speechServerFactory": "speechdispatcherfactory",
+        "chatMessageVerbosity": 0,
+        "enableEchoByWord": false,
+        "spellcheckSpellSuggestion": true,
+        "enableModifierKeys": true,
+        "speakMultiCaseStringsAsWords": false,
+        "flashIsDetailed": true,
+        "speakCellHeaders": true,
+        "rewindAndFastForwardInSayAll": false,
+        "sayAllContextList": true,
+        "speakContextBlockquote": false,
+        "enableEchoByCharacter": false,
+        "playSoundForValue": false,
+        "progressBarUpdateInterval": 10,
+        "spellcheckPresentContext": true,
+        "speechServerInfo": null,
+        "chatRoomHistories": false,
+        "readFullRowInDocumentTable": true,
+        "startingProfile": [
+            "Default",
+            "default"
+        ]
+    },
+    "keybindings": {},
+    "profiles": {
+        "default": {
+            "profile": [
+                "Default",
+                "default"
+            ],
+            "brailleContractionTable": "/usr/share/liblouis/tables/en-us-compbrl.ctb",
+            "voices": {
+                "default": {
+                    "established": false
+                },
+                "system": {
+                    "average-pitch": 3.0
+                },
+                "uppercase": {
+                    "average-pitch": 7.0
+                },
+                "hyperlink": {
+                    "established": false
+                }
+            },
+            "pronunciations": {},
+            "speechServerInfo": [
+                "Default Synthesizer",
+                "default"
+            ],
+            "keybindings": {},
+            "speechServerFactory": "orca.speechdispatcherfactory"
+        }
+    },
+    "pronunciations": {}
+}
\ No newline at end of file
diff --git a/test/keystrokes/firefox/say_all_bugzilla_search_no_context.params 
b/test/keystrokes/firefox/say_all_bugzilla_search_no_context.params
new file mode 100644
index 0000000..d82c60a
--- /dev/null
+++ b/test/keystrokes/firefox/say_all_bugzilla_search_no_context.params
@@ -0,0 +1 @@
+PARAMS=$TEST_DIR/../../html/bugzilla-advanced.html
diff --git a/test/keystrokes/firefox/say_all_bugzilla_search_no_context.py 
b/test/keystrokes/firefox/say_all_bugzilla_search_no_context.py
new file mode 100644
index 0000000..dbac9fe
--- /dev/null
+++ b/test/keystrokes/firefox/say_all_bugzilla_search_no_context.py
@@ -0,0 +1,236 @@
+#!/usr/bin/python
+
+"""Test of sayAll."""
+
+from macaroon.playback import *
+import utils
+
+sequence = MacroSequence()
+
+#sequence.append(WaitForDocLoad())
+sequence.append(PauseAction(5000))
+sequence.append(KeyComboAction("<Shift>Tab"))
+sequence.append(KeyComboAction("<Shift>Tab"))
+sequence.append(KeyComboAction("<Control>Home"))
+
+sequence.append(utils.StartRecordingAction())
+sequence.append(KeyComboAction("KP_Add"))
+sequence.append(utils.AssertPresentationAction(
+    "KP_Add to do a SayAll",
+    ["SPEECH OUTPUT: 'Home'",
+     "SPEECH OUTPUT: 'link'",
+     "SPEECH OUTPUT: 'Bugzilla'",
+     "SPEECH OUTPUT: 'New bug'",
+     "SPEECH OUTPUT: 'link'",
+     "SPEECH OUTPUT: '·'",
+     "SPEECH OUTPUT: 'Browse'",
+     "SPEECH OUTPUT: 'link'",
+     "SPEECH OUTPUT: '·'",
+     "SPEECH OUTPUT: 'Search'",
+     "SPEECH OUTPUT: 'link'",
+     "SPEECH OUTPUT: '·'",
+     "SPEECH OUTPUT: 'Reports'",
+     "SPEECH OUTPUT: 'link'",
+     "SPEECH OUTPUT: '·'",
+     "SPEECH OUTPUT: 'Account'",
+     "SPEECH OUTPUT: 'link'",
+     "SPEECH OUTPUT: '·'",
+     "SPEECH OUTPUT: 'Admin'",
+     "SPEECH OUTPUT: 'link'",
+     "SPEECH OUTPUT: '·'",
+     "SPEECH OUTPUT: 'Help'",
+     "SPEECH OUTPUT: 'link'",
+     "SPEECH OUTPUT: 'Logged In joanmarie diggs gmail com'",
+     "SPEECH OUTPUT: '|'",
+     "SPEECH OUTPUT: 'Log Out'",
+     "SPEECH OUTPUT: 'link'",
+     "SPEECH OUTPUT: 'Short Bug Search Form'",
+     "SPEECH OUTPUT: 'link'",
+     "SPEECH OUTPUT: 'Complicated Bug Search Form'",
+     "SPEECH OUTPUT: 'Give me some help'",
+     "SPEECH OUTPUT: 'link'",
+     "SPEECH OUTPUT: '(reloads page.)'",
+     "SPEECH OUTPUT: 'Summary:'",
+     "SPEECH OUTPUT: 'row header'",
+     "SPEECH OUTPUT: 'contains all of the words/strings'",
+     "SPEECH OUTPUT: 'combo box'",
+     "SPEECH OUTPUT: 'entry'",
+     "SPEECH OUTPUT: 'Search'",
+     "SPEECH OUTPUT: 'push button'",
+     "SPEECH OUTPUT: 'Classification:'",
+     "SPEECH OUTPUT: 'column header'",
+     "SPEECH OUTPUT: 'multi-select'",
+     "SPEECH OUTPUT: 'List with 8 items'",
+     "SPEECH OUTPUT: 'Product:'",
+     "SPEECH OUTPUT: 'column header'",
+     "SPEECH OUTPUT: 'multi-select'",
+     "SPEECH OUTPUT: 'List with 379 items'",
+     "SPEECH OUTPUT: 'Component'",
+     "SPEECH OUTPUT: 'link'",
+     "SPEECH OUTPUT: ':'",
+     "SPEECH OUTPUT: 'column header'",
+     "SPEECH OUTPUT: 'multi-select'",
+     "SPEECH OUTPUT: 'List with 1248 items'",
+     "SPEECH OUTPUT: 'Version:'",
+     "SPEECH OUTPUT: 'column header'",
+     "SPEECH OUTPUT: 'multi-select'",
+     "SPEECH OUTPUT: 'List with 857 items'",
+     "SPEECH OUTPUT: 'Target Milestone:'",
+     "SPEECH OUTPUT: 'column header'",
+     "SPEECH OUTPUT: 'multi-select'",
+     "SPEECH OUTPUT: 'List with 555 items'",
+     "SPEECH OUTPUT: 'A Comment:'",
+     "SPEECH OUTPUT: 'row header'",
+     "SPEECH OUTPUT: 'contains the string'",
+     "SPEECH OUTPUT: 'combo box'",
+     "SPEECH OUTPUT: 'entry'",
+     "SPEECH OUTPUT: 'Whiteboard:'",
+     "SPEECH OUTPUT: 'row header'",
+     "SPEECH OUTPUT: 'contains all of the words/strings'",
+     "SPEECH OUTPUT: 'combo box'",
+     "SPEECH OUTPUT: 'entry'",
+     "SPEECH OUTPUT: 'Keywords'",
+     "SPEECH OUTPUT: 'link'",
+     "SPEECH OUTPUT: ':'",
+     "SPEECH OUTPUT: 'row header'",
+     "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: 'UNCONFIRMED'",
+     "SPEECH OUTPUT: 'NEW'",
+     "SPEECH OUTPUT: 'ASSIGNED'",
+     "SPEECH OUTPUT: 'REOPENED'",
+     "SPEECH OUTPUT: 'NEEDINFO'",
+     "SPEECH OUTPUT: 'multi-select'",
+     "SPEECH OUTPUT: 'List with 8 items'",
+     "SPEECH OUTPUT: 'Resolution:'",
+     "SPEECH OUTPUT: 'column header'",
+     "SPEECH OUTPUT: 'multi-select'",
+     "SPEECH OUTPUT: 'List with 12 items'",
+     "SPEECH OUTPUT: 'Severity:'",
+     "SPEECH OUTPUT: 'column header'",
+     "SPEECH OUTPUT: 'multi-select'",
+     "SPEECH OUTPUT: 'List with 7 items'",
+     "SPEECH OUTPUT: 'Priority:'",
+     "SPEECH OUTPUT: 'column header'",
+     "SPEECH OUTPUT: 'multi-select'",
+     "SPEECH OUTPUT: 'List with 5 items'",
+     "SPEECH OUTPUT: 'OS:'",
+     "SPEECH OUTPUT: 'column header'",
+     "SPEECH OUTPUT: 'multi-select'",
+     "SPEECH OUTPUT: 'List with 21 items'",
+     "SPEECH OUTPUT: 'Email and Numbering'",
+     "SPEECH OUTPUT: 'panel'",
+     "SPEECH OUTPUT: 'Email and Numbering'",
+     "SPEECH OUTPUT: 'Any one of:'",
+     "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'",
+     "SPEECH OUTPUT: 'the QA contact'",
+     "SPEECH OUTPUT: 'check box'",
+     "SPEECH OUTPUT: 'not checked'",
+     "SPEECH OUTPUT: 'a CC list member'",
+     "SPEECH OUTPUT: 'check box'",
+     "SPEECH OUTPUT: 'not checked'",
+     "SPEECH OUTPUT: 'a commenter'",
+     "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'",
+     "SPEECH OUTPUT: 'the reporter'",
+     "SPEECH OUTPUT: 'check box'",
+     "SPEECH OUTPUT: 'checked'",
+     "SPEECH OUTPUT: 'the QA contact'",
+     "SPEECH OUTPUT: 'check box'",
+     "SPEECH OUTPUT: 'checked'",
+     "SPEECH OUTPUT: 'a CC list member'",
+     "SPEECH OUTPUT: 'check box'",
+     "SPEECH OUTPUT: 'not checked'",
+     "SPEECH OUTPUT: 'a commenter'",
+     "SPEECH OUTPUT: 'contains'",
+     "SPEECH OUTPUT: 'combo box'",
+     "SPEECH OUTPUT: 'entry'",
+     "SPEECH OUTPUT: 'separator'",
+     "SPEECH OUTPUT: 'Only include'",
+     "SPEECH OUTPUT: 'combo box'",
+     "SPEECH OUTPUT: 'bugs numbered:'",
+     "SPEECH OUTPUT: 'entry'",
+     "SPEECH OUTPUT: '(comma-separated list)'",
+     "SPEECH OUTPUT: 'Bug Changes'",
+     "SPEECH OUTPUT: 'panel'",
+     "SPEECH OUTPUT: 'Bug Changes'",
+     "SPEECH OUTPUT: 'Only bugs changed between:'",
+     "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: 'multi-select'",
+     "SPEECH OUTPUT: 'List with 26 items'",
+     "SPEECH OUTPUT: 'and the new value was:'",
+     "SPEECH OUTPUT: 'entry'",
+     "SPEECH OUTPUT: 'GNOME version:'",
+     "SPEECH OUTPUT: 'column header'",
+     "SPEECH OUTPUT: 'multi-select'",
+     "SPEECH OUTPUT: 'List with 14 items'",
+     "SPEECH OUTPUT: 'GNOME target:'",
+     "SPEECH OUTPUT: 'column header'",
+     "SPEECH OUTPUT: 'multi-select'",
+     "SPEECH OUTPUT: 'List with 12 items'",
+     "SPEECH OUTPUT: 'Sort results by:'",
+     "SPEECH OUTPUT: 'Reuse same sort as last time'",
+     "SPEECH OUTPUT: 'combo box'",
+     "SPEECH OUTPUT: 'Search'",
+     "SPEECH OUTPUT: 'push button'",
+     "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: 'check box'",
+     "SPEECH OUTPUT: 'not checked'",
+     "SPEECH OUTPUT: 'Not (negate this whole chart)'",
+     "SPEECH OUTPUT: '---'",
+     "SPEECH OUTPUT: 'combo box'",
+     "SPEECH OUTPUT: '---'",
+     "SPEECH OUTPUT: 'combo box'",
+     "SPEECH OUTPUT: 'entry'",
+     "SPEECH OUTPUT: 'Or'",
+     "SPEECH OUTPUT: 'push button'",
+     "SPEECH OUTPUT: 'And'",
+     "SPEECH OUTPUT: 'push button'",
+     "SPEECH OUTPUT: 'Add another boolean chart'",
+     "SPEECH OUTPUT: 'push button'",
+     "SPEECH OUTPUT: 'separator'",
+     "SPEECH OUTPUT: 'Saved Searches:'",
+     "SPEECH OUTPUT: 'My Bugs and Patches'",
+     "SPEECH OUTPUT: 'link'",
+     "SPEECH OUTPUT: '|'",
+     "SPEECH OUTPUT: 'All Orca'",
+     "SPEECH OUTPUT: 'link'",
+     "SPEECH OUTPUT: '|'",
+     "SPEECH OUTPUT: 'Firefox'",
+     "SPEECH OUTPUT: 'link'",
+     "SPEECH OUTPUT: '|'",
+     "SPEECH OUTPUT: 'open orca'",
+     "SPEECH OUTPUT: 'link'",
+     "SPEECH OUTPUT: '|'",
+     "SPEECH OUTPUT: 'Open RFEs'",
+     "SPEECH OUTPUT: 'link'"]))
+
+sequence.append(utils.AssertionSummaryAction())
+sequence.start()
diff --git a/test/keystrokes/firefox/say_all_bugzilla_search_no_context.settings 
b/test/keystrokes/firefox/say_all_bugzilla_search_no_context.settings
new file mode 100644
index 0000000..e6a6d5c
--- /dev/null
+++ b/test/keystrokes/firefox/say_all_bugzilla_search_no_context.settings
@@ -0,0 +1,165 @@
+{
+    "general": {
+        "enabledSpokenTextAttributes": "size:; family-name:; weight:400; indent:0; underline:none; 
strikethrough:false; justification:left; style:normal; paragraph-style:; text-spelling:none; fg-color:; 
bg-color:;",
+        "orcaModifierKeys": [
+            "Insert",
+            "KP_Insert"
+        ],
+        "skipBlankCells": false,
+        "onlySpeakDisplayedText": false,
+        "enableMnemonicSpeaking": false,
+        "chatAnnounceBuddyTyping": false,
+        "messagesAreDetailed": true,
+        "speakProgressBarUpdates": true,
+        "speakCellCoordinates": true,
+        "enableAlphabeticKeys": true,
+        "enableBraille": false,
+        "brailleAlignmentStyle": 0,
+        "playSoundForPositionInSet": false,
+        "sayAllStyle": 1,
+        "enableEchoBySentence": false,
+        "chatSpeakRoomName": false,
+        "soundVolume": 0.5,
+        "activeProfile": [
+            "Default",
+            "default"
+        ],
+        "brailleVerbosityLevel": 1,
+        "sayAllContextTable": false,
+        "enableTutorialMessages": false,
+        "wrappedStructuralNavigation": true,
+        "capitalizationStyle": "none",
+        "findResultsMinimumLength": 4,
+        "enableContractedBraille": false,
+        "presentDateFormat": "%x",
+        "enableSpeechIndentation": false,
+        "brailleContractionTable": "",
+        "structNavTriggersFocusMode": false,
+        "enablePauseBreaks": true,
+        "speakNumbersAsDigits": false,
+        "spellcheckSpellError": true,
+        "useColorNames": true,
+        "speakContextTable": false,
+        "readFullRowInGUITable": true,
+        "enabledBrailledTextAttributes": "size:; family-name:; weight:400; indent:0; underline:none; 
strikethrough:false; justification:left; style:normal; text-spelling:none;",
+        "enableSpace": true,
+        "brailleSelectorIndicator": 192,
+        "profile": [
+            "Default",
+            "default"
+        ],
+        "verbalizePunctuationStyle": 1,
+        "enableBrailleContext": true,
+        "enableNavigationKeys": false,
+        "structNavInSayAll": false,
+        "enableSound": true,
+        "speakCellSpan": true,
+        "speechVerbosityLevel": 1,
+        "brailleRolenameStyle": 1,
+        "mouseDwellDelay": null,
+        "enableSpeech": true,
+        "caretNavTriggersFocusMode": false,
+        "enableDiacriticalKeys": false,
+        "findResultsVerbosity": 2,
+        "sayAllContextBlockquote": false,
+        "speakBlankLines": true,
+        "speakSpreadsheetCoordinates": true,
+        "flashIsPersistent": false,
+        "enableNumericKeys": true,
+        "enableFlashMessages": true,
+        "progressBarVerbosity": 1,
+        "brailleLinkIndicator": 192,
+        "presentTimeFormat": "%X",
+        "enablePunctuationKeys": true,
+        "enableKeyEcho": false,
+        "playSoundForState": false,
+        "beepProgressBarUpdates": false,
+        "enableFunctionKeys": true,
+        "speakMisspelledIndicator": true,
+        "textAttributesBrailleIndicator": 0,
+        "voices": {
+            "default": {
+                "established": false
+            },
+            "system": {
+                "average-pitch": 3.0
+            },
+            "uppercase": {
+                "average-pitch": 7.0
+            },
+            "hyperlink": {
+                "established": false
+            }
+        },
+        "enableBrailleMonitor": true,
+        "layoutMode": true,
+        "brailleFlashTime": 5000,
+        "largeObjectTextLength": 75,
+        "speakContextList": false,
+        "ignoreStatusBarProgressBars": true,
+        "keyboardLayout": 1,
+        "brailleProgressBarUpdates": false,
+        "readFullRowInSpreadSheet": false,
+        "enableActionKeys": true,
+        "enablePositionSpeaking": false,
+        "structuralNavigationEnabled": true,
+        "playSoundForRole": false,
+        "disableBrailleEOL": false,
+        "presentToolTips": false,
+        "enableMouseReview": false,
+        "speechServerFactory": "speechdispatcherfactory",
+        "chatMessageVerbosity": 0,
+        "enableEchoByWord": false,
+        "spellcheckSpellSuggestion": true,
+        "enableModifierKeys": true,
+        "speakMultiCaseStringsAsWords": false,
+        "flashIsDetailed": true,
+        "speakCellHeaders": true,
+        "rewindAndFastForwardInSayAll": false,
+        "sayAllContextList": false,
+        "speakContextBlockquote": false,
+        "enableEchoByCharacter": false,
+        "playSoundForValue": false,
+        "progressBarUpdateInterval": 10,
+        "spellcheckPresentContext": true,
+        "speechServerInfo": null,
+        "chatRoomHistories": false,
+        "readFullRowInDocumentTable": true,
+        "startingProfile": [
+            "Default",
+            "default"
+        ]
+    },
+    "keybindings": {},
+    "profiles": {
+        "default": {
+            "profile": [
+                "Default",
+                "default"
+            ],
+            "brailleContractionTable": "/usr/share/liblouis/tables/en-us-compbrl.ctb",
+            "voices": {
+                "default": {
+                    "established": false
+                },
+                "system": {
+                    "average-pitch": 3.0
+                },
+                "uppercase": {
+                    "average-pitch": 7.0
+                },
+                "hyperlink": {
+                    "established": false
+                }
+            },
+            "pronunciations": {},
+            "speechServerInfo": [
+                "Default Synthesizer",
+                "default"
+            ],
+            "keybindings": {},
+            "speechServerFactory": "orca.speechdispatcherfactory"
+        }
+    },
+    "pronunciations": {}
+}
\ No newline at end of file
diff --git a/test/keystrokes/firefox/say_all_multi_line_text.py 
b/test/keystrokes/firefox/say_all_multi_line_text.py
index 2279b55..34fb1db 100644
--- a/test/keystrokes/firefox/say_all_multi_line_text.py
+++ b/test/keystrokes/firefox/say_all_multi_line_text.py
@@ -19,11 +19,12 @@ 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: 'List with 3 items'",
      "SPEECH OUTPUT: '•'",
      "SPEECH OUTPUT: 'This is a test'",
      "SPEECH OUTPUT: 'link'",
@@ -36,12 +37,14 @@ sequence.append(utils.AssertPresentationAction(
      "SPEECH OUTPUT: 'And that's'",
      "SPEECH OUTPUT: 'link'",
      "SPEECH OUTPUT: 'why this silly test is here.'",
+     "SPEECH OUTPUT: 'leaving list.'",
      "SPEECH OUTPUT: 'So it's'",
      "SPEECH OUTPUT: 'far more interesting'",
      "SPEECH OUTPUT: 'link'",
      "SPEECH OUTPUT: 'than it looks.'",
      "SPEECH OUTPUT: 'World'",
      "SPEECH OUTPUT: 'heading level 3'",
+     "SPEECH OUTPUT: 'List with 3 items'",
      "SPEECH OUTPUT: '•'",
      "SPEECH OUTPUT: 'The thing is'",
      "SPEECH OUTPUT: 'link'",
@@ -54,6 +57,7 @@ sequence.append(utils.AssertPresentationAction(
      "SPEECH OUTPUT: 'Oh'",
      "SPEECH OUTPUT: 'link'",
      "SPEECH OUTPUT: 'well.'",
+     "SPEECH OUTPUT: 'leaving list.'",
      "SPEECH OUTPUT: 'At least it's'",
      "SPEECH OUTPUT: 'over'",
      "SPEECH OUTPUT: 'link'",
diff --git a/test/keystrokes/firefox/say_all_multi_line_text.settings 
b/test/keystrokes/firefox/say_all_multi_line_text.settings
new file mode 100644
index 0000000..6d6a48a
--- /dev/null
+++ b/test/keystrokes/firefox/say_all_multi_line_text.settings
@@ -0,0 +1,165 @@
+{
+    "general": {
+        "enabledSpokenTextAttributes": "size:; family-name:; weight:400; indent:0; underline:none; 
strikethrough:false; justification:left; style:normal; paragraph-style:; text-spelling:none; fg-color:; 
bg-color:;",
+        "orcaModifierKeys": [
+            "Insert",
+            "KP_Insert"
+        ],
+        "skipBlankCells": false,
+        "onlySpeakDisplayedText": false,
+        "enableMnemonicSpeaking": false,
+        "chatAnnounceBuddyTyping": false,
+        "messagesAreDetailed": true,
+        "speakProgressBarUpdates": true,
+        "speakCellCoordinates": true,
+        "enableAlphabeticKeys": true,
+        "enableBraille": false,
+        "brailleAlignmentStyle": 0,
+        "playSoundForPositionInSet": false,
+        "sayAllStyle": 1,
+        "enableEchoBySentence": false,
+        "chatSpeakRoomName": false,
+        "soundVolume": 0.5,
+        "activeProfile": [
+            "Default",
+            "default"
+        ],
+        "brailleVerbosityLevel": 1,
+        "sayAllContextTable": true,
+        "enableTutorialMessages": false,
+        "wrappedStructuralNavigation": true,
+        "capitalizationStyle": "none",
+        "findResultsMinimumLength": 4,
+        "enableContractedBraille": false,
+        "presentDateFormat": "%x",
+        "enableSpeechIndentation": false,
+        "brailleContractionTable": "",
+        "structNavTriggersFocusMode": false,
+        "enablePauseBreaks": true,
+        "speakNumbersAsDigits": false,
+        "spellcheckSpellError": true,
+        "useColorNames": true,
+        "speakContextTable": false,
+        "readFullRowInGUITable": true,
+        "enabledBrailledTextAttributes": "size:; family-name:; weight:400; indent:0; underline:none; 
strikethrough:false; justification:left; style:normal; text-spelling:none;",
+        "enableSpace": true,
+        "brailleSelectorIndicator": 192,
+        "profile": [
+            "Default",
+            "default"
+        ],
+        "verbalizePunctuationStyle": 1,
+        "enableBrailleContext": true,
+        "enableNavigationKeys": false,
+        "structNavInSayAll": false,
+        "enableSound": true,
+        "speakCellSpan": true,
+        "speechVerbosityLevel": 1,
+        "brailleRolenameStyle": 1,
+        "mouseDwellDelay": null,
+        "enableSpeech": true,
+        "caretNavTriggersFocusMode": false,
+        "enableDiacriticalKeys": false,
+        "findResultsVerbosity": 2,
+        "sayAllContextBlockquote": true,
+        "speakBlankLines": true,
+        "speakSpreadsheetCoordinates": true,
+        "flashIsPersistent": false,
+        "enableNumericKeys": true,
+        "enableFlashMessages": true,
+        "progressBarVerbosity": 1,
+        "brailleLinkIndicator": 192,
+        "presentTimeFormat": "%X",
+        "enablePunctuationKeys": true,
+        "enableKeyEcho": false,
+        "playSoundForState": false,
+        "beepProgressBarUpdates": false,
+        "enableFunctionKeys": true,
+        "speakMisspelledIndicator": true,
+        "textAttributesBrailleIndicator": 0,
+        "voices": {
+            "default": {
+                "established": false
+            },
+            "system": {
+                "average-pitch": 3.0
+            },
+            "uppercase": {
+                "average-pitch": 7.0
+            },
+            "hyperlink": {
+                "established": false
+            }
+        },
+        "enableBrailleMonitor": true,
+        "layoutMode": true,
+        "brailleFlashTime": 5000,
+        "largeObjectTextLength": 75,
+        "speakContextList": false,
+        "ignoreStatusBarProgressBars": true,
+        "keyboardLayout": 1,
+        "brailleProgressBarUpdates": false,
+        "readFullRowInSpreadSheet": false,
+        "enableActionKeys": true,
+        "enablePositionSpeaking": false,
+        "structuralNavigationEnabled": true,
+        "playSoundForRole": false,
+        "disableBrailleEOL": false,
+        "presentToolTips": false,
+        "enableMouseReview": false,
+        "speechServerFactory": "speechdispatcherfactory",
+        "chatMessageVerbosity": 0,
+        "enableEchoByWord": false,
+        "spellcheckSpellSuggestion": true,
+        "enableModifierKeys": true,
+        "speakMultiCaseStringsAsWords": false,
+        "flashIsDetailed": true,
+        "speakCellHeaders": true,
+        "rewindAndFastForwardInSayAll": false,
+        "sayAllContextList": true,
+        "speakContextBlockquote": false,
+        "enableEchoByCharacter": false,
+        "playSoundForValue": false,
+        "progressBarUpdateInterval": 10,
+        "spellcheckPresentContext": true,
+        "speechServerInfo": null,
+        "chatRoomHistories": false,
+        "readFullRowInDocumentTable": true,
+        "startingProfile": [
+            "Default",
+            "default"
+        ]
+    },
+    "keybindings": {},
+    "profiles": {
+        "default": {
+            "profile": [
+                "Default",
+                "default"
+            ],
+            "brailleContractionTable": "/usr/share/liblouis/tables/en-us-compbrl.ctb",
+            "voices": {
+                "default": {
+                    "established": false
+                },
+                "system": {
+                    "average-pitch": 3.0
+                },
+                "uppercase": {
+                    "average-pitch": 7.0
+                },
+                "hyperlink": {
+                    "established": false
+                }
+            },
+            "pronunciations": {},
+            "speechServerInfo": [
+                "Default Synthesizer",
+                "default"
+            ],
+            "keybindings": {},
+            "speechServerFactory": "orca.speechdispatcherfactory"
+        }
+    },
+    "pronunciations": {}
+}
\ No newline at end of file
diff --git a/test/keystrokes/firefox/say_all_multi_line_text_no_context.params 
b/test/keystrokes/firefox/say_all_multi_line_text_no_context.params
new file mode 100644
index 0000000..815c992
--- /dev/null
+++ b/test/keystrokes/firefox/say_all_multi_line_text_no_context.params
@@ -0,0 +1 @@
+PARAMS=$TEST_DIR/../../html/multi-line.html
diff --git a/test/keystrokes/firefox/say_all_multi_line_text_no_context.py 
b/test/keystrokes/firefox/say_all_multi_line_text_no_context.py
new file mode 100644
index 0000000..d8a7f4f
--- /dev/null
+++ b/test/keystrokes/firefox/say_all_multi_line_text_no_context.py
@@ -0,0 +1,63 @@
+#!/usr/bin/python
+
+"""Test of sayAll."""
+
+from macaroon.playback import *
+import utils
+
+sequence = MacroSequence()
+
+#sequence.append(WaitForDocLoad())
+sequence.append(PauseAction(5000))
+sequence.append(KeyComboAction("<Control>Home"))
+
+sequence.append(utils.StartRecordingAction())
+sequence.append(KeyComboAction("KP_Add"))
+sequence.append(utils.AssertPresentationAction(
+    "1. KP_Add to do a SayAll",
+    ["SPEECH OUTPUT: 'Table test'",
+     "SPEECH OUTPUT: 'foo'",
+     "SPEECH OUTPUT: 'bar'",
+     "SPEECH OUTPUT: 'foo",
+     "foo'",
+     "SPEECH OUTPUT: 'bar",
+     "bar'",
+     "SPEECH OUTPUT: 'Hello'",
+     "SPEECH OUTPUT: 'heading level 3'",
+     "SPEECH OUTPUT: '•'",
+     "SPEECH OUTPUT: 'This is a test'",
+     "SPEECH OUTPUT: 'link'",
+     "SPEECH OUTPUT: 'that is not very interesting.'",
+     "SPEECH OUTPUT: '•'",
+     "SPEECH OUTPUT: 'But it looks like'",
+     "SPEECH OUTPUT: 'link'",
+     "SPEECH OUTPUT: 'a real-world example.'",
+     "SPEECH OUTPUT: '•'",
+     "SPEECH OUTPUT: 'And that's'",
+     "SPEECH OUTPUT: 'link'",
+     "SPEECH OUTPUT: 'why this silly test is here.'",
+     "SPEECH OUTPUT: 'So it's'",
+     "SPEECH OUTPUT: 'far more interesting'",
+     "SPEECH OUTPUT: 'link'",
+     "SPEECH OUTPUT: 'than it looks.'",
+     "SPEECH OUTPUT: 'World'",
+     "SPEECH OUTPUT: 'heading level 3'",
+     "SPEECH OUTPUT: '•'",
+     "SPEECH OUTPUT: 'The thing is'",
+     "SPEECH OUTPUT: 'link'",
+     "SPEECH OUTPUT: 'we can't copy content.'",
+     "SPEECH OUTPUT: '•'",
+     "SPEECH OUTPUT: 'So we must'",
+     "SPEECH OUTPUT: 'link'",
+     "SPEECH OUTPUT: 'create silly tests.'",
+     "SPEECH OUTPUT: '•'",
+     "SPEECH OUTPUT: 'Oh'",
+     "SPEECH OUTPUT: 'link'",
+     "SPEECH OUTPUT: 'well.'",
+     "SPEECH OUTPUT: 'At least it's'",
+     "SPEECH OUTPUT: 'over'",
+     "SPEECH OUTPUT: 'link'",
+     "SPEECH OUTPUT: '.'"]))
+
+sequence.append(utils.AssertionSummaryAction())
+sequence.start()
diff --git a/test/keystrokes/firefox/say_all_multi_line_text_no_context.settings 
b/test/keystrokes/firefox/say_all_multi_line_text_no_context.settings
new file mode 100644
index 0000000..e6a6d5c
--- /dev/null
+++ b/test/keystrokes/firefox/say_all_multi_line_text_no_context.settings
@@ -0,0 +1,165 @@
+{
+    "general": {
+        "enabledSpokenTextAttributes": "size:; family-name:; weight:400; indent:0; underline:none; 
strikethrough:false; justification:left; style:normal; paragraph-style:; text-spelling:none; fg-color:; 
bg-color:;",
+        "orcaModifierKeys": [
+            "Insert",
+            "KP_Insert"
+        ],
+        "skipBlankCells": false,
+        "onlySpeakDisplayedText": false,
+        "enableMnemonicSpeaking": false,
+        "chatAnnounceBuddyTyping": false,
+        "messagesAreDetailed": true,
+        "speakProgressBarUpdates": true,
+        "speakCellCoordinates": true,
+        "enableAlphabeticKeys": true,
+        "enableBraille": false,
+        "brailleAlignmentStyle": 0,
+        "playSoundForPositionInSet": false,
+        "sayAllStyle": 1,
+        "enableEchoBySentence": false,
+        "chatSpeakRoomName": false,
+        "soundVolume": 0.5,
+        "activeProfile": [
+            "Default",
+            "default"
+        ],
+        "brailleVerbosityLevel": 1,
+        "sayAllContextTable": false,
+        "enableTutorialMessages": false,
+        "wrappedStructuralNavigation": true,
+        "capitalizationStyle": "none",
+        "findResultsMinimumLength": 4,
+        "enableContractedBraille": false,
+        "presentDateFormat": "%x",
+        "enableSpeechIndentation": false,
+        "brailleContractionTable": "",
+        "structNavTriggersFocusMode": false,
+        "enablePauseBreaks": true,
+        "speakNumbersAsDigits": false,
+        "spellcheckSpellError": true,
+        "useColorNames": true,
+        "speakContextTable": false,
+        "readFullRowInGUITable": true,
+        "enabledBrailledTextAttributes": "size:; family-name:; weight:400; indent:0; underline:none; 
strikethrough:false; justification:left; style:normal; text-spelling:none;",
+        "enableSpace": true,
+        "brailleSelectorIndicator": 192,
+        "profile": [
+            "Default",
+            "default"
+        ],
+        "verbalizePunctuationStyle": 1,
+        "enableBrailleContext": true,
+        "enableNavigationKeys": false,
+        "structNavInSayAll": false,
+        "enableSound": true,
+        "speakCellSpan": true,
+        "speechVerbosityLevel": 1,
+        "brailleRolenameStyle": 1,
+        "mouseDwellDelay": null,
+        "enableSpeech": true,
+        "caretNavTriggersFocusMode": false,
+        "enableDiacriticalKeys": false,
+        "findResultsVerbosity": 2,
+        "sayAllContextBlockquote": false,
+        "speakBlankLines": true,
+        "speakSpreadsheetCoordinates": true,
+        "flashIsPersistent": false,
+        "enableNumericKeys": true,
+        "enableFlashMessages": true,
+        "progressBarVerbosity": 1,
+        "brailleLinkIndicator": 192,
+        "presentTimeFormat": "%X",
+        "enablePunctuationKeys": true,
+        "enableKeyEcho": false,
+        "playSoundForState": false,
+        "beepProgressBarUpdates": false,
+        "enableFunctionKeys": true,
+        "speakMisspelledIndicator": true,
+        "textAttributesBrailleIndicator": 0,
+        "voices": {
+            "default": {
+                "established": false
+            },
+            "system": {
+                "average-pitch": 3.0
+            },
+            "uppercase": {
+                "average-pitch": 7.0
+            },
+            "hyperlink": {
+                "established": false
+            }
+        },
+        "enableBrailleMonitor": true,
+        "layoutMode": true,
+        "brailleFlashTime": 5000,
+        "largeObjectTextLength": 75,
+        "speakContextList": false,
+        "ignoreStatusBarProgressBars": true,
+        "keyboardLayout": 1,
+        "brailleProgressBarUpdates": false,
+        "readFullRowInSpreadSheet": false,
+        "enableActionKeys": true,
+        "enablePositionSpeaking": false,
+        "structuralNavigationEnabled": true,
+        "playSoundForRole": false,
+        "disableBrailleEOL": false,
+        "presentToolTips": false,
+        "enableMouseReview": false,
+        "speechServerFactory": "speechdispatcherfactory",
+        "chatMessageVerbosity": 0,
+        "enableEchoByWord": false,
+        "spellcheckSpellSuggestion": true,
+        "enableModifierKeys": true,
+        "speakMultiCaseStringsAsWords": false,
+        "flashIsDetailed": true,
+        "speakCellHeaders": true,
+        "rewindAndFastForwardInSayAll": false,
+        "sayAllContextList": false,
+        "speakContextBlockquote": false,
+        "enableEchoByCharacter": false,
+        "playSoundForValue": false,
+        "progressBarUpdateInterval": 10,
+        "spellcheckPresentContext": true,
+        "speechServerInfo": null,
+        "chatRoomHistories": false,
+        "readFullRowInDocumentTable": true,
+        "startingProfile": [
+            "Default",
+            "default"
+        ]
+    },
+    "keybindings": {},
+    "profiles": {
+        "default": {
+            "profile": [
+                "Default",
+                "default"
+            ],
+            "brailleContractionTable": "/usr/share/liblouis/tables/en-us-compbrl.ctb",
+            "voices": {
+                "default": {
+                    "established": false
+                },
+                "system": {
+                    "average-pitch": 3.0
+                },
+                "uppercase": {
+                    "average-pitch": 7.0
+                },
+                "hyperlink": {
+                    "established": false
+                }
+            },
+            "pronunciations": {},
+            "speechServerInfo": [
+                "Default Synthesizer",
+                "default"
+            ],
+            "keybindings": {},
+            "speechServerFactory": "orca.speechdispatcherfactory"
+        }
+    },
+    "pronunciations": {}
+}
\ No newline at end of file
diff --git a/test/keystrokes/firefox/say_all_nested_tables.py 
b/test/keystrokes/firefox/say_all_nested_tables.py
index 8a44761..7ea4126 100644
--- a/test/keystrokes/firefox/say_all_nested_tables.py
+++ b/test/keystrokes/firefox/say_all_nested_tables.py
@@ -15,7 +15,6 @@ sequence.append(KeyComboAction("KP_Add"))
 sequence.append(utils.AssertPresentationAction(
     "1. KP_Add to do a SayAll",
     ["SPEECH OUTPUT: 'nested-tables'",
-     "SPEECH OUTPUT: 'image'",
      "SPEECH OUTPUT: 'visited link'",
      "SPEECH OUTPUT: 'Campus'",
      "SPEECH OUTPUT: 'link'",
diff --git a/test/keystrokes/firefox/say_all_nested_tables.settings 
b/test/keystrokes/firefox/say_all_nested_tables.settings
new file mode 100644
index 0000000..6d6a48a
--- /dev/null
+++ b/test/keystrokes/firefox/say_all_nested_tables.settings
@@ -0,0 +1,165 @@
+{
+    "general": {
+        "enabledSpokenTextAttributes": "size:; family-name:; weight:400; indent:0; underline:none; 
strikethrough:false; justification:left; style:normal; paragraph-style:; text-spelling:none; fg-color:; 
bg-color:;",
+        "orcaModifierKeys": [
+            "Insert",
+            "KP_Insert"
+        ],
+        "skipBlankCells": false,
+        "onlySpeakDisplayedText": false,
+        "enableMnemonicSpeaking": false,
+        "chatAnnounceBuddyTyping": false,
+        "messagesAreDetailed": true,
+        "speakProgressBarUpdates": true,
+        "speakCellCoordinates": true,
+        "enableAlphabeticKeys": true,
+        "enableBraille": false,
+        "brailleAlignmentStyle": 0,
+        "playSoundForPositionInSet": false,
+        "sayAllStyle": 1,
+        "enableEchoBySentence": false,
+        "chatSpeakRoomName": false,
+        "soundVolume": 0.5,
+        "activeProfile": [
+            "Default",
+            "default"
+        ],
+        "brailleVerbosityLevel": 1,
+        "sayAllContextTable": true,
+        "enableTutorialMessages": false,
+        "wrappedStructuralNavigation": true,
+        "capitalizationStyle": "none",
+        "findResultsMinimumLength": 4,
+        "enableContractedBraille": false,
+        "presentDateFormat": "%x",
+        "enableSpeechIndentation": false,
+        "brailleContractionTable": "",
+        "structNavTriggersFocusMode": false,
+        "enablePauseBreaks": true,
+        "speakNumbersAsDigits": false,
+        "spellcheckSpellError": true,
+        "useColorNames": true,
+        "speakContextTable": false,
+        "readFullRowInGUITable": true,
+        "enabledBrailledTextAttributes": "size:; family-name:; weight:400; indent:0; underline:none; 
strikethrough:false; justification:left; style:normal; text-spelling:none;",
+        "enableSpace": true,
+        "brailleSelectorIndicator": 192,
+        "profile": [
+            "Default",
+            "default"
+        ],
+        "verbalizePunctuationStyle": 1,
+        "enableBrailleContext": true,
+        "enableNavigationKeys": false,
+        "structNavInSayAll": false,
+        "enableSound": true,
+        "speakCellSpan": true,
+        "speechVerbosityLevel": 1,
+        "brailleRolenameStyle": 1,
+        "mouseDwellDelay": null,
+        "enableSpeech": true,
+        "caretNavTriggersFocusMode": false,
+        "enableDiacriticalKeys": false,
+        "findResultsVerbosity": 2,
+        "sayAllContextBlockquote": true,
+        "speakBlankLines": true,
+        "speakSpreadsheetCoordinates": true,
+        "flashIsPersistent": false,
+        "enableNumericKeys": true,
+        "enableFlashMessages": true,
+        "progressBarVerbosity": 1,
+        "brailleLinkIndicator": 192,
+        "presentTimeFormat": "%X",
+        "enablePunctuationKeys": true,
+        "enableKeyEcho": false,
+        "playSoundForState": false,
+        "beepProgressBarUpdates": false,
+        "enableFunctionKeys": true,
+        "speakMisspelledIndicator": true,
+        "textAttributesBrailleIndicator": 0,
+        "voices": {
+            "default": {
+                "established": false
+            },
+            "system": {
+                "average-pitch": 3.0
+            },
+            "uppercase": {
+                "average-pitch": 7.0
+            },
+            "hyperlink": {
+                "established": false
+            }
+        },
+        "enableBrailleMonitor": true,
+        "layoutMode": true,
+        "brailleFlashTime": 5000,
+        "largeObjectTextLength": 75,
+        "speakContextList": false,
+        "ignoreStatusBarProgressBars": true,
+        "keyboardLayout": 1,
+        "brailleProgressBarUpdates": false,
+        "readFullRowInSpreadSheet": false,
+        "enableActionKeys": true,
+        "enablePositionSpeaking": false,
+        "structuralNavigationEnabled": true,
+        "playSoundForRole": false,
+        "disableBrailleEOL": false,
+        "presentToolTips": false,
+        "enableMouseReview": false,
+        "speechServerFactory": "speechdispatcherfactory",
+        "chatMessageVerbosity": 0,
+        "enableEchoByWord": false,
+        "spellcheckSpellSuggestion": true,
+        "enableModifierKeys": true,
+        "speakMultiCaseStringsAsWords": false,
+        "flashIsDetailed": true,
+        "speakCellHeaders": true,
+        "rewindAndFastForwardInSayAll": false,
+        "sayAllContextList": true,
+        "speakContextBlockquote": false,
+        "enableEchoByCharacter": false,
+        "playSoundForValue": false,
+        "progressBarUpdateInterval": 10,
+        "spellcheckPresentContext": true,
+        "speechServerInfo": null,
+        "chatRoomHistories": false,
+        "readFullRowInDocumentTable": true,
+        "startingProfile": [
+            "Default",
+            "default"
+        ]
+    },
+    "keybindings": {},
+    "profiles": {
+        "default": {
+            "profile": [
+                "Default",
+                "default"
+            ],
+            "brailleContractionTable": "/usr/share/liblouis/tables/en-us-compbrl.ctb",
+            "voices": {
+                "default": {
+                    "established": false
+                },
+                "system": {
+                    "average-pitch": 3.0
+                },
+                "uppercase": {
+                    "average-pitch": 7.0
+                },
+                "hyperlink": {
+                    "established": false
+                }
+            },
+            "pronunciations": {},
+            "speechServerInfo": [
+                "Default Synthesizer",
+                "default"
+            ],
+            "keybindings": {},
+            "speechServerFactory": "orca.speechdispatcherfactory"
+        }
+    },
+    "pronunciations": {}
+}
\ No newline at end of file
diff --git a/test/keystrokes/firefox/say_all_nested_tables_no_context.params 
b/test/keystrokes/firefox/say_all_nested_tables_no_context.params
new file mode 100644
index 0000000..feec66e
--- /dev/null
+++ b/test/keystrokes/firefox/say_all_nested_tables_no_context.params
@@ -0,0 +1 @@
+PARAMS=$TEST_DIR/../../html/nested-tables.html
diff --git a/test/keystrokes/firefox/say_all_nested_tables_no_context.py 
b/test/keystrokes/firefox/say_all_nested_tables_no_context.py
new file mode 100644
index 0000000..7ea4126
--- /dev/null
+++ b/test/keystrokes/firefox/say_all_nested_tables_no_context.py
@@ -0,0 +1,44 @@
+#!/usr/bin/python
+
+"""Test of sayAll."""
+
+from macaroon.playback import *
+import utils
+
+sequence = MacroSequence()
+
+#sequence.append(WaitForDocLoad())
+sequence.append(PauseAction(5000))
+
+sequence.append(utils.StartRecordingAction())
+sequence.append(KeyComboAction("KP_Add"))
+sequence.append(utils.AssertPresentationAction(
+    "1. KP_Add to do a SayAll",
+    ["SPEECH OUTPUT: 'nested-tables'",
+     "SPEECH OUTPUT: 'visited link'",
+     "SPEECH OUTPUT: 'Campus'",
+     "SPEECH OUTPUT: 'link'",
+     "SPEECH OUTPUT: '.'",
+     "SPEECH OUTPUT: 'Classroom'",
+     "SPEECH OUTPUT: 'link'",
+     "SPEECH OUTPUT: '.'",
+     "SPEECH OUTPUT: 'Communicate'",
+     "SPEECH OUTPUT: 'link'",
+     "SPEECH OUTPUT: '.'",
+     "SPEECH OUTPUT: 'Reports'",
+     "SPEECH OUTPUT: 'link'",
+     "SPEECH OUTPUT: 'Your Learning Plan'",
+     "SPEECH OUTPUT: 'Below is a list of the courses that make up your learning plan.'",
+     "SPEECH OUTPUT: 'UNIX 2007'",
+     "SPEECH OUTPUT: 'Take Course'",
+     "SPEECH OUTPUT: 'link'",
+     "SPEECH OUTPUT: 'You have completed 87 of the 87 modules in this course.'",
+     "SPEECH OUTPUT: 'separator'",
+     "SPEECH OUTPUT: 'SQL Plus'",
+     "SPEECH OUTPUT: 'Take Course'",
+     "SPEECH OUTPUT: 'link'",
+     "SPEECH OUTPUT: 'You have completed 59 of the 184 modules in this course.'",
+     "SPEECH OUTPUT: 'separator'"]))
+
+sequence.append(utils.AssertionSummaryAction())
+sequence.start()
diff --git a/test/keystrokes/firefox/say_all_nested_tables_no_context.settings 
b/test/keystrokes/firefox/say_all_nested_tables_no_context.settings
new file mode 100644
index 0000000..e6a6d5c
--- /dev/null
+++ b/test/keystrokes/firefox/say_all_nested_tables_no_context.settings
@@ -0,0 +1,165 @@
+{
+    "general": {
+        "enabledSpokenTextAttributes": "size:; family-name:; weight:400; indent:0; underline:none; 
strikethrough:false; justification:left; style:normal; paragraph-style:; text-spelling:none; fg-color:; 
bg-color:;",
+        "orcaModifierKeys": [
+            "Insert",
+            "KP_Insert"
+        ],
+        "skipBlankCells": false,
+        "onlySpeakDisplayedText": false,
+        "enableMnemonicSpeaking": false,
+        "chatAnnounceBuddyTyping": false,
+        "messagesAreDetailed": true,
+        "speakProgressBarUpdates": true,
+        "speakCellCoordinates": true,
+        "enableAlphabeticKeys": true,
+        "enableBraille": false,
+        "brailleAlignmentStyle": 0,
+        "playSoundForPositionInSet": false,
+        "sayAllStyle": 1,
+        "enableEchoBySentence": false,
+        "chatSpeakRoomName": false,
+        "soundVolume": 0.5,
+        "activeProfile": [
+            "Default",
+            "default"
+        ],
+        "brailleVerbosityLevel": 1,
+        "sayAllContextTable": false,
+        "enableTutorialMessages": false,
+        "wrappedStructuralNavigation": true,
+        "capitalizationStyle": "none",
+        "findResultsMinimumLength": 4,
+        "enableContractedBraille": false,
+        "presentDateFormat": "%x",
+        "enableSpeechIndentation": false,
+        "brailleContractionTable": "",
+        "structNavTriggersFocusMode": false,
+        "enablePauseBreaks": true,
+        "speakNumbersAsDigits": false,
+        "spellcheckSpellError": true,
+        "useColorNames": true,
+        "speakContextTable": false,
+        "readFullRowInGUITable": true,
+        "enabledBrailledTextAttributes": "size:; family-name:; weight:400; indent:0; underline:none; 
strikethrough:false; justification:left; style:normal; text-spelling:none;",
+        "enableSpace": true,
+        "brailleSelectorIndicator": 192,
+        "profile": [
+            "Default",
+            "default"
+        ],
+        "verbalizePunctuationStyle": 1,
+        "enableBrailleContext": true,
+        "enableNavigationKeys": false,
+        "structNavInSayAll": false,
+        "enableSound": true,
+        "speakCellSpan": true,
+        "speechVerbosityLevel": 1,
+        "brailleRolenameStyle": 1,
+        "mouseDwellDelay": null,
+        "enableSpeech": true,
+        "caretNavTriggersFocusMode": false,
+        "enableDiacriticalKeys": false,
+        "findResultsVerbosity": 2,
+        "sayAllContextBlockquote": false,
+        "speakBlankLines": true,
+        "speakSpreadsheetCoordinates": true,
+        "flashIsPersistent": false,
+        "enableNumericKeys": true,
+        "enableFlashMessages": true,
+        "progressBarVerbosity": 1,
+        "brailleLinkIndicator": 192,
+        "presentTimeFormat": "%X",
+        "enablePunctuationKeys": true,
+        "enableKeyEcho": false,
+        "playSoundForState": false,
+        "beepProgressBarUpdates": false,
+        "enableFunctionKeys": true,
+        "speakMisspelledIndicator": true,
+        "textAttributesBrailleIndicator": 0,
+        "voices": {
+            "default": {
+                "established": false
+            },
+            "system": {
+                "average-pitch": 3.0
+            },
+            "uppercase": {
+                "average-pitch": 7.0
+            },
+            "hyperlink": {
+                "established": false
+            }
+        },
+        "enableBrailleMonitor": true,
+        "layoutMode": true,
+        "brailleFlashTime": 5000,
+        "largeObjectTextLength": 75,
+        "speakContextList": false,
+        "ignoreStatusBarProgressBars": true,
+        "keyboardLayout": 1,
+        "brailleProgressBarUpdates": false,
+        "readFullRowInSpreadSheet": false,
+        "enableActionKeys": true,
+        "enablePositionSpeaking": false,
+        "structuralNavigationEnabled": true,
+        "playSoundForRole": false,
+        "disableBrailleEOL": false,
+        "presentToolTips": false,
+        "enableMouseReview": false,
+        "speechServerFactory": "speechdispatcherfactory",
+        "chatMessageVerbosity": 0,
+        "enableEchoByWord": false,
+        "spellcheckSpellSuggestion": true,
+        "enableModifierKeys": true,
+        "speakMultiCaseStringsAsWords": false,
+        "flashIsDetailed": true,
+        "speakCellHeaders": true,
+        "rewindAndFastForwardInSayAll": false,
+        "sayAllContextList": false,
+        "speakContextBlockquote": false,
+        "enableEchoByCharacter": false,
+        "playSoundForValue": false,
+        "progressBarUpdateInterval": 10,
+        "spellcheckPresentContext": true,
+        "speechServerInfo": null,
+        "chatRoomHistories": false,
+        "readFullRowInDocumentTable": true,
+        "startingProfile": [
+            "Default",
+            "default"
+        ]
+    },
+    "keybindings": {},
+    "profiles": {
+        "default": {
+            "profile": [
+                "Default",
+                "default"
+            ],
+            "brailleContractionTable": "/usr/share/liblouis/tables/en-us-compbrl.ctb",
+            "voices": {
+                "default": {
+                    "established": false
+                },
+                "system": {
+                    "average-pitch": 3.0
+                },
+                "uppercase": {
+                    "average-pitch": 7.0
+                },
+                "hyperlink": {
+                    "established": false
+                }
+            },
+            "pronunciations": {},
+            "speechServerInfo": [
+                "Default Synthesizer",
+                "default"
+            ],
+            "keybindings": {},
+            "speechServerFactory": "orca.speechdispatcherfactory"
+        }
+    },
+    "pronunciations": {}
+}
\ No newline at end of file
diff --git a/test/keystrokes/firefox/say_all_role_links.py b/test/keystrokes/firefox/say_all_role_links.py
index c9c8193..42e9c22 100644
--- a/test/keystrokes/firefox/say_all_role_links.py
+++ b/test/keystrokes/firefox/say_all_role_links.py
@@ -15,6 +15,7 @@ sequence.append(KeyComboAction("KP_Add"))
 sequence.append(utils.AssertPresentationAction(
     "1. KP_Add to do a SayAll",
     ["SPEECH OUTPUT: 'Here are some of our local test files:'",
+     "SPEECH OUTPUT: 'List with 16 items'",
      "SPEECH OUTPUT: '•'",
      "SPEECH OUTPUT: 'anchors.html'",
      "SPEECH OUTPUT: 'link'",
diff --git a/test/keystrokes/firefox/say_all_role_links.settings 
b/test/keystrokes/firefox/say_all_role_links.settings
new file mode 100644
index 0000000..6d6a48a
--- /dev/null
+++ b/test/keystrokes/firefox/say_all_role_links.settings
@@ -0,0 +1,165 @@
+{
+    "general": {
+        "enabledSpokenTextAttributes": "size:; family-name:; weight:400; indent:0; underline:none; 
strikethrough:false; justification:left; style:normal; paragraph-style:; text-spelling:none; fg-color:; 
bg-color:;",
+        "orcaModifierKeys": [
+            "Insert",
+            "KP_Insert"
+        ],
+        "skipBlankCells": false,
+        "onlySpeakDisplayedText": false,
+        "enableMnemonicSpeaking": false,
+        "chatAnnounceBuddyTyping": false,
+        "messagesAreDetailed": true,
+        "speakProgressBarUpdates": true,
+        "speakCellCoordinates": true,
+        "enableAlphabeticKeys": true,
+        "enableBraille": false,
+        "brailleAlignmentStyle": 0,
+        "playSoundForPositionInSet": false,
+        "sayAllStyle": 1,
+        "enableEchoBySentence": false,
+        "chatSpeakRoomName": false,
+        "soundVolume": 0.5,
+        "activeProfile": [
+            "Default",
+            "default"
+        ],
+        "brailleVerbosityLevel": 1,
+        "sayAllContextTable": true,
+        "enableTutorialMessages": false,
+        "wrappedStructuralNavigation": true,
+        "capitalizationStyle": "none",
+        "findResultsMinimumLength": 4,
+        "enableContractedBraille": false,
+        "presentDateFormat": "%x",
+        "enableSpeechIndentation": false,
+        "brailleContractionTable": "",
+        "structNavTriggersFocusMode": false,
+        "enablePauseBreaks": true,
+        "speakNumbersAsDigits": false,
+        "spellcheckSpellError": true,
+        "useColorNames": true,
+        "speakContextTable": false,
+        "readFullRowInGUITable": true,
+        "enabledBrailledTextAttributes": "size:; family-name:; weight:400; indent:0; underline:none; 
strikethrough:false; justification:left; style:normal; text-spelling:none;",
+        "enableSpace": true,
+        "brailleSelectorIndicator": 192,
+        "profile": [
+            "Default",
+            "default"
+        ],
+        "verbalizePunctuationStyle": 1,
+        "enableBrailleContext": true,
+        "enableNavigationKeys": false,
+        "structNavInSayAll": false,
+        "enableSound": true,
+        "speakCellSpan": true,
+        "speechVerbosityLevel": 1,
+        "brailleRolenameStyle": 1,
+        "mouseDwellDelay": null,
+        "enableSpeech": true,
+        "caretNavTriggersFocusMode": false,
+        "enableDiacriticalKeys": false,
+        "findResultsVerbosity": 2,
+        "sayAllContextBlockquote": true,
+        "speakBlankLines": true,
+        "speakSpreadsheetCoordinates": true,
+        "flashIsPersistent": false,
+        "enableNumericKeys": true,
+        "enableFlashMessages": true,
+        "progressBarVerbosity": 1,
+        "brailleLinkIndicator": 192,
+        "presentTimeFormat": "%X",
+        "enablePunctuationKeys": true,
+        "enableKeyEcho": false,
+        "playSoundForState": false,
+        "beepProgressBarUpdates": false,
+        "enableFunctionKeys": true,
+        "speakMisspelledIndicator": true,
+        "textAttributesBrailleIndicator": 0,
+        "voices": {
+            "default": {
+                "established": false
+            },
+            "system": {
+                "average-pitch": 3.0
+            },
+            "uppercase": {
+                "average-pitch": 7.0
+            },
+            "hyperlink": {
+                "established": false
+            }
+        },
+        "enableBrailleMonitor": true,
+        "layoutMode": true,
+        "brailleFlashTime": 5000,
+        "largeObjectTextLength": 75,
+        "speakContextList": false,
+        "ignoreStatusBarProgressBars": true,
+        "keyboardLayout": 1,
+        "brailleProgressBarUpdates": false,
+        "readFullRowInSpreadSheet": false,
+        "enableActionKeys": true,
+        "enablePositionSpeaking": false,
+        "structuralNavigationEnabled": true,
+        "playSoundForRole": false,
+        "disableBrailleEOL": false,
+        "presentToolTips": false,
+        "enableMouseReview": false,
+        "speechServerFactory": "speechdispatcherfactory",
+        "chatMessageVerbosity": 0,
+        "enableEchoByWord": false,
+        "spellcheckSpellSuggestion": true,
+        "enableModifierKeys": true,
+        "speakMultiCaseStringsAsWords": false,
+        "flashIsDetailed": true,
+        "speakCellHeaders": true,
+        "rewindAndFastForwardInSayAll": false,
+        "sayAllContextList": true,
+        "speakContextBlockquote": false,
+        "enableEchoByCharacter": false,
+        "playSoundForValue": false,
+        "progressBarUpdateInterval": 10,
+        "spellcheckPresentContext": true,
+        "speechServerInfo": null,
+        "chatRoomHistories": false,
+        "readFullRowInDocumentTable": true,
+        "startingProfile": [
+            "Default",
+            "default"
+        ]
+    },
+    "keybindings": {},
+    "profiles": {
+        "default": {
+            "profile": [
+                "Default",
+                "default"
+            ],
+            "brailleContractionTable": "/usr/share/liblouis/tables/en-us-compbrl.ctb",
+            "voices": {
+                "default": {
+                    "established": false
+                },
+                "system": {
+                    "average-pitch": 3.0
+                },
+                "uppercase": {
+                    "average-pitch": 7.0
+                },
+                "hyperlink": {
+                    "established": false
+                }
+            },
+            "pronunciations": {},
+            "speechServerInfo": [
+                "Default Synthesizer",
+                "default"
+            ],
+            "keybindings": {},
+            "speechServerFactory": "orca.speechdispatcherfactory"
+        }
+    },
+    "pronunciations": {}
+}
\ No newline at end of file
diff --git a/test/keystrokes/firefox/say_all_role_links_no_context.params 
b/test/keystrokes/firefox/say_all_role_links_no_context.params
new file mode 100644
index 0000000..6041395
--- /dev/null
+++ b/test/keystrokes/firefox/say_all_role_links_no_context.params
@@ -0,0 +1 @@
+PARAMS=$TEST_DIR/../../html/anchors2.html
diff --git a/test/keystrokes/firefox/say_all_role_links_no_context.py 
b/test/keystrokes/firefox/say_all_role_links_no_context.py
new file mode 100644
index 0000000..c9c8193
--- /dev/null
+++ b/test/keystrokes/firefox/say_all_role_links_no_context.py
@@ -0,0 +1,68 @@
+#!/usr/bin/python
+
+"""Test of sayAll."""
+
+from macaroon.playback import *
+import utils
+
+sequence = MacroSequence()
+
+#sequence.append(WaitForDocLoad())
+sequence.append(PauseAction(5000))
+
+sequence.append(utils.StartRecordingAction())
+sequence.append(KeyComboAction("KP_Add"))
+sequence.append(utils.AssertPresentationAction(
+    "1. KP_Add to do a SayAll",
+    ["SPEECH OUTPUT: 'Here are some of our local test files:'",
+     "SPEECH OUTPUT: '•'",
+     "SPEECH OUTPUT: 'anchors.html'",
+     "SPEECH OUTPUT: 'link'",
+     "SPEECH OUTPUT: '•'",
+     "SPEECH OUTPUT: 'blockquotes.html'",
+     "SPEECH OUTPUT: 'link'",
+     "SPEECH OUTPUT: '•'",
+     "SPEECH OUTPUT: 'bugzilla_top.html'",
+     "SPEECH OUTPUT: 'link'",
+     "SPEECH OUTPUT: '•'",
+     "SPEECH OUTPUT: 'combobox.html'",
+     "SPEECH OUTPUT: 'link'",
+     "SPEECH OUTPUT: '•'",
+     "SPEECH OUTPUT: 'fieldset.html'",
+     "SPEECH OUTPUT: 'link'",
+     "SPEECH OUTPUT: '•'",
+     "SPEECH OUTPUT: 'htmlpage.html'",
+     "SPEECH OUTPUT: 'link'",
+     "SPEECH OUTPUT: '•'",
+     "SPEECH OUTPUT: 'image-test.html'",
+     "SPEECH OUTPUT: 'link'",
+     "SPEECH OUTPUT: '•'",
+     "SPEECH OUTPUT: 'linebreak-test.html'",
+     "SPEECH OUTPUT: 'link'",
+     "SPEECH OUTPUT: '•'",
+     "SPEECH OUTPUT: 'lists.html'",
+     "SPEECH OUTPUT: 'link'",
+     "SPEECH OUTPUT: '•'",
+     "SPEECH OUTPUT: 'samesizearea.html'",
+     "SPEECH OUTPUT: 'link'",
+     "SPEECH OUTPUT: '•'",
+     "SPEECH OUTPUT: 'simpleform.html'",
+     "SPEECH OUTPUT: 'link'",
+     "SPEECH OUTPUT: '•'",
+     "SPEECH OUTPUT: 'simpleheader.html'",
+     "SPEECH OUTPUT: 'link'",
+     "SPEECH OUTPUT: '•'",
+     "SPEECH OUTPUT: 'slash-test.html'",
+     "SPEECH OUTPUT: 'link'",
+     "SPEECH OUTPUT: '•'",
+     "SPEECH OUTPUT: 'status-bar.html'",
+     "SPEECH OUTPUT: 'link'",
+     "SPEECH OUTPUT: '•'",
+     "SPEECH OUTPUT: 'tables.html'",
+     "SPEECH OUTPUT: 'link'",
+     "SPEECH OUTPUT: '•'",
+     "SPEECH OUTPUT: 'textattributes.html'",
+     "SPEECH OUTPUT: 'link'"]))
+
+sequence.append(utils.AssertionSummaryAction())
+sequence.start()
diff --git a/test/keystrokes/firefox/say_all_role_links_no_context.settings 
b/test/keystrokes/firefox/say_all_role_links_no_context.settings
new file mode 100644
index 0000000..e6a6d5c
--- /dev/null
+++ b/test/keystrokes/firefox/say_all_role_links_no_context.settings
@@ -0,0 +1,165 @@
+{
+    "general": {
+        "enabledSpokenTextAttributes": "size:; family-name:; weight:400; indent:0; underline:none; 
strikethrough:false; justification:left; style:normal; paragraph-style:; text-spelling:none; fg-color:; 
bg-color:;",
+        "orcaModifierKeys": [
+            "Insert",
+            "KP_Insert"
+        ],
+        "skipBlankCells": false,
+        "onlySpeakDisplayedText": false,
+        "enableMnemonicSpeaking": false,
+        "chatAnnounceBuddyTyping": false,
+        "messagesAreDetailed": true,
+        "speakProgressBarUpdates": true,
+        "speakCellCoordinates": true,
+        "enableAlphabeticKeys": true,
+        "enableBraille": false,
+        "brailleAlignmentStyle": 0,
+        "playSoundForPositionInSet": false,
+        "sayAllStyle": 1,
+        "enableEchoBySentence": false,
+        "chatSpeakRoomName": false,
+        "soundVolume": 0.5,
+        "activeProfile": [
+            "Default",
+            "default"
+        ],
+        "brailleVerbosityLevel": 1,
+        "sayAllContextTable": false,
+        "enableTutorialMessages": false,
+        "wrappedStructuralNavigation": true,
+        "capitalizationStyle": "none",
+        "findResultsMinimumLength": 4,
+        "enableContractedBraille": false,
+        "presentDateFormat": "%x",
+        "enableSpeechIndentation": false,
+        "brailleContractionTable": "",
+        "structNavTriggersFocusMode": false,
+        "enablePauseBreaks": true,
+        "speakNumbersAsDigits": false,
+        "spellcheckSpellError": true,
+        "useColorNames": true,
+        "speakContextTable": false,
+        "readFullRowInGUITable": true,
+        "enabledBrailledTextAttributes": "size:; family-name:; weight:400; indent:0; underline:none; 
strikethrough:false; justification:left; style:normal; text-spelling:none;",
+        "enableSpace": true,
+        "brailleSelectorIndicator": 192,
+        "profile": [
+            "Default",
+            "default"
+        ],
+        "verbalizePunctuationStyle": 1,
+        "enableBrailleContext": true,
+        "enableNavigationKeys": false,
+        "structNavInSayAll": false,
+        "enableSound": true,
+        "speakCellSpan": true,
+        "speechVerbosityLevel": 1,
+        "brailleRolenameStyle": 1,
+        "mouseDwellDelay": null,
+        "enableSpeech": true,
+        "caretNavTriggersFocusMode": false,
+        "enableDiacriticalKeys": false,
+        "findResultsVerbosity": 2,
+        "sayAllContextBlockquote": false,
+        "speakBlankLines": true,
+        "speakSpreadsheetCoordinates": true,
+        "flashIsPersistent": false,
+        "enableNumericKeys": true,
+        "enableFlashMessages": true,
+        "progressBarVerbosity": 1,
+        "brailleLinkIndicator": 192,
+        "presentTimeFormat": "%X",
+        "enablePunctuationKeys": true,
+        "enableKeyEcho": false,
+        "playSoundForState": false,
+        "beepProgressBarUpdates": false,
+        "enableFunctionKeys": true,
+        "speakMisspelledIndicator": true,
+        "textAttributesBrailleIndicator": 0,
+        "voices": {
+            "default": {
+                "established": false
+            },
+            "system": {
+                "average-pitch": 3.0
+            },
+            "uppercase": {
+                "average-pitch": 7.0
+            },
+            "hyperlink": {
+                "established": false
+            }
+        },
+        "enableBrailleMonitor": true,
+        "layoutMode": true,
+        "brailleFlashTime": 5000,
+        "largeObjectTextLength": 75,
+        "speakContextList": false,
+        "ignoreStatusBarProgressBars": true,
+        "keyboardLayout": 1,
+        "brailleProgressBarUpdates": false,
+        "readFullRowInSpreadSheet": false,
+        "enableActionKeys": true,
+        "enablePositionSpeaking": false,
+        "structuralNavigationEnabled": true,
+        "playSoundForRole": false,
+        "disableBrailleEOL": false,
+        "presentToolTips": false,
+        "enableMouseReview": false,
+        "speechServerFactory": "speechdispatcherfactory",
+        "chatMessageVerbosity": 0,
+        "enableEchoByWord": false,
+        "spellcheckSpellSuggestion": true,
+        "enableModifierKeys": true,
+        "speakMultiCaseStringsAsWords": false,
+        "flashIsDetailed": true,
+        "speakCellHeaders": true,
+        "rewindAndFastForwardInSayAll": false,
+        "sayAllContextList": false,
+        "speakContextBlockquote": false,
+        "enableEchoByCharacter": false,
+        "playSoundForValue": false,
+        "progressBarUpdateInterval": 10,
+        "spellcheckPresentContext": true,
+        "speechServerInfo": null,
+        "chatRoomHistories": false,
+        "readFullRowInDocumentTable": true,
+        "startingProfile": [
+            "Default",
+            "default"
+        ]
+    },
+    "keybindings": {},
+    "profiles": {
+        "default": {
+            "profile": [
+                "Default",
+                "default"
+            ],
+            "brailleContractionTable": "/usr/share/liblouis/tables/en-us-compbrl.ctb",
+            "voices": {
+                "default": {
+                    "established": false
+                },
+                "system": {
+                    "average-pitch": 3.0
+                },
+                "uppercase": {
+                    "average-pitch": 7.0
+                },
+                "hyperlink": {
+                    "established": false
+                }
+            },
+            "pronunciations": {},
+            "speechServerInfo": [
+                "Default Synthesizer",
+                "default"
+            ],
+            "keybindings": {},
+            "speechServerFactory": "orca.speechdispatcherfactory"
+        }
+    },
+    "pronunciations": {}
+}
\ No newline at end of file
diff --git a/test/keystrokes/firefox/say_all_role_lists.py b/test/keystrokes/firefox/say_all_role_lists.py
index 735843c..3a73860 100644
--- a/test/keystrokes/firefox/say_all_role_lists.py
+++ b/test/keystrokes/firefox/say_all_role_lists.py
@@ -18,30 +18,47 @@ sequence.append(utils.AssertPresentationAction(
      "SPEECH OUTPUT: 'heading level 1'",
      "SPEECH OUTPUT: 'Lists are not only fun to make, they are fun to use.'",
      "SPEECH OUTPUT: 'They help us:'",
+     "SPEECH OUTPUT: 'List with 4 items'",
      "SPEECH OUTPUT: '1. remember what the heck we are doing each day'",
      "SPEECH OUTPUT: '2. arrange long and arbitrary lines of text into ordered lists that are pleasing to 
the eye and suggest some sense of priority, even if it is artificial'",
      "SPEECH OUTPUT: '3. look really cool when we carry them around on yellow Post-Itstm.'",
      "SPEECH OUTPUT: '4. and that other thing I keep forgetting.'",
+     "SPEECH OUTPUT: 'leaving list.'",
      "SPEECH OUTPUT: 'Your ordered lists can start at a strange number, like:'",
+     "SPEECH OUTPUT: 'List with 6 items'",
      "SPEECH OUTPUT: '6. And use roman numerals,'",
      "SPEECH OUTPUT: 'g. You might try using letters as well,'",
      "SPEECH OUTPUT: 'H. Maybe you prefer Big Letters,'",
      "SPEECH OUTPUT: '9. or small roman numerals'",
      "SPEECH OUTPUT: '• But discs belong to unordered lists'",
      "SPEECH OUTPUT: '50. Though you can set the value in a list item!'",
+     "SPEECH OUTPUT: 'leaving list.'",
      "SPEECH OUTPUT: 'Unordered list:'",
+     "SPEECH OUTPUT: 'List with 2 items'",
      "SPEECH OUTPUT: '• listing item'",
+     "SPEECH OUTPUT: 'List with 2 items'",
      "SPEECH OUTPUT: '◦ first sublevel'",
+     "SPEECH OUTPUT: 'List with 2 items'",
      "SPEECH OUTPUT: '◾ look for the bullet on'",
+     "SPEECH OUTPUT: 'List with 2 items'",
      "SPEECH OUTPUT: '◾ each sublevel'",
      "SPEECH OUTPUT: '◾ they should all be different, except here.'",
+     "SPEECH OUTPUT: 'leaving list.'",
      "SPEECH OUTPUT: '◾ second sublevel'",
+     "SPEECH OUTPUT: 'leaving list.'",
      "SPEECH OUTPUT: '◾ or you can specify a square'",
+     "SPEECH OUTPUT: 'List with 2 items'",
      "SPEECH OUTPUT: '◦ if your TYPE is circle'",
      "SPEECH OUTPUT: '• or even a disc'",
+     "SPEECH OUTPUT: 'leaving list.'",
+     "SPEECH OUTPUT: 'leaving list.'",
      "SPEECH OUTPUT: '◾ Franz Liszt'",
+     "SPEECH OUTPUT: 'List with 2 items'",
      "SPEECH OUTPUT: '◦ was a composer who was not square'",
      "SPEECH OUTPUT: '• would have liked the Who'",
+     "SPEECH OUTPUT: 'leaving list.'",
+     "SPEECH OUTPUT: 'leaving list.'",
+     "SPEECH OUTPUT: 'List with 3 items'",
      "SPEECH OUTPUT: '◦ feeling listless'",
      "SPEECH OUTPUT: '◾ blah, blah, blah'",
      "SPEECH OUTPUT: '• whine, whine, whine'"]))
diff --git a/test/keystrokes/firefox/say_all_role_lists.settings 
b/test/keystrokes/firefox/say_all_role_lists.settings
new file mode 100644
index 0000000..6d6a48a
--- /dev/null
+++ b/test/keystrokes/firefox/say_all_role_lists.settings
@@ -0,0 +1,165 @@
+{
+    "general": {
+        "enabledSpokenTextAttributes": "size:; family-name:; weight:400; indent:0; underline:none; 
strikethrough:false; justification:left; style:normal; paragraph-style:; text-spelling:none; fg-color:; 
bg-color:;",
+        "orcaModifierKeys": [
+            "Insert",
+            "KP_Insert"
+        ],
+        "skipBlankCells": false,
+        "onlySpeakDisplayedText": false,
+        "enableMnemonicSpeaking": false,
+        "chatAnnounceBuddyTyping": false,
+        "messagesAreDetailed": true,
+        "speakProgressBarUpdates": true,
+        "speakCellCoordinates": true,
+        "enableAlphabeticKeys": true,
+        "enableBraille": false,
+        "brailleAlignmentStyle": 0,
+        "playSoundForPositionInSet": false,
+        "sayAllStyle": 1,
+        "enableEchoBySentence": false,
+        "chatSpeakRoomName": false,
+        "soundVolume": 0.5,
+        "activeProfile": [
+            "Default",
+            "default"
+        ],
+        "brailleVerbosityLevel": 1,
+        "sayAllContextTable": true,
+        "enableTutorialMessages": false,
+        "wrappedStructuralNavigation": true,
+        "capitalizationStyle": "none",
+        "findResultsMinimumLength": 4,
+        "enableContractedBraille": false,
+        "presentDateFormat": "%x",
+        "enableSpeechIndentation": false,
+        "brailleContractionTable": "",
+        "structNavTriggersFocusMode": false,
+        "enablePauseBreaks": true,
+        "speakNumbersAsDigits": false,
+        "spellcheckSpellError": true,
+        "useColorNames": true,
+        "speakContextTable": false,
+        "readFullRowInGUITable": true,
+        "enabledBrailledTextAttributes": "size:; family-name:; weight:400; indent:0; underline:none; 
strikethrough:false; justification:left; style:normal; text-spelling:none;",
+        "enableSpace": true,
+        "brailleSelectorIndicator": 192,
+        "profile": [
+            "Default",
+            "default"
+        ],
+        "verbalizePunctuationStyle": 1,
+        "enableBrailleContext": true,
+        "enableNavigationKeys": false,
+        "structNavInSayAll": false,
+        "enableSound": true,
+        "speakCellSpan": true,
+        "speechVerbosityLevel": 1,
+        "brailleRolenameStyle": 1,
+        "mouseDwellDelay": null,
+        "enableSpeech": true,
+        "caretNavTriggersFocusMode": false,
+        "enableDiacriticalKeys": false,
+        "findResultsVerbosity": 2,
+        "sayAllContextBlockquote": true,
+        "speakBlankLines": true,
+        "speakSpreadsheetCoordinates": true,
+        "flashIsPersistent": false,
+        "enableNumericKeys": true,
+        "enableFlashMessages": true,
+        "progressBarVerbosity": 1,
+        "brailleLinkIndicator": 192,
+        "presentTimeFormat": "%X",
+        "enablePunctuationKeys": true,
+        "enableKeyEcho": false,
+        "playSoundForState": false,
+        "beepProgressBarUpdates": false,
+        "enableFunctionKeys": true,
+        "speakMisspelledIndicator": true,
+        "textAttributesBrailleIndicator": 0,
+        "voices": {
+            "default": {
+                "established": false
+            },
+            "system": {
+                "average-pitch": 3.0
+            },
+            "uppercase": {
+                "average-pitch": 7.0
+            },
+            "hyperlink": {
+                "established": false
+            }
+        },
+        "enableBrailleMonitor": true,
+        "layoutMode": true,
+        "brailleFlashTime": 5000,
+        "largeObjectTextLength": 75,
+        "speakContextList": false,
+        "ignoreStatusBarProgressBars": true,
+        "keyboardLayout": 1,
+        "brailleProgressBarUpdates": false,
+        "readFullRowInSpreadSheet": false,
+        "enableActionKeys": true,
+        "enablePositionSpeaking": false,
+        "structuralNavigationEnabled": true,
+        "playSoundForRole": false,
+        "disableBrailleEOL": false,
+        "presentToolTips": false,
+        "enableMouseReview": false,
+        "speechServerFactory": "speechdispatcherfactory",
+        "chatMessageVerbosity": 0,
+        "enableEchoByWord": false,
+        "spellcheckSpellSuggestion": true,
+        "enableModifierKeys": true,
+        "speakMultiCaseStringsAsWords": false,
+        "flashIsDetailed": true,
+        "speakCellHeaders": true,
+        "rewindAndFastForwardInSayAll": false,
+        "sayAllContextList": true,
+        "speakContextBlockquote": false,
+        "enableEchoByCharacter": false,
+        "playSoundForValue": false,
+        "progressBarUpdateInterval": 10,
+        "spellcheckPresentContext": true,
+        "speechServerInfo": null,
+        "chatRoomHistories": false,
+        "readFullRowInDocumentTable": true,
+        "startingProfile": [
+            "Default",
+            "default"
+        ]
+    },
+    "keybindings": {},
+    "profiles": {
+        "default": {
+            "profile": [
+                "Default",
+                "default"
+            ],
+            "brailleContractionTable": "/usr/share/liblouis/tables/en-us-compbrl.ctb",
+            "voices": {
+                "default": {
+                    "established": false
+                },
+                "system": {
+                    "average-pitch": 3.0
+                },
+                "uppercase": {
+                    "average-pitch": 7.0
+                },
+                "hyperlink": {
+                    "established": false
+                }
+            },
+            "pronunciations": {},
+            "speechServerInfo": [
+                "Default Synthesizer",
+                "default"
+            ],
+            "keybindings": {},
+            "speechServerFactory": "orca.speechdispatcherfactory"
+        }
+    },
+    "pronunciations": {}
+}
\ No newline at end of file
diff --git a/test/keystrokes/firefox/say_all_role_lists_no_context.params 
b/test/keystrokes/firefox/say_all_role_lists_no_context.params
new file mode 100644
index 0000000..4634af5
--- /dev/null
+++ b/test/keystrokes/firefox/say_all_role_lists_no_context.params
@@ -0,0 +1 @@
+PARAMS=$TEST_DIR/../../html/lists.html
diff --git a/test/keystrokes/firefox/say_all_role_lists_no_context.py 
b/test/keystrokes/firefox/say_all_role_lists_no_context.py
new file mode 100644
index 0000000..735843c
--- /dev/null
+++ b/test/keystrokes/firefox/say_all_role_lists_no_context.py
@@ -0,0 +1,50 @@
+#!/usr/bin/python
+
+"""Test of sayAll."""
+
+from macaroon.playback import *
+import utils
+
+sequence = MacroSequence()
+
+#sequence.append(WaitForDocLoad())
+sequence.append(PauseAction(5000))
+
+sequence.append(utils.StartRecordingAction())
+sequence.append(KeyComboAction("KP_Add"))
+sequence.append(utils.AssertPresentationAction(
+    "1. KP_Add to do a SayAll",
+    ["SPEECH OUTPUT: 'Welcome to a List of Lists'",
+     "SPEECH OUTPUT: 'heading level 1'",
+     "SPEECH OUTPUT: 'Lists are not only fun to make, they are fun to use.'",
+     "SPEECH OUTPUT: 'They help us:'",
+     "SPEECH OUTPUT: '1. remember what the heck we are doing each day'",
+     "SPEECH OUTPUT: '2. arrange long and arbitrary lines of text into ordered lists that are pleasing to 
the eye and suggest some sense of priority, even if it is artificial'",
+     "SPEECH OUTPUT: '3. look really cool when we carry them around on yellow Post-Itstm.'",
+     "SPEECH OUTPUT: '4. and that other thing I keep forgetting.'",
+     "SPEECH OUTPUT: 'Your ordered lists can start at a strange number, like:'",
+     "SPEECH OUTPUT: '6. And use roman numerals,'",
+     "SPEECH OUTPUT: 'g. You might try using letters as well,'",
+     "SPEECH OUTPUT: 'H. Maybe you prefer Big Letters,'",
+     "SPEECH OUTPUT: '9. or small roman numerals'",
+     "SPEECH OUTPUT: '• But discs belong to unordered lists'",
+     "SPEECH OUTPUT: '50. Though you can set the value in a list item!'",
+     "SPEECH OUTPUT: 'Unordered list:'",
+     "SPEECH OUTPUT: '• listing item'",
+     "SPEECH OUTPUT: '◦ first sublevel'",
+     "SPEECH OUTPUT: '◾ look for the bullet on'",
+     "SPEECH OUTPUT: '◾ each sublevel'",
+     "SPEECH OUTPUT: '◾ they should all be different, except here.'",
+     "SPEECH OUTPUT: '◾ second sublevel'",
+     "SPEECH OUTPUT: '◾ or you can specify a square'",
+     "SPEECH OUTPUT: '◦ if your TYPE is circle'",
+     "SPEECH OUTPUT: '• or even a disc'",
+     "SPEECH OUTPUT: '◾ Franz Liszt'",
+     "SPEECH OUTPUT: '◦ was a composer who was not square'",
+     "SPEECH OUTPUT: '• would have liked the Who'",
+     "SPEECH OUTPUT: '◦ feeling listless'",
+     "SPEECH OUTPUT: '◾ blah, blah, blah'",
+     "SPEECH OUTPUT: '• whine, whine, whine'"]))
+
+sequence.append(utils.AssertionSummaryAction())
+sequence.start()
diff --git a/test/keystrokes/firefox/say_all_role_lists_no_context.settings 
b/test/keystrokes/firefox/say_all_role_lists_no_context.settings
new file mode 100644
index 0000000..e6a6d5c
--- /dev/null
+++ b/test/keystrokes/firefox/say_all_role_lists_no_context.settings
@@ -0,0 +1,165 @@
+{
+    "general": {
+        "enabledSpokenTextAttributes": "size:; family-name:; weight:400; indent:0; underline:none; 
strikethrough:false; justification:left; style:normal; paragraph-style:; text-spelling:none; fg-color:; 
bg-color:;",
+        "orcaModifierKeys": [
+            "Insert",
+            "KP_Insert"
+        ],
+        "skipBlankCells": false,
+        "onlySpeakDisplayedText": false,
+        "enableMnemonicSpeaking": false,
+        "chatAnnounceBuddyTyping": false,
+        "messagesAreDetailed": true,
+        "speakProgressBarUpdates": true,
+        "speakCellCoordinates": true,
+        "enableAlphabeticKeys": true,
+        "enableBraille": false,
+        "brailleAlignmentStyle": 0,
+        "playSoundForPositionInSet": false,
+        "sayAllStyle": 1,
+        "enableEchoBySentence": false,
+        "chatSpeakRoomName": false,
+        "soundVolume": 0.5,
+        "activeProfile": [
+            "Default",
+            "default"
+        ],
+        "brailleVerbosityLevel": 1,
+        "sayAllContextTable": false,
+        "enableTutorialMessages": false,
+        "wrappedStructuralNavigation": true,
+        "capitalizationStyle": "none",
+        "findResultsMinimumLength": 4,
+        "enableContractedBraille": false,
+        "presentDateFormat": "%x",
+        "enableSpeechIndentation": false,
+        "brailleContractionTable": "",
+        "structNavTriggersFocusMode": false,
+        "enablePauseBreaks": true,
+        "speakNumbersAsDigits": false,
+        "spellcheckSpellError": true,
+        "useColorNames": true,
+        "speakContextTable": false,
+        "readFullRowInGUITable": true,
+        "enabledBrailledTextAttributes": "size:; family-name:; weight:400; indent:0; underline:none; 
strikethrough:false; justification:left; style:normal; text-spelling:none;",
+        "enableSpace": true,
+        "brailleSelectorIndicator": 192,
+        "profile": [
+            "Default",
+            "default"
+        ],
+        "verbalizePunctuationStyle": 1,
+        "enableBrailleContext": true,
+        "enableNavigationKeys": false,
+        "structNavInSayAll": false,
+        "enableSound": true,
+        "speakCellSpan": true,
+        "speechVerbosityLevel": 1,
+        "brailleRolenameStyle": 1,
+        "mouseDwellDelay": null,
+        "enableSpeech": true,
+        "caretNavTriggersFocusMode": false,
+        "enableDiacriticalKeys": false,
+        "findResultsVerbosity": 2,
+        "sayAllContextBlockquote": false,
+        "speakBlankLines": true,
+        "speakSpreadsheetCoordinates": true,
+        "flashIsPersistent": false,
+        "enableNumericKeys": true,
+        "enableFlashMessages": true,
+        "progressBarVerbosity": 1,
+        "brailleLinkIndicator": 192,
+        "presentTimeFormat": "%X",
+        "enablePunctuationKeys": true,
+        "enableKeyEcho": false,
+        "playSoundForState": false,
+        "beepProgressBarUpdates": false,
+        "enableFunctionKeys": true,
+        "speakMisspelledIndicator": true,
+        "textAttributesBrailleIndicator": 0,
+        "voices": {
+            "default": {
+                "established": false
+            },
+            "system": {
+                "average-pitch": 3.0
+            },
+            "uppercase": {
+                "average-pitch": 7.0
+            },
+            "hyperlink": {
+                "established": false
+            }
+        },
+        "enableBrailleMonitor": true,
+        "layoutMode": true,
+        "brailleFlashTime": 5000,
+        "largeObjectTextLength": 75,
+        "speakContextList": false,
+        "ignoreStatusBarProgressBars": true,
+        "keyboardLayout": 1,
+        "brailleProgressBarUpdates": false,
+        "readFullRowInSpreadSheet": false,
+        "enableActionKeys": true,
+        "enablePositionSpeaking": false,
+        "structuralNavigationEnabled": true,
+        "playSoundForRole": false,
+        "disableBrailleEOL": false,
+        "presentToolTips": false,
+        "enableMouseReview": false,
+        "speechServerFactory": "speechdispatcherfactory",
+        "chatMessageVerbosity": 0,
+        "enableEchoByWord": false,
+        "spellcheckSpellSuggestion": true,
+        "enableModifierKeys": true,
+        "speakMultiCaseStringsAsWords": false,
+        "flashIsDetailed": true,
+        "speakCellHeaders": true,
+        "rewindAndFastForwardInSayAll": false,
+        "sayAllContextList": false,
+        "speakContextBlockquote": false,
+        "enableEchoByCharacter": false,
+        "playSoundForValue": false,
+        "progressBarUpdateInterval": 10,
+        "spellcheckPresentContext": true,
+        "speechServerInfo": null,
+        "chatRoomHistories": false,
+        "readFullRowInDocumentTable": true,
+        "startingProfile": [
+            "Default",
+            "default"
+        ]
+    },
+    "keybindings": {},
+    "profiles": {
+        "default": {
+            "profile": [
+                "Default",
+                "default"
+            ],
+            "brailleContractionTable": "/usr/share/liblouis/tables/en-us-compbrl.ctb",
+            "voices": {
+                "default": {
+                    "established": false
+                },
+                "system": {
+                    "average-pitch": 3.0
+                },
+                "uppercase": {
+                    "average-pitch": 7.0
+                },
+                "hyperlink": {
+                    "established": false
+                }
+            },
+            "pronunciations": {},
+            "speechServerInfo": [
+                "Default Synthesizer",
+                "default"
+            ],
+            "keybindings": {},
+            "speechServerFactory": "orca.speechdispatcherfactory"
+        }
+    },
+    "pronunciations": {}
+}
\ No newline at end of file
diff --git a/test/keystrokes/firefox/say_all_table_caption.py 
b/test/keystrokes/firefox/say_all_table_caption.py
index fb9a8f7..33cd18e 100644
--- a/test/keystrokes/firefox/say_all_table_caption.py
+++ b/test/keystrokes/firefox/say_all_table_caption.py
@@ -16,6 +16,8 @@ sequence.append(utils.AssertPresentationAction(
     "1. KP_Add to do a SayAll",
     ["SPEECH OUTPUT: 'Below is a table, with some sample table data'",
      "SPEECH OUTPUT: 'this is a caption for this table'",
+     "SPEECH OUTPUT: 'table with 4 rows 3 columns'",
+     "SPEECH OUTPUT: 'this is a caption for this table'",
      "SPEECH OUTPUT: 'caption'",
      "SPEECH OUTPUT: 'col1'",
      "SPEECH OUTPUT: 'column header'",
@@ -32,6 +34,7 @@ sequence.append(utils.AssertPresentationAction(
      "SPEECH OUTPUT: '7'",
      "SPEECH OUTPUT: '8'",
      "SPEECH OUTPUT: '9'",
+     "SPEECH OUTPUT: 'leaving table.'",
      "SPEECH OUTPUT: 'hope the table looks pretty'"]))
 
 sequence.append(utils.AssertionSummaryAction())
diff --git a/test/keystrokes/firefox/say_all_table_caption.settings 
b/test/keystrokes/firefox/say_all_table_caption.settings
new file mode 100644
index 0000000..6d6a48a
--- /dev/null
+++ b/test/keystrokes/firefox/say_all_table_caption.settings
@@ -0,0 +1,165 @@
+{
+    "general": {
+        "enabledSpokenTextAttributes": "size:; family-name:; weight:400; indent:0; underline:none; 
strikethrough:false; justification:left; style:normal; paragraph-style:; text-spelling:none; fg-color:; 
bg-color:;",
+        "orcaModifierKeys": [
+            "Insert",
+            "KP_Insert"
+        ],
+        "skipBlankCells": false,
+        "onlySpeakDisplayedText": false,
+        "enableMnemonicSpeaking": false,
+        "chatAnnounceBuddyTyping": false,
+        "messagesAreDetailed": true,
+        "speakProgressBarUpdates": true,
+        "speakCellCoordinates": true,
+        "enableAlphabeticKeys": true,
+        "enableBraille": false,
+        "brailleAlignmentStyle": 0,
+        "playSoundForPositionInSet": false,
+        "sayAllStyle": 1,
+        "enableEchoBySentence": false,
+        "chatSpeakRoomName": false,
+        "soundVolume": 0.5,
+        "activeProfile": [
+            "Default",
+            "default"
+        ],
+        "brailleVerbosityLevel": 1,
+        "sayAllContextTable": true,
+        "enableTutorialMessages": false,
+        "wrappedStructuralNavigation": true,
+        "capitalizationStyle": "none",
+        "findResultsMinimumLength": 4,
+        "enableContractedBraille": false,
+        "presentDateFormat": "%x",
+        "enableSpeechIndentation": false,
+        "brailleContractionTable": "",
+        "structNavTriggersFocusMode": false,
+        "enablePauseBreaks": true,
+        "speakNumbersAsDigits": false,
+        "spellcheckSpellError": true,
+        "useColorNames": true,
+        "speakContextTable": false,
+        "readFullRowInGUITable": true,
+        "enabledBrailledTextAttributes": "size:; family-name:; weight:400; indent:0; underline:none; 
strikethrough:false; justification:left; style:normal; text-spelling:none;",
+        "enableSpace": true,
+        "brailleSelectorIndicator": 192,
+        "profile": [
+            "Default",
+            "default"
+        ],
+        "verbalizePunctuationStyle": 1,
+        "enableBrailleContext": true,
+        "enableNavigationKeys": false,
+        "structNavInSayAll": false,
+        "enableSound": true,
+        "speakCellSpan": true,
+        "speechVerbosityLevel": 1,
+        "brailleRolenameStyle": 1,
+        "mouseDwellDelay": null,
+        "enableSpeech": true,
+        "caretNavTriggersFocusMode": false,
+        "enableDiacriticalKeys": false,
+        "findResultsVerbosity": 2,
+        "sayAllContextBlockquote": true,
+        "speakBlankLines": true,
+        "speakSpreadsheetCoordinates": true,
+        "flashIsPersistent": false,
+        "enableNumericKeys": true,
+        "enableFlashMessages": true,
+        "progressBarVerbosity": 1,
+        "brailleLinkIndicator": 192,
+        "presentTimeFormat": "%X",
+        "enablePunctuationKeys": true,
+        "enableKeyEcho": false,
+        "playSoundForState": false,
+        "beepProgressBarUpdates": false,
+        "enableFunctionKeys": true,
+        "speakMisspelledIndicator": true,
+        "textAttributesBrailleIndicator": 0,
+        "voices": {
+            "default": {
+                "established": false
+            },
+            "system": {
+                "average-pitch": 3.0
+            },
+            "uppercase": {
+                "average-pitch": 7.0
+            },
+            "hyperlink": {
+                "established": false
+            }
+        },
+        "enableBrailleMonitor": true,
+        "layoutMode": true,
+        "brailleFlashTime": 5000,
+        "largeObjectTextLength": 75,
+        "speakContextList": false,
+        "ignoreStatusBarProgressBars": true,
+        "keyboardLayout": 1,
+        "brailleProgressBarUpdates": false,
+        "readFullRowInSpreadSheet": false,
+        "enableActionKeys": true,
+        "enablePositionSpeaking": false,
+        "structuralNavigationEnabled": true,
+        "playSoundForRole": false,
+        "disableBrailleEOL": false,
+        "presentToolTips": false,
+        "enableMouseReview": false,
+        "speechServerFactory": "speechdispatcherfactory",
+        "chatMessageVerbosity": 0,
+        "enableEchoByWord": false,
+        "spellcheckSpellSuggestion": true,
+        "enableModifierKeys": true,
+        "speakMultiCaseStringsAsWords": false,
+        "flashIsDetailed": true,
+        "speakCellHeaders": true,
+        "rewindAndFastForwardInSayAll": false,
+        "sayAllContextList": true,
+        "speakContextBlockquote": false,
+        "enableEchoByCharacter": false,
+        "playSoundForValue": false,
+        "progressBarUpdateInterval": 10,
+        "spellcheckPresentContext": true,
+        "speechServerInfo": null,
+        "chatRoomHistories": false,
+        "readFullRowInDocumentTable": true,
+        "startingProfile": [
+            "Default",
+            "default"
+        ]
+    },
+    "keybindings": {},
+    "profiles": {
+        "default": {
+            "profile": [
+                "Default",
+                "default"
+            ],
+            "brailleContractionTable": "/usr/share/liblouis/tables/en-us-compbrl.ctb",
+            "voices": {
+                "default": {
+                    "established": false
+                },
+                "system": {
+                    "average-pitch": 3.0
+                },
+                "uppercase": {
+                    "average-pitch": 7.0
+                },
+                "hyperlink": {
+                    "established": false
+                }
+            },
+            "pronunciations": {},
+            "speechServerInfo": [
+                "Default Synthesizer",
+                "default"
+            ],
+            "keybindings": {},
+            "speechServerFactory": "orca.speechdispatcherfactory"
+        }
+    },
+    "pronunciations": {}
+}
\ No newline at end of file
diff --git a/test/keystrokes/firefox/say_all_table_caption_no_context.params 
b/test/keystrokes/firefox/say_all_table_caption_no_context.params
new file mode 100644
index 0000000..71b25db
--- /dev/null
+++ b/test/keystrokes/firefox/say_all_table_caption_no_context.params
@@ -0,0 +1 @@
+PARAMS=$TEST_DIR/../../html/table-caption.html
diff --git a/test/keystrokes/firefox/say_all_table_caption_no_context.py 
b/test/keystrokes/firefox/say_all_table_caption_no_context.py
new file mode 100644
index 0000000..fb9a8f7
--- /dev/null
+++ b/test/keystrokes/firefox/say_all_table_caption_no_context.py
@@ -0,0 +1,38 @@
+#!/usr/bin/python
+
+"""Test of sayAll."""
+
+from macaroon.playback import *
+import utils
+
+sequence = MacroSequence()
+
+#sequence.append(WaitForDocLoad())
+sequence.append(PauseAction(5000))
+
+sequence.append(utils.StartRecordingAction())
+sequence.append(KeyComboAction("KP_Add"))
+sequence.append(utils.AssertPresentationAction(
+    "1. KP_Add to do a SayAll",
+    ["SPEECH OUTPUT: 'Below is a table, with some sample table data'",
+     "SPEECH OUTPUT: 'this is a caption for this table'",
+     "SPEECH OUTPUT: 'caption'",
+     "SPEECH OUTPUT: 'col1'",
+     "SPEECH OUTPUT: 'column header'",
+     "SPEECH OUTPUT: 'col2'",
+     "SPEECH OUTPUT: 'column header'",
+     "SPEECH OUTPUT: 'col3'",
+     "SPEECH OUTPUT: 'column header'",
+     "SPEECH OUTPUT: '1'",
+     "SPEECH OUTPUT: '2'",
+     "SPEECH OUTPUT: '3'",
+     "SPEECH OUTPUT: '4'",
+     "SPEECH OUTPUT: '5'",
+     "SPEECH OUTPUT: '6'",
+     "SPEECH OUTPUT: '7'",
+     "SPEECH OUTPUT: '8'",
+     "SPEECH OUTPUT: '9'",
+     "SPEECH OUTPUT: 'hope the table looks pretty'"]))
+
+sequence.append(utils.AssertionSummaryAction())
+sequence.start()
diff --git a/test/keystrokes/firefox/say_all_table_caption_no_context.settings 
b/test/keystrokes/firefox/say_all_table_caption_no_context.settings
new file mode 100644
index 0000000..e6a6d5c
--- /dev/null
+++ b/test/keystrokes/firefox/say_all_table_caption_no_context.settings
@@ -0,0 +1,165 @@
+{
+    "general": {
+        "enabledSpokenTextAttributes": "size:; family-name:; weight:400; indent:0; underline:none; 
strikethrough:false; justification:left; style:normal; paragraph-style:; text-spelling:none; fg-color:; 
bg-color:;",
+        "orcaModifierKeys": [
+            "Insert",
+            "KP_Insert"
+        ],
+        "skipBlankCells": false,
+        "onlySpeakDisplayedText": false,
+        "enableMnemonicSpeaking": false,
+        "chatAnnounceBuddyTyping": false,
+        "messagesAreDetailed": true,
+        "speakProgressBarUpdates": true,
+        "speakCellCoordinates": true,
+        "enableAlphabeticKeys": true,
+        "enableBraille": false,
+        "brailleAlignmentStyle": 0,
+        "playSoundForPositionInSet": false,
+        "sayAllStyle": 1,
+        "enableEchoBySentence": false,
+        "chatSpeakRoomName": false,
+        "soundVolume": 0.5,
+        "activeProfile": [
+            "Default",
+            "default"
+        ],
+        "brailleVerbosityLevel": 1,
+        "sayAllContextTable": false,
+        "enableTutorialMessages": false,
+        "wrappedStructuralNavigation": true,
+        "capitalizationStyle": "none",
+        "findResultsMinimumLength": 4,
+        "enableContractedBraille": false,
+        "presentDateFormat": "%x",
+        "enableSpeechIndentation": false,
+        "brailleContractionTable": "",
+        "structNavTriggersFocusMode": false,
+        "enablePauseBreaks": true,
+        "speakNumbersAsDigits": false,
+        "spellcheckSpellError": true,
+        "useColorNames": true,
+        "speakContextTable": false,
+        "readFullRowInGUITable": true,
+        "enabledBrailledTextAttributes": "size:; family-name:; weight:400; indent:0; underline:none; 
strikethrough:false; justification:left; style:normal; text-spelling:none;",
+        "enableSpace": true,
+        "brailleSelectorIndicator": 192,
+        "profile": [
+            "Default",
+            "default"
+        ],
+        "verbalizePunctuationStyle": 1,
+        "enableBrailleContext": true,
+        "enableNavigationKeys": false,
+        "structNavInSayAll": false,
+        "enableSound": true,
+        "speakCellSpan": true,
+        "speechVerbosityLevel": 1,
+        "brailleRolenameStyle": 1,
+        "mouseDwellDelay": null,
+        "enableSpeech": true,
+        "caretNavTriggersFocusMode": false,
+        "enableDiacriticalKeys": false,
+        "findResultsVerbosity": 2,
+        "sayAllContextBlockquote": false,
+        "speakBlankLines": true,
+        "speakSpreadsheetCoordinates": true,
+        "flashIsPersistent": false,
+        "enableNumericKeys": true,
+        "enableFlashMessages": true,
+        "progressBarVerbosity": 1,
+        "brailleLinkIndicator": 192,
+        "presentTimeFormat": "%X",
+        "enablePunctuationKeys": true,
+        "enableKeyEcho": false,
+        "playSoundForState": false,
+        "beepProgressBarUpdates": false,
+        "enableFunctionKeys": true,
+        "speakMisspelledIndicator": true,
+        "textAttributesBrailleIndicator": 0,
+        "voices": {
+            "default": {
+                "established": false
+            },
+            "system": {
+                "average-pitch": 3.0
+            },
+            "uppercase": {
+                "average-pitch": 7.0
+            },
+            "hyperlink": {
+                "established": false
+            }
+        },
+        "enableBrailleMonitor": true,
+        "layoutMode": true,
+        "brailleFlashTime": 5000,
+        "largeObjectTextLength": 75,
+        "speakContextList": false,
+        "ignoreStatusBarProgressBars": true,
+        "keyboardLayout": 1,
+        "brailleProgressBarUpdates": false,
+        "readFullRowInSpreadSheet": false,
+        "enableActionKeys": true,
+        "enablePositionSpeaking": false,
+        "structuralNavigationEnabled": true,
+        "playSoundForRole": false,
+        "disableBrailleEOL": false,
+        "presentToolTips": false,
+        "enableMouseReview": false,
+        "speechServerFactory": "speechdispatcherfactory",
+        "chatMessageVerbosity": 0,
+        "enableEchoByWord": false,
+        "spellcheckSpellSuggestion": true,
+        "enableModifierKeys": true,
+        "speakMultiCaseStringsAsWords": false,
+        "flashIsDetailed": true,
+        "speakCellHeaders": true,
+        "rewindAndFastForwardInSayAll": false,
+        "sayAllContextList": false,
+        "speakContextBlockquote": false,
+        "enableEchoByCharacter": false,
+        "playSoundForValue": false,
+        "progressBarUpdateInterval": 10,
+        "spellcheckPresentContext": true,
+        "speechServerInfo": null,
+        "chatRoomHistories": false,
+        "readFullRowInDocumentTable": true,
+        "startingProfile": [
+            "Default",
+            "default"
+        ]
+    },
+    "keybindings": {},
+    "profiles": {
+        "default": {
+            "profile": [
+                "Default",
+                "default"
+            ],
+            "brailleContractionTable": "/usr/share/liblouis/tables/en-us-compbrl.ctb",
+            "voices": {
+                "default": {
+                    "established": false
+                },
+                "system": {
+                    "average-pitch": 3.0
+                },
+                "uppercase": {
+                    "average-pitch": 7.0
+                },
+                "hyperlink": {
+                    "established": false
+                }
+            },
+            "pronunciations": {},
+            "speechServerInfo": [
+                "Default Synthesizer",
+                "default"
+            ],
+            "keybindings": {},
+            "speechServerFactory": "orca.speechdispatcherfactory"
+        }
+    },
+    "pronunciations": {}
+}
\ No newline at end of file
diff --git a/test/keystrokes/firefox/say_all_wiki.py b/test/keystrokes/firefox/say_all_wiki.py
index 1a783c1..bd2b93b 100644
--- a/test/keystrokes/firefox/say_all_wiki.py
+++ b/test/keystrokes/firefox/say_all_wiki.py
@@ -28,6 +28,7 @@ sequence.append(utils.AssertPresentationAction(
      "SPEECH OUTPUT: 'link'",
      "SPEECH OUTPUT: 'Community'",
      "SPEECH OUTPUT: 'link'",
+     "SPEECH OUTPUT: 'leaving list.'",
      "SPEECH OUTPUT: 'live.gnome.org'",
      "SPEECH OUTPUT: 'heading level 1'",
      "SPEECH OUTPUT: 'entry'",
@@ -81,6 +82,7 @@ sequence.append(utils.AssertPresentationAction(
      "SPEECH OUTPUT: 'access to Firefox 3.0'",
      "SPEECH OUTPUT: 'link'",
      "SPEECH OUTPUT: 'Contents'",
+     "SPEECH OUTPUT: 'List with 8 items'",
      "SPEECH OUTPUT: '1.'",
      "SPEECH OUTPUT: 'Welcome to Orca!'",
      "SPEECH OUTPUT: 'link'",
@@ -105,11 +107,12 @@ sequence.append(utils.AssertPresentationAction(
      "SPEECH OUTPUT: '8.'",
      "SPEECH OUTPUT: 'More Information'",
      "SPEECH OUTPUT: 'link'",
+     "SPEECH OUTPUT: 'leaving list.'",
      "SPEECH OUTPUT: 'About'",
      "SPEECH OUTPUT: 'heading level 1'",
      "SPEECH OUTPUT: 'Orca is a free, open source, flexible, extensible, and powerful assistive technology 
for people with visual impairments.'",
-     "SPEECH OUTPUT: 'Using various combinations of speech synthesis, braille, and magnification, Orca helps 
provide access to applications and toolkits that support the AT-SPI \(e.g.,",
-     "SPEECH OUTPUT: 'the GNOME desktop\).",
+     "SPEECH OUTPUT: 'Using various combinations of speech synthesis, braille, and magnification, Orca helps 
provide access to applications and toolkits that support the AT-SPI \(e.g.,'",
+     "SPEECH OUTPUT: 'the GNOME desktop\).'",
      "SPEECH OUTPUT: 'The development of Orca has been led by the'",
      "SPEECH OUTPUT: 'Accessibility Program Office of Sun Microsystems, Inc.'",
      "SPEECH OUTPUT: 'link'",
@@ -141,6 +144,7 @@ sequence.append(utils.AssertPresentationAction(
      "SPEECH OUTPUT: 'http://www.digitaldarragh.com/linuxat.asp'",
      "SPEECH OUTPUT: 'link'",
      "SPEECH OUTPUT: 'and include the following:'",
+     "SPEECH OUTPUT: 'List with 3 items'",
      "SPEECH OUTPUT: '•'",
      "SPEECH OUTPUT: 'Walk through of the installation of Ubuntu 7.4. Very helpful tutorial'",
      "SPEECH OUTPUT: 'link'",
@@ -150,6 +154,7 @@ sequence.append(utils.AssertPresentationAction(
      "SPEECH OUTPUT: '•'",
      "SPEECH OUTPUT: 'Guide to installing the latest versions of Firefox and Orca'",
      "SPEECH OUTPUT: 'link'",
+     "SPEECH OUTPUT: 'leaving list.'",
      "SPEECH OUTPUT: 'Download/Installation'",
      "SPEECH OUTPUT: 'heading level 1'",
      "SPEECH OUTPUT: 'As of GNOME 2.16,'",
@@ -223,6 +228,7 @@ sequence.append(utils.AssertPresentationAction(
      "SPEECH OUTPUT: 'for detailed information.'",
      "SPEECH OUTPUT: 'More Information'",
      "SPEECH OUTPUT: 'heading level 1'",
+     "SPEECH OUTPUT: 'List with 7 items'",
      "SPEECH OUTPUT: '•'",
      "SPEECH OUTPUT: 'Frequently Asked Questions:'",
      "SPEECH OUTPUT: 'FAQ'",
@@ -256,6 +262,7 @@ sequence.append(utils.AssertPresentationAction(
      "SPEECH OUTPUT: '•'",
      "SPEECH OUTPUT: 'Python Pocket Reference, Mark Lutz'",
      "SPEECH OUTPUT: 'link'",
+     "SPEECH OUTPUT: 'leaving list.'",
      "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'",
@@ -269,8 +276,10 @@ sequence.append(utils.AssertPresentationAction(
      "SPEECH OUTPUT: 'heading level 3'",
      "SPEECH OUTPUT: 'Login'",
      "SPEECH OUTPUT: 'link'",
+     "SPEECH OUTPUT: 'leaving list.'",
      "SPEECH OUTPUT: 'Page'",
      "SPEECH OUTPUT: 'heading level 3'",
+     "SPEECH OUTPUT: 'List with 4 items'",
      "SPEECH OUTPUT: 'Immutable Page'",
      "SPEECH OUTPUT: 'Info'",
      "SPEECH OUTPUT: 'link'",
@@ -278,6 +287,7 @@ sequence.append(utils.AssertPresentationAction(
      "SPEECH OUTPUT: 'link'",
      "SPEECH OUTPUT: 'More Actions:'",
      "SPEECH OUTPUT: 'combo box'",
+     "SPEECH OUTPUT: 'leaving list.'",
      "SPEECH OUTPUT: 'GNOME World Wide'",
      "SPEECH OUTPUT: 'heading level 3'",
      "SPEECH OUTPUT: 'GnomeWorldWide'",
diff --git a/test/keystrokes/firefox/say_all_wiki.settings b/test/keystrokes/firefox/say_all_wiki.settings
new file mode 100644
index 0000000..6d6a48a
--- /dev/null
+++ b/test/keystrokes/firefox/say_all_wiki.settings
@@ -0,0 +1,165 @@
+{
+    "general": {
+        "enabledSpokenTextAttributes": "size:; family-name:; weight:400; indent:0; underline:none; 
strikethrough:false; justification:left; style:normal; paragraph-style:; text-spelling:none; fg-color:; 
bg-color:;",
+        "orcaModifierKeys": [
+            "Insert",
+            "KP_Insert"
+        ],
+        "skipBlankCells": false,
+        "onlySpeakDisplayedText": false,
+        "enableMnemonicSpeaking": false,
+        "chatAnnounceBuddyTyping": false,
+        "messagesAreDetailed": true,
+        "speakProgressBarUpdates": true,
+        "speakCellCoordinates": true,
+        "enableAlphabeticKeys": true,
+        "enableBraille": false,
+        "brailleAlignmentStyle": 0,
+        "playSoundForPositionInSet": false,
+        "sayAllStyle": 1,
+        "enableEchoBySentence": false,
+        "chatSpeakRoomName": false,
+        "soundVolume": 0.5,
+        "activeProfile": [
+            "Default",
+            "default"
+        ],
+        "brailleVerbosityLevel": 1,
+        "sayAllContextTable": true,
+        "enableTutorialMessages": false,
+        "wrappedStructuralNavigation": true,
+        "capitalizationStyle": "none",
+        "findResultsMinimumLength": 4,
+        "enableContractedBraille": false,
+        "presentDateFormat": "%x",
+        "enableSpeechIndentation": false,
+        "brailleContractionTable": "",
+        "structNavTriggersFocusMode": false,
+        "enablePauseBreaks": true,
+        "speakNumbersAsDigits": false,
+        "spellcheckSpellError": true,
+        "useColorNames": true,
+        "speakContextTable": false,
+        "readFullRowInGUITable": true,
+        "enabledBrailledTextAttributes": "size:; family-name:; weight:400; indent:0; underline:none; 
strikethrough:false; justification:left; style:normal; text-spelling:none;",
+        "enableSpace": true,
+        "brailleSelectorIndicator": 192,
+        "profile": [
+            "Default",
+            "default"
+        ],
+        "verbalizePunctuationStyle": 1,
+        "enableBrailleContext": true,
+        "enableNavigationKeys": false,
+        "structNavInSayAll": false,
+        "enableSound": true,
+        "speakCellSpan": true,
+        "speechVerbosityLevel": 1,
+        "brailleRolenameStyle": 1,
+        "mouseDwellDelay": null,
+        "enableSpeech": true,
+        "caretNavTriggersFocusMode": false,
+        "enableDiacriticalKeys": false,
+        "findResultsVerbosity": 2,
+        "sayAllContextBlockquote": true,
+        "speakBlankLines": true,
+        "speakSpreadsheetCoordinates": true,
+        "flashIsPersistent": false,
+        "enableNumericKeys": true,
+        "enableFlashMessages": true,
+        "progressBarVerbosity": 1,
+        "brailleLinkIndicator": 192,
+        "presentTimeFormat": "%X",
+        "enablePunctuationKeys": true,
+        "enableKeyEcho": false,
+        "playSoundForState": false,
+        "beepProgressBarUpdates": false,
+        "enableFunctionKeys": true,
+        "speakMisspelledIndicator": true,
+        "textAttributesBrailleIndicator": 0,
+        "voices": {
+            "default": {
+                "established": false
+            },
+            "system": {
+                "average-pitch": 3.0
+            },
+            "uppercase": {
+                "average-pitch": 7.0
+            },
+            "hyperlink": {
+                "established": false
+            }
+        },
+        "enableBrailleMonitor": true,
+        "layoutMode": true,
+        "brailleFlashTime": 5000,
+        "largeObjectTextLength": 75,
+        "speakContextList": false,
+        "ignoreStatusBarProgressBars": true,
+        "keyboardLayout": 1,
+        "brailleProgressBarUpdates": false,
+        "readFullRowInSpreadSheet": false,
+        "enableActionKeys": true,
+        "enablePositionSpeaking": false,
+        "structuralNavigationEnabled": true,
+        "playSoundForRole": false,
+        "disableBrailleEOL": false,
+        "presentToolTips": false,
+        "enableMouseReview": false,
+        "speechServerFactory": "speechdispatcherfactory",
+        "chatMessageVerbosity": 0,
+        "enableEchoByWord": false,
+        "spellcheckSpellSuggestion": true,
+        "enableModifierKeys": true,
+        "speakMultiCaseStringsAsWords": false,
+        "flashIsDetailed": true,
+        "speakCellHeaders": true,
+        "rewindAndFastForwardInSayAll": false,
+        "sayAllContextList": true,
+        "speakContextBlockquote": false,
+        "enableEchoByCharacter": false,
+        "playSoundForValue": false,
+        "progressBarUpdateInterval": 10,
+        "spellcheckPresentContext": true,
+        "speechServerInfo": null,
+        "chatRoomHistories": false,
+        "readFullRowInDocumentTable": true,
+        "startingProfile": [
+            "Default",
+            "default"
+        ]
+    },
+    "keybindings": {},
+    "profiles": {
+        "default": {
+            "profile": [
+                "Default",
+                "default"
+            ],
+            "brailleContractionTable": "/usr/share/liblouis/tables/en-us-compbrl.ctb",
+            "voices": {
+                "default": {
+                    "established": false
+                },
+                "system": {
+                    "average-pitch": 3.0
+                },
+                "uppercase": {
+                    "average-pitch": 7.0
+                },
+                "hyperlink": {
+                    "established": false
+                }
+            },
+            "pronunciations": {},
+            "speechServerInfo": [
+                "Default Synthesizer",
+                "default"
+            ],
+            "keybindings": {},
+            "speechServerFactory": "orca.speechdispatcherfactory"
+        }
+    },
+    "pronunciations": {}
+}
\ No newline at end of file
diff --git a/test/keystrokes/firefox/say_all_wiki_no_context.params 
b/test/keystrokes/firefox/say_all_wiki_no_context.params
new file mode 100644
index 0000000..0dafc37
--- /dev/null
+++ b/test/keystrokes/firefox/say_all_wiki_no_context.params
@@ -0,0 +1 @@
+PARAMS=$TEST_DIR/../../html/orca-wiki.html
diff --git a/test/keystrokes/firefox/say_all_wiki_no_context.py 
b/test/keystrokes/firefox/say_all_wiki_no_context.py
new file mode 100644
index 0000000..8301a31
--- /dev/null
+++ b/test/keystrokes/firefox/say_all_wiki_no_context.py
@@ -0,0 +1,296 @@
+#!/usr/bin/python
+
+"""Test of sayAll."""
+
+from macaroon.playback import *
+import utils
+
+sequence = MacroSequence()
+
+#sequence.append(WaitForDocLoad())
+sequence.append(PauseAction(5000))
+
+sequence.append(utils.StartRecordingAction())
+sequence.append(KeyComboAction("KP_Add"))
+sequence.append(utils.AssertPresentationAction(
+    "1. KP_Add to do a SayAll",
+    ["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: 'live.gnome.org'",
+     "SPEECH OUTPUT: 'heading level 1'",
+     "SPEECH OUTPUT: 'entry'",
+     "SPEECH OUTPUT: 'Search'",
+     "SPEECH OUTPUT: 'Titles'",
+     "SPEECH OUTPUT: 'push button'",
+     "SPEECH OUTPUT: 'grayed'",
+     "SPEECH OUTPUT: 'Text'",
+     "SPEECH OUTPUT: 'push button'",
+     "SPEECH OUTPUT: 'grayed'",
+     "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: 'en Español'",
+     "SPEECH OUTPUT: 'link'",
+     "SPEECH OUTPUT: 'Home'",
+     "SPEECH OUTPUT: 'link'",
+     "SPEECH OUTPUT: '|'",
+     "SPEECH OUTPUT: 'Download/Installation'",
+     "SPEECH OUTPUT: 'link'",
+     "SPEECH OUTPUT: '|'",
+     "SPEECH OUTPUT: 'Configuration/Use'",
+     "SPEECH OUTPUT: 'link'",
+     "SPEECH OUTPUT: '|'",
+     "SPEECH OUTPUT: 'Accessible Applications'",
+     "SPEECH OUTPUT: 'link'",
+     "SPEECH OUTPUT: '|'",
+     "SPEECH OUTPUT: 'Mailing List'",
+     "SPEECH OUTPUT: 'link'",
+     "SPEECH OUTPUT: '('",
+     "SPEECH OUTPUT: 'Archives'",
+     "SPEECH OUTPUT: 'link'",
+     "SPEECH OUTPUT: ') |'",
+     "SPEECH OUTPUT: 'FAQ'",
+     "SPEECH OUTPUT: 'link'",
+     "SPEECH OUTPUT: '|'",
+     "SPEECH OUTPUT: 'DocIndex'",
+     "SPEECH OUTPUT: 'link'",
+     "SPEECH OUTPUT: 'Welcome to Orca!'",
+     "SPEECH OUTPUT: 'heading level 1'",
+     "SPEECH OUTPUT: 'Orca Logo'",
+     "SPEECH OUTPUT: 'link'",
+     "SPEECH OUTPUT: 'HOT HOT HOT: Notes on'",
+     "SPEECH OUTPUT: 'access to Firefox 3.0'",
+     "SPEECH OUTPUT: 'link'",
+     "SPEECH OUTPUT: 'Contents'",
+     "SPEECH OUTPUT: '1.'",
+     "SPEECH OUTPUT: 'Welcome to Orca!'",
+     "SPEECH OUTPUT: 'link'",
+     "SPEECH OUTPUT: '2.'",
+     "SPEECH OUTPUT: 'About'",
+     "SPEECH OUTPUT: 'link'",
+     "SPEECH OUTPUT: '3.'",
+     "SPEECH OUTPUT: 'Audio Guides'",
+     "SPEECH OUTPUT: 'link'",
+     "SPEECH OUTPUT: '4.'",
+     "SPEECH OUTPUT: 'Download/Installation'",
+     "SPEECH OUTPUT: 'link'",
+     "SPEECH OUTPUT: '5.'",
+     "SPEECH OUTPUT: 'Configuration/Use'",
+     "SPEECH OUTPUT: 'link'",
+     "SPEECH OUTPUT: '6.'",
+     "SPEECH OUTPUT: 'Accessible Applications'",
+     "SPEECH OUTPUT: 'link'",
+     "SPEECH OUTPUT: '7.'",
+     "SPEECH OUTPUT: 'How Can I Help?'",
+     "SPEECH OUTPUT: 'link'",
+     "SPEECH OUTPUT: '8.'",
+     "SPEECH OUTPUT: 'More Information'",
+     "SPEECH OUTPUT: 'link'",
+     "SPEECH OUTPUT: 'About'",
+     "SPEECH OUTPUT: 'heading level 1'",
+     "SPEECH OUTPUT: 'Orca is a free, open source, flexible, extensible, and powerful assistive technology 
for people with visual impairments.'",
+     "SPEECH OUTPUT: 'Using various combinations of speech synthesis, braille, and magnification, Orca helps 
provide access to applications and toolkits that support the AT-SPI \(e.g.,'",
+     "SPEECH OUTPUT: 'the GNOME desktop\).'",
+     "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: 'with'",
+     "SPEECH OUTPUT: 'contributions from many community members'",
+     "SPEECH OUTPUT: 'link'",
+     "SPEECH OUTPUT: '.'",
+     "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: '(please see our'",
+     "SPEECH OUTPUT: 'notes on how we use Bugzilla'",
+     "SPEECH OUTPUT: 'link'",
+     "SPEECH OUTPUT: ').'",
+     "SPEECH OUTPUT: 'Please join and participate on the'",
+     "SPEECH OUTPUT: 'Orca mailing list'",
+     "SPEECH OUTPUT: 'link'",
+     "SPEECH OUTPUT: '('",
+     "SPEECH OUTPUT: 'archives'",
+     "SPEECH OUTPUT: 'link'",
+     "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: '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: '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: '•'",
+     "SPEECH OUTPUT: 'Review of Fedora 7 and the Orca screen reader for the Gnome graphical desktop'",
+     "SPEECH OUTPUT: 'link'",
+     "SPEECH OUTPUT: '•'",
+     "SPEECH OUTPUT: 'Guide to installing the latest versions of Firefox and Orca'",
+     "SPEECH OUTPUT: 'link'",
+     "SPEECH OUTPUT: 'Download/Installation'",
+     "SPEECH OUTPUT: 'heading level 1'",
+     "SPEECH OUTPUT: 'As of GNOME 2.16,'",
+     "SPEECH OUTPUT: 'Orca is a part of the GNOME platform.'",
+     "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: 'and'",
+     "SPEECH OUTPUT: 'Ubuntu'",
+     "SPEECH OUTPUT: 'link'",
+     "SPEECH OUTPUT: '.'",
+     "SPEECH OUTPUT: 'Please also refer to the'",
+     "SPEECH OUTPUT: 'Download/Installation page'",
+     "SPEECH OUTPUT: 'link'",
+     "SPEECH OUTPUT: 'for detailed information on various distributions as well as installing Orca directly 
from source.'",
+     "SPEECH OUTPUT: 'Configuration/Use'",
+     "SPEECH OUTPUT: 'heading level 1'",
+     "SPEECH OUTPUT: 'The command to run orca is orca.'",
+     "SPEECH OUTPUT: 'You can enter this command by pressing Alt+F2 when logged in, waiting for a second or 
so, then typing orca and pressing return.'",
+     "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: '.'",
+     "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'",
+     "SPEECH OUTPUT: 'Orca Configuration GUI'",
+     "SPEECH OUTPUT: 'link'",
+     "SPEECH OUTPUT: '(accessed by pressing Insert+Space when Orca is running) and for using flat review 
mode to examine a window.'",
+     "SPEECH OUTPUT: 'Refer to'",
+     "SPEECH OUTPUT: 'Orca Keyboard Commands'",
+     "SPEECH OUTPUT: 'link'",
+     "SPEECH OUTPUT: '(Laptop Layout)'",
+     "SPEECH OUTPUT: 'link'",
+     "SPEECH OUTPUT: 'for more information on Orca-specific keyboard commands.'",
+     "SPEECH OUTPUT: 'The'",
+     "SPEECH OUTPUT: 'Orca Configuration GUI'",
+     "SPEECH OUTPUT: 'link'",
+     "SPEECH OUTPUT: 'also includes a \"Key Bindings\" tab that allows you to get a complete list of Orca 
key bindings.'",
+     "SPEECH OUTPUT: 'Please also refer to the'",
+     "SPEECH OUTPUT: 'Configuration/Use page'",
+     "SPEECH OUTPUT: 'link'",
+     "SPEECH OUTPUT: 'for detailed information.'",
+     "SPEECH OUTPUT: 'Accessible Applications'",
+     "SPEECH OUTPUT: 'heading level 1'",
+     "SPEECH OUTPUT: 'Orca is designed to work with applications and toolkits that support the assistive 
technology service provider interface (AT-SPI).'",
+     "SPEECH OUTPUT: 'This includes the GNOME desktop and its applications,'",
+     "SPEECH OUTPUT: 'OpenOffice'",
+     "SPEECH OUTPUT: 'link'",
+     "SPEECH OUTPUT: ', Firefox, and the Java platform.'",
+     "SPEECH OUTPUT: 'Some applications work better than others, however, and the Orca community continually 
works to provide compelling access to more and more applications.'",
+     "SPEECH OUTPUT: 'On the'",
+     "SPEECH OUTPUT: 'Accessible Applications page'",
+     "SPEECH OUTPUT: 'link'",
+     "SPEECH OUTPUT: ', you will find a growing list of information regarding various applications that can 
be accessed with Orca as well as tips and tricks for using them.'",
+     "SPEECH OUTPUT: 'The list is not to be a conclusive list of all applications.'",
+     "SPEECH OUTPUT: 'Rather, the goal is to provide a repository within which users can share experiences 
regarding applications they have tested.'",
+     "SPEECH OUTPUT: 'See also the'",
+     "SPEECH OUTPUT: 'Application Specific Settings'",
+     "SPEECH OUTPUT: 'link'",
+     "SPEECH OUTPUT: 'page for how to configure settings specific to an application.'",
+     "SPEECH OUTPUT: 'Please also refer to the'",
+     "SPEECH OUTPUT: 'Accessible Applications page'",
+     "SPEECH OUTPUT: 'link'",
+     "SPEECH OUTPUT: 'for detailed information.'",
+     "SPEECH OUTPUT: 'How Can I Help?'",
+     "SPEECH OUTPUT: 'heading level 1'",
+     "SPEECH OUTPUT: 'There's a bunch you can do!'",
+     "SPEECH OUTPUT: 'Please refer to the'",
+     "SPEECH OUTPUT: 'How Can I Help page'",
+     "SPEECH OUTPUT: 'link'",
+     "SPEECH OUTPUT: 'for detailed information.'",
+     "SPEECH OUTPUT: 'More Information'",
+     "SPEECH OUTPUT: 'heading level 1'",
+     "SPEECH OUTPUT: '•'",
+     "SPEECH OUTPUT: 'Frequently Asked Questions:'",
+     "SPEECH OUTPUT: 'FAQ'",
+     "SPEECH OUTPUT: 'link'",
+     "SPEECH OUTPUT: '•'",
+     "SPEECH OUTPUT: 'Mailing list:'",
+     "SPEECH OUTPUT: 'orca-list gnome org'",
+     "SPEECH OUTPUT: 'link'",
+     "SPEECH OUTPUT: '('",
+     "SPEECH OUTPUT: 'Archives'",
+     "SPEECH OUTPUT: 'link'",
+     "SPEECH OUTPUT: ')'",
+     "SPEECH OUTPUT: '•'",
+     "SPEECH OUTPUT: 'Bug database:'",
+     "SPEECH OUTPUT: 'GNOME Bug Tracking System (Bugzilla)'",
+     "SPEECH OUTPUT: 'link'",
+     "SPEECH OUTPUT: '('",
+     "SPEECH OUTPUT: 'current bug list'",
+     "SPEECH OUTPUT: 'link'",
+     "SPEECH OUTPUT: ')'",
+     "SPEECH OUTPUT: '•'",
+     "SPEECH OUTPUT: 'Design documents:'",
+     "SPEECH OUTPUT: 'Orca Documentation Series'",
+     "SPEECH OUTPUT: 'link'",
+     "SPEECH OUTPUT: '•'",
+     "SPEECH OUTPUT: 'Dive Into Python, Mark Pilgrim'",
+     "SPEECH OUTPUT: 'link'",
+     "SPEECH OUTPUT: '•'",
+     "SPEECH OUTPUT: 'Python in a Nutshell, Alex Martelli'",
+     "SPEECH OUTPUT: 'link'",
+     "SPEECH OUTPUT: '•'",
+     "SPEECH OUTPUT: 'Python Pocket Reference, Mark Lutz'",
+     "SPEECH OUTPUT: 'link'",
+     "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'",
+     "SPEECH OUTPUT: 'CategoryAccessibility'",
+     "SPEECH OUTPUT: 'link'",
+     "SPEECH OUTPUT: 'Orca (last edited 2007-12-07 22:09:22 by'",
+     "SPEECH OUTPUT: 'WillieWalker'",
+     "SPEECH OUTPUT: 'link'",
+     "SPEECH OUTPUT: ')'",
+     "SPEECH OUTPUT: 'User'",
+     "SPEECH OUTPUT: 'heading level 3'",
+     "SPEECH OUTPUT: 'Login'",
+     "SPEECH OUTPUT: 'link'",
+     "SPEECH OUTPUT: 'Page'",
+     "SPEECH OUTPUT: 'heading level 3'",
+     "SPEECH OUTPUT: 'Immutable Page'",
+     "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'",
+     "SPEECH OUTPUT: 'heading level 3'",
+     "SPEECH OUTPUT: 'GnomeWorldWide'",
+     "SPEECH OUTPUT: 'image'",
+     "SPEECH OUTPUT: 'link'",
+     "SPEECH OUTPUT: 'Copyright \xa9 2005, 2006, 2007'",
+     "SPEECH OUTPUT: 'The GNOME Project'",
+     "SPEECH OUTPUT: 'link'",
+     "SPEECH OUTPUT: '.'",
+     "SPEECH OUTPUT: 'Hosted by'",
+     "SPEECH OUTPUT: 'Red Hat'",
+     "SPEECH OUTPUT: 'link'",
+     "SPEECH OUTPUT: '.'"]))
+
+sequence.append(utils.AssertionSummaryAction())
+sequence.start()
diff --git a/test/keystrokes/firefox/say_all_wiki_no_context.settings 
b/test/keystrokes/firefox/say_all_wiki_no_context.settings
new file mode 100644
index 0000000..e6a6d5c
--- /dev/null
+++ b/test/keystrokes/firefox/say_all_wiki_no_context.settings
@@ -0,0 +1,165 @@
+{
+    "general": {
+        "enabledSpokenTextAttributes": "size:; family-name:; weight:400; indent:0; underline:none; 
strikethrough:false; justification:left; style:normal; paragraph-style:; text-spelling:none; fg-color:; 
bg-color:;",
+        "orcaModifierKeys": [
+            "Insert",
+            "KP_Insert"
+        ],
+        "skipBlankCells": false,
+        "onlySpeakDisplayedText": false,
+        "enableMnemonicSpeaking": false,
+        "chatAnnounceBuddyTyping": false,
+        "messagesAreDetailed": true,
+        "speakProgressBarUpdates": true,
+        "speakCellCoordinates": true,
+        "enableAlphabeticKeys": true,
+        "enableBraille": false,
+        "brailleAlignmentStyle": 0,
+        "playSoundForPositionInSet": false,
+        "sayAllStyle": 1,
+        "enableEchoBySentence": false,
+        "chatSpeakRoomName": false,
+        "soundVolume": 0.5,
+        "activeProfile": [
+            "Default",
+            "default"
+        ],
+        "brailleVerbosityLevel": 1,
+        "sayAllContextTable": false,
+        "enableTutorialMessages": false,
+        "wrappedStructuralNavigation": true,
+        "capitalizationStyle": "none",
+        "findResultsMinimumLength": 4,
+        "enableContractedBraille": false,
+        "presentDateFormat": "%x",
+        "enableSpeechIndentation": false,
+        "brailleContractionTable": "",
+        "structNavTriggersFocusMode": false,
+        "enablePauseBreaks": true,
+        "speakNumbersAsDigits": false,
+        "spellcheckSpellError": true,
+        "useColorNames": true,
+        "speakContextTable": false,
+        "readFullRowInGUITable": true,
+        "enabledBrailledTextAttributes": "size:; family-name:; weight:400; indent:0; underline:none; 
strikethrough:false; justification:left; style:normal; text-spelling:none;",
+        "enableSpace": true,
+        "brailleSelectorIndicator": 192,
+        "profile": [
+            "Default",
+            "default"
+        ],
+        "verbalizePunctuationStyle": 1,
+        "enableBrailleContext": true,
+        "enableNavigationKeys": false,
+        "structNavInSayAll": false,
+        "enableSound": true,
+        "speakCellSpan": true,
+        "speechVerbosityLevel": 1,
+        "brailleRolenameStyle": 1,
+        "mouseDwellDelay": null,
+        "enableSpeech": true,
+        "caretNavTriggersFocusMode": false,
+        "enableDiacriticalKeys": false,
+        "findResultsVerbosity": 2,
+        "sayAllContextBlockquote": false,
+        "speakBlankLines": true,
+        "speakSpreadsheetCoordinates": true,
+        "flashIsPersistent": false,
+        "enableNumericKeys": true,
+        "enableFlashMessages": true,
+        "progressBarVerbosity": 1,
+        "brailleLinkIndicator": 192,
+        "presentTimeFormat": "%X",
+        "enablePunctuationKeys": true,
+        "enableKeyEcho": false,
+        "playSoundForState": false,
+        "beepProgressBarUpdates": false,
+        "enableFunctionKeys": true,
+        "speakMisspelledIndicator": true,
+        "textAttributesBrailleIndicator": 0,
+        "voices": {
+            "default": {
+                "established": false
+            },
+            "system": {
+                "average-pitch": 3.0
+            },
+            "uppercase": {
+                "average-pitch": 7.0
+            },
+            "hyperlink": {
+                "established": false
+            }
+        },
+        "enableBrailleMonitor": true,
+        "layoutMode": true,
+        "brailleFlashTime": 5000,
+        "largeObjectTextLength": 75,
+        "speakContextList": false,
+        "ignoreStatusBarProgressBars": true,
+        "keyboardLayout": 1,
+        "brailleProgressBarUpdates": false,
+        "readFullRowInSpreadSheet": false,
+        "enableActionKeys": true,
+        "enablePositionSpeaking": false,
+        "structuralNavigationEnabled": true,
+        "playSoundForRole": false,
+        "disableBrailleEOL": false,
+        "presentToolTips": false,
+        "enableMouseReview": false,
+        "speechServerFactory": "speechdispatcherfactory",
+        "chatMessageVerbosity": 0,
+        "enableEchoByWord": false,
+        "spellcheckSpellSuggestion": true,
+        "enableModifierKeys": true,
+        "speakMultiCaseStringsAsWords": false,
+        "flashIsDetailed": true,
+        "speakCellHeaders": true,
+        "rewindAndFastForwardInSayAll": false,
+        "sayAllContextList": false,
+        "speakContextBlockquote": false,
+        "enableEchoByCharacter": false,
+        "playSoundForValue": false,
+        "progressBarUpdateInterval": 10,
+        "spellcheckPresentContext": true,
+        "speechServerInfo": null,
+        "chatRoomHistories": false,
+        "readFullRowInDocumentTable": true,
+        "startingProfile": [
+            "Default",
+            "default"
+        ]
+    },
+    "keybindings": {},
+    "profiles": {
+        "default": {
+            "profile": [
+                "Default",
+                "default"
+            ],
+            "brailleContractionTable": "/usr/share/liblouis/tables/en-us-compbrl.ctb",
+            "voices": {
+                "default": {
+                    "established": false
+                },
+                "system": {
+                    "average-pitch": 3.0
+                },
+                "uppercase": {
+                    "average-pitch": 7.0
+                },
+                "hyperlink": {
+                    "established": false
+                }
+            },
+            "pronunciations": {},
+            "speechServerInfo": [
+                "Default Synthesizer",
+                "default"
+            ],
+            "keybindings": {},
+            "speechServerFactory": "orca.speechdispatcherfactory"
+        }
+    },
+    "pronunciations": {}
+}
\ No newline at end of file
diff --git a/test/keystrokes/oocalc/document_enter_text.settings 
b/test/keystrokes/oocalc/document_enter_text.settings
new file mode 100644
index 0000000..36a47f6
--- /dev/null
+++ b/test/keystrokes/oocalc/document_enter_text.settings
@@ -0,0 +1,165 @@
+{
+    "general": {
+        "enabledSpokenTextAttributes": "size:; family-name:; weight:400; indent:0; underline:none; 
strikethrough:false; justification:left; style:normal; paragraph-style:; text-spelling:none; fg-color:; 
bg-color:;",
+        "orcaModifierKeys": [
+            "Insert",
+            "KP_Insert"
+        ],
+        "skipBlankCells": false,
+        "onlySpeakDisplayedText": false,
+        "enableMnemonicSpeaking": false,
+        "chatAnnounceBuddyTyping": false,
+        "messagesAreDetailed": true,
+        "speakProgressBarUpdates": true,
+        "speakCellCoordinates": true,
+        "enableAlphabeticKeys": true,
+        "enableBraille": false,
+        "brailleAlignmentStyle": 0,
+        "playSoundForPositionInSet": false,
+        "sayAllStyle": 1,
+        "enableEchoBySentence": false,
+        "chatSpeakRoomName": false,
+        "soundVolume": 0.5,
+        "activeProfile": [
+            "Default",
+            "default"
+        ],
+        "brailleVerbosityLevel": 1,
+        "sayAllContextTable": true,
+        "enableTutorialMessages": false,
+        "wrappedStructuralNavigation": true,
+        "capitalizationStyle": "none",
+        "findResultsMinimumLength": 4,
+        "enableContractedBraille": false,
+        "presentDateFormat": "%x",
+        "enableSpeechIndentation": false,
+        "brailleContractionTable": "",
+        "structNavTriggersFocusMode": false,
+        "enablePauseBreaks": true,
+        "speakNumbersAsDigits": false,
+        "spellcheckSpellError": true,
+        "useColorNames": true,
+        "speakContextTable": true,
+        "readFullRowInGUITable": true,
+        "enabledBrailledTextAttributes": "size:; family-name:; weight:400; indent:0; underline:none; 
strikethrough:false; justification:left; style:normal; text-spelling:none;",
+        "enableSpace": true,
+        "brailleSelectorIndicator": 192,
+        "profile": [
+            "Default",
+            "default"
+        ],
+        "verbalizePunctuationStyle": 1,
+        "enableBrailleContext": true,
+        "enableNavigationKeys": false,
+        "structNavInSayAll": false,
+        "enableSound": true,
+        "speakCellSpan": true,
+        "speechVerbosityLevel": 1,
+        "brailleRolenameStyle": 1,
+        "mouseDwellDelay": null,
+        "enableSpeech": true,
+        "caretNavTriggersFocusMode": false,
+        "enableDiacriticalKeys": false,
+        "findResultsVerbosity": 2,
+        "sayAllContextBlockquote": true,
+        "speakBlankLines": true,
+        "speakSpreadsheetCoordinates": true,
+        "flashIsPersistent": false,
+        "enableNumericKeys": true,
+        "enableFlashMessages": true,
+        "progressBarVerbosity": 1,
+        "brailleLinkIndicator": 192,
+        "presentTimeFormat": "%X",
+        "enablePunctuationKeys": true,
+        "enableKeyEcho": false,
+        "playSoundForState": false,
+        "beepProgressBarUpdates": false,
+        "enableFunctionKeys": true,
+        "speakMisspelledIndicator": true,
+        "textAttributesBrailleIndicator": 0,
+        "voices": {
+            "default": {
+                "established": false
+            },
+            "system": {
+                "established": false
+             },
+            "uppercase": {
+                "average-pitch": 7.0
+            },
+            "hyperlink": {
+                "established": false
+            }
+        },
+        "enableBrailleMonitor": true,
+        "layoutMode": true,
+        "brailleFlashTime": 5000,
+        "largeObjectTextLength": 75,
+        "speakContextList": true,
+        "ignoreStatusBarProgressBars": true,
+        "keyboardLayout": 1,
+        "brailleProgressBarUpdates": false,
+        "readFullRowInSpreadSheet": false,
+        "enableActionKeys": true,
+        "enablePositionSpeaking": false,
+        "structuralNavigationEnabled": true,
+        "playSoundForRole": false,
+        "disableBrailleEOL": false,
+        "presentToolTips": false,
+        "enableMouseReview": false,
+        "speechServerFactory": "speechdispatcherfactory",
+        "chatMessageVerbosity": 0,
+        "enableEchoByWord": false,
+        "spellcheckSpellSuggestion": true,
+        "enableModifierKeys": true,
+        "speakMultiCaseStringsAsWords": false,
+        "flashIsDetailed": true,
+        "speakCellHeaders": true,
+        "rewindAndFastForwardInSayAll": false,
+        "sayAllContextList": true,
+        "speakContextBlockquote": true,
+        "enableEchoByCharacter": false,
+        "playSoundForValue": false,
+        "progressBarUpdateInterval": 10,
+        "spellcheckPresentContext": true,
+        "speechServerInfo": null,
+        "chatRoomHistories": false,
+        "readFullRowInDocumentTable": true,
+        "startingProfile": [
+            "Default",
+            "default"
+        ]
+    },
+    "keybindings": {},
+    "profiles": {
+        "default": {
+            "profile": [
+                "Default",
+                "default"
+            ],
+            "brailleContractionTable": "/usr/share/liblouis/tables/en-us-compbrl.ctb",
+            "voices": {
+                "default": {
+                    "established": false
+                },
+                "system": {
+                    "established": false
+                },
+                "uppercase": {
+                    "average-pitch": 7.0
+                },
+                "hyperlink": {
+                    "established": false
+                }
+            },
+            "pronunciations": {},
+            "speechServerInfo": [
+                "Default Synthesizer",
+                "default"
+            ],
+            "keybindings": {},
+            "speechServerFactory": "orca.speechdispatcherfactory"
+        }
+    },
+    "pronunciations": {}
+}
\ No newline at end of file
diff --git a/test/keystrokes/oocalc/document_enter_text_no_context.py 
b/test/keystrokes/oocalc/document_enter_text_no_context.py
new file mode 100644
index 0000000..630bfdc
--- /dev/null
+++ b/test/keystrokes/oocalc/document_enter_text_no_context.py
@@ -0,0 +1,40 @@
+#!/usr/bin/python
+
+"""Test of presentation when typing in a cell."""
+
+from macaroon.playback import *
+import utils
+
+sequence = MacroSequence()
+
+sequence.append(PauseAction(3000))
+
+sequence.append(utils.StartRecordingAction())
+sequence.append(TypeAction("h"))
+sequence.append(utils.AssertPresentationAction(
+    "1. Type 'h' - keyecho is off",
+    ["BRAILLE LINE:  'Untitled 1 - LibreOffice Calc frame Untitled 1 - LibreOffice Calc root pane Untitled1 
- LibreOffice Spreadsheets Cell A1 panel Paragraph 0 h $l'",
+     "     VISIBLE:  'Paragraph 0 h $l', cursor=14",
+     "SPEECH OUTPUT: 'Cell A1 panel'",
+     "SPEECH OUTPUT: 'Paragraph 0 h'"]))
+
+sequence.append(utils.StartRecordingAction())
+sequence.append(TypeAction("i"))
+sequence.append(utils.AssertPresentationAction(
+    "2. Type 'i' - keyecho is off",
+    ["BRAILLE LINE:  'Untitled 1 - LibreOffice Calc frame Untitled 1 - LibreOffice Calc root pane Untitled1 
- LibreOffice Spreadsheets Cell A1 panel Paragraph 0 hi $l'",
+     "     VISIBLE:  'Paragraph 0 hi $l', cursor=15",
+     "BRAILLE LINE:  'Untitled 1 - LibreOffice Calc frame Untitled 1 - LibreOffice Calc root pane Untitled1 
- LibreOffice Spreadsheets Cell A1 panel Paragraph 0 hi $l'",
+     "     VISIBLE:  'Paragraph 0 hi $l', cursor=15"]))
+
+sequence.append(utils.StartRecordingAction())
+sequence.append(KeyComboAction("Return"))
+sequence.append(PauseAction(3000))
+sequence.append(utils.AssertPresentationAction(
+    "3. Press Return",
+    ["BRAILLE LINE:  'Untitled 1 - LibreOffice Calc frame Untitled 1 - LibreOffice Calc root pane Untitled1 
- LibreOffice Spreadsheets Sheet Sheet1 table  A2'",
+     "     VISIBLE:  ' A2', cursor=1",
+     "SPEECH OUTPUT: 'blank A2.'"]))
+
+sequence.append(utils.AssertionSummaryAction())
+sequence.start()
diff --git a/test/keystrokes/oocalc/document_enter_text_no_context.settings 
b/test/keystrokes/oocalc/document_enter_text_no_context.settings
new file mode 100644
index 0000000..da835ea
--- /dev/null
+++ b/test/keystrokes/oocalc/document_enter_text_no_context.settings
@@ -0,0 +1,165 @@
+{
+    "general": {
+        "enabledSpokenTextAttributes": "size:; family-name:; weight:400; indent:0; underline:none; 
strikethrough:false; justification:left; style:normal; paragraph-style:; text-spelling:none; fg-color:; 
bg-color:;",
+        "orcaModifierKeys": [
+            "Insert",
+            "KP_Insert"
+        ],
+        "skipBlankCells": false,
+        "onlySpeakDisplayedText": false,
+        "enableMnemonicSpeaking": false,
+        "chatAnnounceBuddyTyping": false,
+        "messagesAreDetailed": true,
+        "speakProgressBarUpdates": true,
+        "speakCellCoordinates": true,
+        "enableAlphabeticKeys": true,
+        "enableBraille": false,
+        "brailleAlignmentStyle": 0,
+        "playSoundForPositionInSet": false,
+        "sayAllStyle": 1,
+        "enableEchoBySentence": false,
+        "chatSpeakRoomName": false,
+        "soundVolume": 0.5,
+        "activeProfile": [
+            "Default",
+            "default"
+        ],
+        "brailleVerbosityLevel": 1,
+        "sayAllContextTable": false,
+        "enableTutorialMessages": false,
+        "wrappedStructuralNavigation": true,
+        "capitalizationStyle": "none",
+        "findResultsMinimumLength": 4,
+        "enableContractedBraille": false,
+        "presentDateFormat": "%x",
+        "enableSpeechIndentation": false,
+        "brailleContractionTable": "",
+        "structNavTriggersFocusMode": false,
+        "enablePauseBreaks": true,
+        "speakNumbersAsDigits": false,
+        "spellcheckSpellError": true,
+        "useColorNames": true,
+        "speakContextTable": false,
+        "readFullRowInGUITable": true,
+        "enabledBrailledTextAttributes": "size:; family-name:; weight:400; indent:0; underline:none; 
strikethrough:false; justification:left; style:normal; text-spelling:none;",
+        "enableSpace": true,
+        "brailleSelectorIndicator": 192,
+        "profile": [
+            "Default",
+            "default"
+        ],
+        "verbalizePunctuationStyle": 1,
+        "enableBrailleContext": true,
+        "enableNavigationKeys": false,
+        "structNavInSayAll": false,
+        "enableSound": true,
+        "speakCellSpan": true,
+        "speechVerbosityLevel": 1,
+        "brailleRolenameStyle": 1,
+        "mouseDwellDelay": null,
+        "enableSpeech": true,
+        "caretNavTriggersFocusMode": false,
+        "enableDiacriticalKeys": false,
+        "findResultsVerbosity": 2,
+        "sayAllContextBlockquote": false,
+        "speakBlankLines": true,
+        "speakSpreadsheetCoordinates": true,
+        "flashIsPersistent": false,
+        "enableNumericKeys": true,
+        "enableFlashMessages": true,
+        "progressBarVerbosity": 1,
+        "brailleLinkIndicator": 192,
+        "presentTimeFormat": "%X",
+        "enablePunctuationKeys": true,
+        "enableKeyEcho": false,
+        "playSoundForState": false,
+        "beepProgressBarUpdates": false,
+        "enableFunctionKeys": true,
+        "speakMisspelledIndicator": true,
+        "textAttributesBrailleIndicator": 0,
+        "voices": {
+            "default": {
+                "established": false
+            },
+            "system": {
+                "established": false
+            },
+            "uppercase": {
+                "average-pitch": 7.0
+            },
+            "hyperlink": {
+                "established": false
+            }
+        },
+        "enableBrailleMonitor": true,
+        "layoutMode": true,
+        "brailleFlashTime": 5000,
+        "largeObjectTextLength": 75,
+        "speakContextList": false,
+        "ignoreStatusBarProgressBars": true,
+        "keyboardLayout": 1,
+        "brailleProgressBarUpdates": false,
+        "readFullRowInSpreadSheet": false,
+        "enableActionKeys": true,
+        "enablePositionSpeaking": false,
+        "structuralNavigationEnabled": true,
+        "playSoundForRole": false,
+        "disableBrailleEOL": false,
+        "presentToolTips": false,
+        "enableMouseReview": false,
+        "speechServerFactory": "speechdispatcherfactory",
+        "chatMessageVerbosity": 0,
+        "enableEchoByWord": false,
+        "spellcheckSpellSuggestion": true,
+        "enableModifierKeys": true,
+        "speakMultiCaseStringsAsWords": false,
+        "flashIsDetailed": true,
+        "speakCellHeaders": true,
+        "rewindAndFastForwardInSayAll": false,
+        "sayAllContextList": false,
+        "speakContextBlockquote": false,
+        "enableEchoByCharacter": false,
+        "playSoundForValue": false,
+        "progressBarUpdateInterval": 10,
+        "spellcheckPresentContext": true,
+        "speechServerInfo": null,
+        "chatRoomHistories": false,
+        "readFullRowInDocumentTable": true,
+        "startingProfile": [
+            "Default",
+            "default"
+        ]
+    },
+    "keybindings": {},
+    "profiles": {
+        "default": {
+            "profile": [
+                "Default",
+                "default"
+            ],
+            "brailleContractionTable": "/usr/share/liblouis/tables/en-us-compbrl.ctb",
+            "voices": {
+                "default": {
+                    "established": false
+                },
+                "system": {
+                    "established": false
+                 },
+                "uppercase": {
+                    "average-pitch": 7.0
+                },
+                "hyperlink": {
+                    "established": false
+                }
+            },
+            "pronunciations": {},
+            "speechServerInfo": [
+                "Default Synthesizer",
+                "default"
+            ],
+            "keybindings": {},
+            "speechServerFactory": "orca.speechdispatcherfactory"
+        }
+    },
+    "pronunciations": {}
+}
\ No newline at end of file
diff --git a/test/keystrokes/oocalc/document_nav_dynamic_headers.py 
b/test/keystrokes/oocalc/document_nav_dynamic_headers.py
index 37fcc7f..8f758e6 100644
--- a/test/keystrokes/oocalc/document_nav_dynamic_headers.py
+++ b/test/keystrokes/oocalc/document_nav_dynamic_headers.py
@@ -9,6 +9,7 @@ sequence = MacroSequence()
 
 sequence.append(PauseAction(3000))
 sequence.append(KeyComboAction("<Control>Home"))
+sequence.append(PauseAction(3000))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
diff --git a/test/keystrokes/oocalc/manage_names_combobox.settings 
b/test/keystrokes/oocalc/manage_names_combobox.settings
new file mode 100644
index 0000000..36a47f6
--- /dev/null
+++ b/test/keystrokes/oocalc/manage_names_combobox.settings
@@ -0,0 +1,165 @@
+{
+    "general": {
+        "enabledSpokenTextAttributes": "size:; family-name:; weight:400; indent:0; underline:none; 
strikethrough:false; justification:left; style:normal; paragraph-style:; text-spelling:none; fg-color:; 
bg-color:;",
+        "orcaModifierKeys": [
+            "Insert",
+            "KP_Insert"
+        ],
+        "skipBlankCells": false,
+        "onlySpeakDisplayedText": false,
+        "enableMnemonicSpeaking": false,
+        "chatAnnounceBuddyTyping": false,
+        "messagesAreDetailed": true,
+        "speakProgressBarUpdates": true,
+        "speakCellCoordinates": true,
+        "enableAlphabeticKeys": true,
+        "enableBraille": false,
+        "brailleAlignmentStyle": 0,
+        "playSoundForPositionInSet": false,
+        "sayAllStyle": 1,
+        "enableEchoBySentence": false,
+        "chatSpeakRoomName": false,
+        "soundVolume": 0.5,
+        "activeProfile": [
+            "Default",
+            "default"
+        ],
+        "brailleVerbosityLevel": 1,
+        "sayAllContextTable": true,
+        "enableTutorialMessages": false,
+        "wrappedStructuralNavigation": true,
+        "capitalizationStyle": "none",
+        "findResultsMinimumLength": 4,
+        "enableContractedBraille": false,
+        "presentDateFormat": "%x",
+        "enableSpeechIndentation": false,
+        "brailleContractionTable": "",
+        "structNavTriggersFocusMode": false,
+        "enablePauseBreaks": true,
+        "speakNumbersAsDigits": false,
+        "spellcheckSpellError": true,
+        "useColorNames": true,
+        "speakContextTable": true,
+        "readFullRowInGUITable": true,
+        "enabledBrailledTextAttributes": "size:; family-name:; weight:400; indent:0; underline:none; 
strikethrough:false; justification:left; style:normal; text-spelling:none;",
+        "enableSpace": true,
+        "brailleSelectorIndicator": 192,
+        "profile": [
+            "Default",
+            "default"
+        ],
+        "verbalizePunctuationStyle": 1,
+        "enableBrailleContext": true,
+        "enableNavigationKeys": false,
+        "structNavInSayAll": false,
+        "enableSound": true,
+        "speakCellSpan": true,
+        "speechVerbosityLevel": 1,
+        "brailleRolenameStyle": 1,
+        "mouseDwellDelay": null,
+        "enableSpeech": true,
+        "caretNavTriggersFocusMode": false,
+        "enableDiacriticalKeys": false,
+        "findResultsVerbosity": 2,
+        "sayAllContextBlockquote": true,
+        "speakBlankLines": true,
+        "speakSpreadsheetCoordinates": true,
+        "flashIsPersistent": false,
+        "enableNumericKeys": true,
+        "enableFlashMessages": true,
+        "progressBarVerbosity": 1,
+        "brailleLinkIndicator": 192,
+        "presentTimeFormat": "%X",
+        "enablePunctuationKeys": true,
+        "enableKeyEcho": false,
+        "playSoundForState": false,
+        "beepProgressBarUpdates": false,
+        "enableFunctionKeys": true,
+        "speakMisspelledIndicator": true,
+        "textAttributesBrailleIndicator": 0,
+        "voices": {
+            "default": {
+                "established": false
+            },
+            "system": {
+                "established": false
+             },
+            "uppercase": {
+                "average-pitch": 7.0
+            },
+            "hyperlink": {
+                "established": false
+            }
+        },
+        "enableBrailleMonitor": true,
+        "layoutMode": true,
+        "brailleFlashTime": 5000,
+        "largeObjectTextLength": 75,
+        "speakContextList": true,
+        "ignoreStatusBarProgressBars": true,
+        "keyboardLayout": 1,
+        "brailleProgressBarUpdates": false,
+        "readFullRowInSpreadSheet": false,
+        "enableActionKeys": true,
+        "enablePositionSpeaking": false,
+        "structuralNavigationEnabled": true,
+        "playSoundForRole": false,
+        "disableBrailleEOL": false,
+        "presentToolTips": false,
+        "enableMouseReview": false,
+        "speechServerFactory": "speechdispatcherfactory",
+        "chatMessageVerbosity": 0,
+        "enableEchoByWord": false,
+        "spellcheckSpellSuggestion": true,
+        "enableModifierKeys": true,
+        "speakMultiCaseStringsAsWords": false,
+        "flashIsDetailed": true,
+        "speakCellHeaders": true,
+        "rewindAndFastForwardInSayAll": false,
+        "sayAllContextList": true,
+        "speakContextBlockquote": true,
+        "enableEchoByCharacter": false,
+        "playSoundForValue": false,
+        "progressBarUpdateInterval": 10,
+        "spellcheckPresentContext": true,
+        "speechServerInfo": null,
+        "chatRoomHistories": false,
+        "readFullRowInDocumentTable": true,
+        "startingProfile": [
+            "Default",
+            "default"
+        ]
+    },
+    "keybindings": {},
+    "profiles": {
+        "default": {
+            "profile": [
+                "Default",
+                "default"
+            ],
+            "brailleContractionTable": "/usr/share/liblouis/tables/en-us-compbrl.ctb",
+            "voices": {
+                "default": {
+                    "established": false
+                },
+                "system": {
+                    "established": false
+                },
+                "uppercase": {
+                    "average-pitch": 7.0
+                },
+                "hyperlink": {
+                    "established": false
+                }
+            },
+            "pronunciations": {},
+            "speechServerInfo": [
+                "Default Synthesizer",
+                "default"
+            ],
+            "keybindings": {},
+            "speechServerFactory": "orca.speechdispatcherfactory"
+        }
+    },
+    "pronunciations": {}
+}
\ No newline at end of file
diff --git a/test/keystrokes/oocalc/manage_names_combobox_no_context.py 
b/test/keystrokes/oocalc/manage_names_combobox_no_context.py
new file mode 100644
index 0000000..9e2fd7b
--- /dev/null
+++ b/test/keystrokes/oocalc/manage_names_combobox_no_context.py
@@ -0,0 +1,43 @@
+#!/usr/bin/python
+
+"""Test presentation of the Manage Names combobox"""
+
+from macaroon.playback import *
+import utils
+
+sequence = MacroSequence()
+sequence.append(PauseAction(5000))
+
+sequence.append(utils.StartRecordingAction())
+sequence.append(KeyComboAction("<Shift><Control>t"))
+sequence.append(utils.AssertPresentationAction(
+    "1. Shift+Ctrl+T",
+    ["BRAILLE LINE:  'Untitled 1 - LibreOffice Calc frame Untitled 1 - LibreOffice Calc root pane Formula 
Tool Bar tool bar A1 $l combo box'",
+     "     VISIBLE:  'A1 $l combo box', cursor=3",
+     "SPEECH OUTPUT: 'Formula Tool Bar tool bar'",
+     "SPEECH OUTPUT: 'Name Box editable combo box.'",
+     "SPEECH OUTPUT: 'A1 selected'"]))
+
+sequence.append(KeyComboAction("<Control>a"))
+sequence.append(KeyComboAction("BackSpace"))
+sequence.append(PauseAction(3000))
+
+sequence.append(utils.StartRecordingAction())
+sequence.append(TypeAction("C3"))
+sequence.append(utils.AssertPresentationAction(
+    "2. Type 'C3' - keyecho is disabled",
+    ["BRAILLE LINE:  'Untitled 1 - LibreOffice Calc frame Untitled 1 - LibreOffice Calc root pane Formula 
Tool Bar tool bar Name Box C $l'",
+     "     VISIBLE:  'C $l', cursor=2",
+     "BRAILLE LINE:  'Untitled 1 - LibreOffice Calc frame Untitled 1 - LibreOffice Calc root pane Formula 
Tool Bar tool bar Name Box C3 $l'",
+     "     VISIBLE:  'C3 $l', cursor=3"]))
+
+sequence.append(utils.StartRecordingAction())
+sequence.append(KeyComboAction("Return"))
+sequence.append(utils.AssertPresentationAction(
+    "3. Press Return to jump to C3",
+    ["BRAILLE LINE:  'Untitled 1 - LibreOffice Calc frame Untitled 1 - LibreOffice Calc root pane Untitled1 
- LibreOffice Spreadsheets Sheet Sheet1 table  C3'",
+     "     VISIBLE:  ' C3', cursor=1",
+     "SPEECH OUTPUT: 'blank C3.'"]))
+
+sequence.append(utils.AssertionSummaryAction())
+sequence.start()
diff --git a/test/keystrokes/oocalc/manage_names_combobox_no_context.settings 
b/test/keystrokes/oocalc/manage_names_combobox_no_context.settings
new file mode 100644
index 0000000..da835ea
--- /dev/null
+++ b/test/keystrokes/oocalc/manage_names_combobox_no_context.settings
@@ -0,0 +1,165 @@
+{
+    "general": {
+        "enabledSpokenTextAttributes": "size:; family-name:; weight:400; indent:0; underline:none; 
strikethrough:false; justification:left; style:normal; paragraph-style:; text-spelling:none; fg-color:; 
bg-color:;",
+        "orcaModifierKeys": [
+            "Insert",
+            "KP_Insert"
+        ],
+        "skipBlankCells": false,
+        "onlySpeakDisplayedText": false,
+        "enableMnemonicSpeaking": false,
+        "chatAnnounceBuddyTyping": false,
+        "messagesAreDetailed": true,
+        "speakProgressBarUpdates": true,
+        "speakCellCoordinates": true,
+        "enableAlphabeticKeys": true,
+        "enableBraille": false,
+        "brailleAlignmentStyle": 0,
+        "playSoundForPositionInSet": false,
+        "sayAllStyle": 1,
+        "enableEchoBySentence": false,
+        "chatSpeakRoomName": false,
+        "soundVolume": 0.5,
+        "activeProfile": [
+            "Default",
+            "default"
+        ],
+        "brailleVerbosityLevel": 1,
+        "sayAllContextTable": false,
+        "enableTutorialMessages": false,
+        "wrappedStructuralNavigation": true,
+        "capitalizationStyle": "none",
+        "findResultsMinimumLength": 4,
+        "enableContractedBraille": false,
+        "presentDateFormat": "%x",
+        "enableSpeechIndentation": false,
+        "brailleContractionTable": "",
+        "structNavTriggersFocusMode": false,
+        "enablePauseBreaks": true,
+        "speakNumbersAsDigits": false,
+        "spellcheckSpellError": true,
+        "useColorNames": true,
+        "speakContextTable": false,
+        "readFullRowInGUITable": true,
+        "enabledBrailledTextAttributes": "size:; family-name:; weight:400; indent:0; underline:none; 
strikethrough:false; justification:left; style:normal; text-spelling:none;",
+        "enableSpace": true,
+        "brailleSelectorIndicator": 192,
+        "profile": [
+            "Default",
+            "default"
+        ],
+        "verbalizePunctuationStyle": 1,
+        "enableBrailleContext": true,
+        "enableNavigationKeys": false,
+        "structNavInSayAll": false,
+        "enableSound": true,
+        "speakCellSpan": true,
+        "speechVerbosityLevel": 1,
+        "brailleRolenameStyle": 1,
+        "mouseDwellDelay": null,
+        "enableSpeech": true,
+        "caretNavTriggersFocusMode": false,
+        "enableDiacriticalKeys": false,
+        "findResultsVerbosity": 2,
+        "sayAllContextBlockquote": false,
+        "speakBlankLines": true,
+        "speakSpreadsheetCoordinates": true,
+        "flashIsPersistent": false,
+        "enableNumericKeys": true,
+        "enableFlashMessages": true,
+        "progressBarVerbosity": 1,
+        "brailleLinkIndicator": 192,
+        "presentTimeFormat": "%X",
+        "enablePunctuationKeys": true,
+        "enableKeyEcho": false,
+        "playSoundForState": false,
+        "beepProgressBarUpdates": false,
+        "enableFunctionKeys": true,
+        "speakMisspelledIndicator": true,
+        "textAttributesBrailleIndicator": 0,
+        "voices": {
+            "default": {
+                "established": false
+            },
+            "system": {
+                "established": false
+            },
+            "uppercase": {
+                "average-pitch": 7.0
+            },
+            "hyperlink": {
+                "established": false
+            }
+        },
+        "enableBrailleMonitor": true,
+        "layoutMode": true,
+        "brailleFlashTime": 5000,
+        "largeObjectTextLength": 75,
+        "speakContextList": false,
+        "ignoreStatusBarProgressBars": true,
+        "keyboardLayout": 1,
+        "brailleProgressBarUpdates": false,
+        "readFullRowInSpreadSheet": false,
+        "enableActionKeys": true,
+        "enablePositionSpeaking": false,
+        "structuralNavigationEnabled": true,
+        "playSoundForRole": false,
+        "disableBrailleEOL": false,
+        "presentToolTips": false,
+        "enableMouseReview": false,
+        "speechServerFactory": "speechdispatcherfactory",
+        "chatMessageVerbosity": 0,
+        "enableEchoByWord": false,
+        "spellcheckSpellSuggestion": true,
+        "enableModifierKeys": true,
+        "speakMultiCaseStringsAsWords": false,
+        "flashIsDetailed": true,
+        "speakCellHeaders": true,
+        "rewindAndFastForwardInSayAll": false,
+        "sayAllContextList": false,
+        "speakContextBlockquote": false,
+        "enableEchoByCharacter": false,
+        "playSoundForValue": false,
+        "progressBarUpdateInterval": 10,
+        "spellcheckPresentContext": true,
+        "speechServerInfo": null,
+        "chatRoomHistories": false,
+        "readFullRowInDocumentTable": true,
+        "startingProfile": [
+            "Default",
+            "default"
+        ]
+    },
+    "keybindings": {},
+    "profiles": {
+        "default": {
+            "profile": [
+                "Default",
+                "default"
+            ],
+            "brailleContractionTable": "/usr/share/liblouis/tables/en-us-compbrl.ctb",
+            "voices": {
+                "default": {
+                    "established": false
+                },
+                "system": {
+                    "established": false
+                 },
+                "uppercase": {
+                    "average-pitch": 7.0
+                },
+                "hyperlink": {
+                    "established": false
+                }
+            },
+            "pronunciations": {},
+            "speechServerInfo": [
+                "Default Synthesizer",
+                "default"
+            ],
+            "keybindings": {},
+            "speechServerFactory": "orca.speechdispatcherfactory"
+        }
+    },
+    "pronunciations": {}
+}
\ No newline at end of file
diff --git a/test/keystrokes/oowriter/messages_table.settings 
b/test/keystrokes/oowriter/messages_table.settings
new file mode 100644
index 0000000..d36600d
--- /dev/null
+++ b/test/keystrokes/oowriter/messages_table.settings
@@ -0,0 +1,165 @@
+{
+    "general": {
+        "enabledSpokenTextAttributes": "size:; family-name:; weight:400; indent:0; underline:none; 
strikethrough:false; justification:left; style:normal; paragraph-style:; text-spelling:none; fg-color:; 
bg-color:;",
+        "orcaModifierKeys": [
+            "Insert",
+            "KP_Insert"
+        ],
+        "skipBlankCells": false,
+        "onlySpeakDisplayedText": false,
+        "enableMnemonicSpeaking": false,
+        "chatAnnounceBuddyTyping": false,
+        "messagesAreDetailed": true,
+        "speakProgressBarUpdates": true,
+        "speakCellCoordinates": true,
+        "enableAlphabeticKeys": true,
+        "enableBraille": false,
+        "brailleAlignmentStyle": 0,
+        "playSoundForPositionInSet": false,
+        "sayAllStyle": 1,
+        "enableEchoBySentence": false,
+        "chatSpeakRoomName": false,
+        "soundVolume": 0.5,
+        "activeProfile": [
+            "Default",
+            "default"
+        ],
+        "brailleVerbosityLevel": 1,
+        "sayAllContextTable": true,
+        "enableTutorialMessages": false,
+        "wrappedStructuralNavigation": true,
+        "capitalizationStyle": "none",
+        "findResultsMinimumLength": 4,
+        "enableContractedBraille": false,
+        "presentDateFormat": "%x",
+        "enableSpeechIndentation": false,
+        "brailleContractionTable": "",
+        "structNavTriggersFocusMode": false,
+        "enablePauseBreaks": true,
+        "speakNumbersAsDigits": false,
+        "spellcheckSpellError": true,
+        "useColorNames": true,
+        "speakContextTable": true,
+        "readFullRowInGUITable": true,
+        "enabledBrailledTextAttributes": "size:; family-name:; weight:400; indent:0; underline:none; 
strikethrough:false; justification:left; style:normal; text-spelling:none;",
+        "enableSpace": true,
+        "brailleSelectorIndicator": 192,
+        "profile": [
+            "Default",
+            "default"
+        ],
+        "verbalizePunctuationStyle": 1,
+        "enableBrailleContext": true,
+        "enableNavigationKeys": false,
+        "structNavInSayAll": false,
+        "enableSound": true,
+        "speakCellSpan": true,
+        "speechVerbosityLevel": 1,
+        "brailleRolenameStyle": 1,
+        "mouseDwellDelay": null,
+        "enableSpeech": true,
+        "caretNavTriggersFocusMode": false,
+        "enableDiacriticalKeys": false,
+        "findResultsVerbosity": 2,
+        "sayAllContextBlockquote": true,
+        "speakBlankLines": true,
+        "speakSpreadsheetCoordinates": true,
+        "flashIsPersistent": false,
+        "enableNumericKeys": true,
+        "enableFlashMessages": true,
+        "progressBarVerbosity": 1,
+        "brailleLinkIndicator": 192,
+        "presentTimeFormat": "%X",
+        "enablePunctuationKeys": true,
+        "enableKeyEcho": false,
+        "playSoundForState": false,
+        "beepProgressBarUpdates": false,
+        "enableFunctionKeys": true,
+        "speakMisspelledIndicator": true,
+        "textAttributesBrailleIndicator": 0,
+        "voices": {
+            "default": {
+                "established": false
+            },
+            "system": {
+                "average-pitch": 3.0
+            },
+            "uppercase": {
+                "average-pitch": 7.0
+            },
+            "hyperlink": {
+                "established": false
+            }
+        },
+        "enableBrailleMonitor": true,
+        "layoutMode": true,
+        "brailleFlashTime": 5000,
+        "largeObjectTextLength": 75,
+        "speakContextList": true,
+        "ignoreStatusBarProgressBars": true,
+        "keyboardLayout": 1,
+        "brailleProgressBarUpdates": false,
+        "readFullRowInSpreadSheet": false,
+        "enableActionKeys": true,
+        "enablePositionSpeaking": false,
+        "structuralNavigationEnabled": true,
+        "playSoundForRole": false,
+        "disableBrailleEOL": false,
+        "presentToolTips": false,
+        "enableMouseReview": false,
+        "speechServerFactory": "speechdispatcherfactory",
+        "chatMessageVerbosity": 0,
+        "enableEchoByWord": false,
+        "spellcheckSpellSuggestion": true,
+        "enableModifierKeys": true,
+        "speakMultiCaseStringsAsWords": false,
+        "flashIsDetailed": true,
+        "speakCellHeaders": true,
+        "rewindAndFastForwardInSayAll": false,
+        "sayAllContextList": true,
+        "speakContextBlockquote": true,
+        "enableEchoByCharacter": false,
+        "playSoundForValue": false,
+        "progressBarUpdateInterval": 10,
+        "spellcheckPresentContext": true,
+        "speechServerInfo": null,
+        "chatRoomHistories": false,
+        "readFullRowInDocumentTable": true,
+        "startingProfile": [
+            "Default",
+            "default"
+        ]
+    },
+    "keybindings": {},
+    "profiles": {
+        "default": {
+            "profile": [
+                "Default",
+                "default"
+            ],
+            "brailleContractionTable": "/usr/share/liblouis/tables/en-us-compbrl.ctb",
+            "voices": {
+                "default": {
+                    "established": false
+                },
+                "system": {
+                    "average-pitch": 3.0
+                },
+                "uppercase": {
+                    "average-pitch": 7.0
+                },
+                "hyperlink": {
+                    "established": false
+                }
+            },
+            "pronunciations": {},
+            "speechServerInfo": [
+                "Default Synthesizer",
+                "default"
+            ],
+            "keybindings": {},
+            "speechServerFactory": "orca.speechdispatcherfactory"
+        }
+    },
+    "pronunciations": {}
+}
\ No newline at end of file
diff --git a/test/keystrokes/oowriter/messages_table_no_context.py 
b/test/keystrokes/oowriter/messages_table_no_context.py
new file mode 100644
index 0000000..3117248
--- /dev/null
+++ b/test/keystrokes/oowriter/messages_table_no_context.py
@@ -0,0 +1,93 @@
+#!/usr/bin/python
+
+"""Test to verify table message presentation."""
+
+from macaroon.playback import *
+import utils
+
+sequence = MacroSequence()
+
+sequence.append(PauseAction(3000))
+sequence.append(TypeAction("Line 1"))
+sequence.append(KeyComboAction("Return"))
+
+sequence.append(KeyComboAction("<Control>F12"))
+sequence.append(PauseAction(1000))
+
+sequence.append(KeyComboAction("Return"))
+sequence.append(PauseAction(3000))
+
+sequence.append(KeyComboAction("<Control>Home"))
+sequence.append(PauseAction(3000))
+
+sequence.append(utils.StartRecordingAction())
+sequence.append(KeyComboAction("Down"))
+sequence.append(utils.AssertPresentationAction(
+    "1. Down arrow to enter the table",
+    ["BRAILLE LINE:  ' $l'",
+     "     VISIBLE:  ' $l', cursor=1",
+     "SPEECH OUTPUT: 'A1 B1.'"]))
+
+sequence.append(utils.StartRecordingAction())
+sequence.append(KeyComboAction("Down"))
+sequence.append(utils.AssertPresentationAction(
+    "2. Down arrow to next row of the table",
+    ["BRAILLE LINE:  ' $l'",
+     "     VISIBLE:  ' $l', cursor=1",
+     "SPEECH OUTPUT: 'A2 B2.'"]))
+
+sequence.append(utils.StartRecordingAction())
+sequence.append(KeyComboAction("Down"))
+sequence.append(utils.AssertPresentationAction(
+    "3. Down arrow to exit the table",
+    ["BRAILLE LINE:  ' $l'",
+     "     VISIBLE:  ' $l', cursor=1",
+     "SPEECH OUTPUT: 'blank'"]))
+
+sequence.append(utils.StartRecordingAction())
+sequence.append(KeyComboAction("Up"))
+sequence.append(utils.AssertPresentationAction(
+    "4. Up arrow to enter the table",
+    ["BRAILLE LINE:  ' $l'",
+     "     VISIBLE:  ' $l', cursor=1",
+     "SPEECH OUTPUT: 'A2 B2.'"]))
+
+sequence.append(utils.StartRecordingAction())
+sequence.append(KeyComboAction("Tab"))
+sequence.append(utils.AssertPresentationAction(
+    "5. Tab to move to last cell of the table",
+    ["BRAILLE LINE:  ' $l'",
+     "     VISIBLE:  ' $l', cursor=1",
+     "SPEECH OUTPUT: 'End of table.'",
+     "SPEECH OUTPUT: 'blank B2.'"]))
+
+sequence.append(utils.StartRecordingAction())
+sequence.append(KeyComboAction("Tab"))
+sequence.append(utils.AssertPresentationAction(
+    "6. Tab to insert a new row in the table",
+    ["BRAILLE LINE:  'Row inserted at the end of the table.'",
+     "     VISIBLE:  'Row inserted at the end of the t', cursor=0",
+     "BRAILLE LINE:  ' $l'",
+     "     VISIBLE:  ' $l', cursor=1",
+     "SPEECH OUTPUT: 'Row inserted at the end of the table.' voice=system",
+     "SPEECH OUTPUT: 'blank A3.'"]))
+
+sequence.append(utils.StartRecordingAction())
+sequence.append(KeyComboAction("<Control>Z"))
+sequence.append(utils.AssertPresentationAction(
+    "7. Ctrl+Z to undo that insertion",
+    ["BRAILLE LINE:  'undo'",
+     "     VISIBLE:  'undo', cursor=0",
+     "BRAILLE LINE:  'Last row deleted.'",
+     "     VISIBLE:  'Last row deleted.', cursor=0",
+     "BRAILLE LINE:  ' $l'",
+     "     VISIBLE:  ' $l', cursor=1",
+     "SPEECH OUTPUT: 'undo' voice=system",
+     "SPEECH OUTPUT: 'Last row deleted.' voice=system",
+     "SPEECH OUTPUT: 'End of table.'",
+     "SPEECH OUTPUT: 'A2 B2.'"]))
+
+sequence.append(KeyComboAction("<Alt>F4"))
+
+sequence.append(utils.AssertionSummaryAction())
+sequence.start()
diff --git a/test/keystrokes/oowriter/messages_table_no_context.settings 
b/test/keystrokes/oowriter/messages_table_no_context.settings
new file mode 100644
index 0000000..e6a6d5c
--- /dev/null
+++ b/test/keystrokes/oowriter/messages_table_no_context.settings
@@ -0,0 +1,165 @@
+{
+    "general": {
+        "enabledSpokenTextAttributes": "size:; family-name:; weight:400; indent:0; underline:none; 
strikethrough:false; justification:left; style:normal; paragraph-style:; text-spelling:none; fg-color:; 
bg-color:;",
+        "orcaModifierKeys": [
+            "Insert",
+            "KP_Insert"
+        ],
+        "skipBlankCells": false,
+        "onlySpeakDisplayedText": false,
+        "enableMnemonicSpeaking": false,
+        "chatAnnounceBuddyTyping": false,
+        "messagesAreDetailed": true,
+        "speakProgressBarUpdates": true,
+        "speakCellCoordinates": true,
+        "enableAlphabeticKeys": true,
+        "enableBraille": false,
+        "brailleAlignmentStyle": 0,
+        "playSoundForPositionInSet": false,
+        "sayAllStyle": 1,
+        "enableEchoBySentence": false,
+        "chatSpeakRoomName": false,
+        "soundVolume": 0.5,
+        "activeProfile": [
+            "Default",
+            "default"
+        ],
+        "brailleVerbosityLevel": 1,
+        "sayAllContextTable": false,
+        "enableTutorialMessages": false,
+        "wrappedStructuralNavigation": true,
+        "capitalizationStyle": "none",
+        "findResultsMinimumLength": 4,
+        "enableContractedBraille": false,
+        "presentDateFormat": "%x",
+        "enableSpeechIndentation": false,
+        "brailleContractionTable": "",
+        "structNavTriggersFocusMode": false,
+        "enablePauseBreaks": true,
+        "speakNumbersAsDigits": false,
+        "spellcheckSpellError": true,
+        "useColorNames": true,
+        "speakContextTable": false,
+        "readFullRowInGUITable": true,
+        "enabledBrailledTextAttributes": "size:; family-name:; weight:400; indent:0; underline:none; 
strikethrough:false; justification:left; style:normal; text-spelling:none;",
+        "enableSpace": true,
+        "brailleSelectorIndicator": 192,
+        "profile": [
+            "Default",
+            "default"
+        ],
+        "verbalizePunctuationStyle": 1,
+        "enableBrailleContext": true,
+        "enableNavigationKeys": false,
+        "structNavInSayAll": false,
+        "enableSound": true,
+        "speakCellSpan": true,
+        "speechVerbosityLevel": 1,
+        "brailleRolenameStyle": 1,
+        "mouseDwellDelay": null,
+        "enableSpeech": true,
+        "caretNavTriggersFocusMode": false,
+        "enableDiacriticalKeys": false,
+        "findResultsVerbosity": 2,
+        "sayAllContextBlockquote": false,
+        "speakBlankLines": true,
+        "speakSpreadsheetCoordinates": true,
+        "flashIsPersistent": false,
+        "enableNumericKeys": true,
+        "enableFlashMessages": true,
+        "progressBarVerbosity": 1,
+        "brailleLinkIndicator": 192,
+        "presentTimeFormat": "%X",
+        "enablePunctuationKeys": true,
+        "enableKeyEcho": false,
+        "playSoundForState": false,
+        "beepProgressBarUpdates": false,
+        "enableFunctionKeys": true,
+        "speakMisspelledIndicator": true,
+        "textAttributesBrailleIndicator": 0,
+        "voices": {
+            "default": {
+                "established": false
+            },
+            "system": {
+                "average-pitch": 3.0
+            },
+            "uppercase": {
+                "average-pitch": 7.0
+            },
+            "hyperlink": {
+                "established": false
+            }
+        },
+        "enableBrailleMonitor": true,
+        "layoutMode": true,
+        "brailleFlashTime": 5000,
+        "largeObjectTextLength": 75,
+        "speakContextList": false,
+        "ignoreStatusBarProgressBars": true,
+        "keyboardLayout": 1,
+        "brailleProgressBarUpdates": false,
+        "readFullRowInSpreadSheet": false,
+        "enableActionKeys": true,
+        "enablePositionSpeaking": false,
+        "structuralNavigationEnabled": true,
+        "playSoundForRole": false,
+        "disableBrailleEOL": false,
+        "presentToolTips": false,
+        "enableMouseReview": false,
+        "speechServerFactory": "speechdispatcherfactory",
+        "chatMessageVerbosity": 0,
+        "enableEchoByWord": false,
+        "spellcheckSpellSuggestion": true,
+        "enableModifierKeys": true,
+        "speakMultiCaseStringsAsWords": false,
+        "flashIsDetailed": true,
+        "speakCellHeaders": true,
+        "rewindAndFastForwardInSayAll": false,
+        "sayAllContextList": false,
+        "speakContextBlockquote": false,
+        "enableEchoByCharacter": false,
+        "playSoundForValue": false,
+        "progressBarUpdateInterval": 10,
+        "spellcheckPresentContext": true,
+        "speechServerInfo": null,
+        "chatRoomHistories": false,
+        "readFullRowInDocumentTable": true,
+        "startingProfile": [
+            "Default",
+            "default"
+        ]
+    },
+    "keybindings": {},
+    "profiles": {
+        "default": {
+            "profile": [
+                "Default",
+                "default"
+            ],
+            "brailleContractionTable": "/usr/share/liblouis/tables/en-us-compbrl.ctb",
+            "voices": {
+                "default": {
+                    "established": false
+                },
+                "system": {
+                    "average-pitch": 3.0
+                },
+                "uppercase": {
+                    "average-pitch": 7.0
+                },
+                "hyperlink": {
+                    "established": false
+                }
+            },
+            "pronunciations": {},
+            "speechServerInfo": [
+                "Default Synthesizer",
+                "default"
+            ],
+            "keybindings": {},
+            "speechServerFactory": "orca.speechdispatcherfactory"
+        }
+    },
+    "pronunciations": {}
+}
\ No newline at end of file
diff --git a/test/keystrokes/oowriter/say_all_table.params b/test/keystrokes/oowriter/say_all_table.params
new file mode 100644
index 0000000..6952e8c
--- /dev/null
+++ b/test/keystrokes/oowriter/say_all_table.params
@@ -0,0 +1 @@
+PARAMS=$TEST_DIR/../../documents/table-sample.odt
diff --git a/test/keystrokes/oowriter/say_all_table.py b/test/keystrokes/oowriter/say_all_table.py
new file mode 100644
index 0000000..da1a15c
--- /dev/null
+++ b/test/keystrokes/oowriter/say_all_table.py
@@ -0,0 +1,65 @@
+#!/usr/bin/python
+
+"""Test to verify SayAll works in Writer."""
+
+from macaroon.playback import *
+import utils
+
+sequence = MacroSequence()
+sequence.append(PauseAction(2000))
+sequence.append(KeyComboAction("<Control>Home"))
+sequence.append(PauseAction(2000))
+
+sequence.append(utils.StartRecordingAction())
+sequence.append(KeyComboAction("KP_Add"))
+sequence.append(utils.AssertPresentationAction(
+    "1. Say all",
+    ["SPEECH OUTPUT: 'December 2006'",
+     "SPEECH OUTPUT: 'This is a test.'",
+     "SPEECH OUTPUT: 'Calendar-1.'",
+     "SPEECH OUTPUT: 'table with 7 rows 7 columns'",
+     "SPEECH OUTPUT: 'Sun'",
+     "SPEECH OUTPUT: 'Mon'",
+     "SPEECH OUTPUT: 'Tue'",
+     "SPEECH OUTPUT: 'Wed'",
+     "SPEECH OUTPUT: 'Thu'",
+     "SPEECH OUTPUT: 'Fri'",
+     "SPEECH OUTPUT: 'Sat'",
+     "SPEECH OUTPUT: '1'",
+     "SPEECH OUTPUT: '2'",
+     "SPEECH OUTPUT: '3'",
+     "SPEECH OUTPUT: '4'",
+     "SPEECH OUTPUT: '5'",
+     "SPEECH OUTPUT: '6'",
+     "SPEECH OUTPUT: '7'",
+     "SPEECH OUTPUT: '8'",
+     "SPEECH OUTPUT: '9'",
+     "SPEECH OUTPUT: '10'",
+     "SPEECH OUTPUT: '11'",
+     "SPEECH OUTPUT: '12'",
+     "SPEECH OUTPUT: '13'",
+     "SPEECH OUTPUT: '14'",
+     "SPEECH OUTPUT: '15'",
+     "SPEECH OUTPUT: '16'",
+     "SPEECH OUTPUT: '17'",
+     "SPEECH OUTPUT: '18'",
+     "SPEECH OUTPUT: '19'",
+     "SPEECH OUTPUT: '20'",
+     "SPEECH OUTPUT: '21'",
+     "SPEECH OUTPUT: '22'",
+     "SPEECH OUTPUT: '23'",
+     "SPEECH OUTPUT: '24'",
+     "SPEECH OUTPUT: '25'",
+     "SPEECH OUTPUT: '26'",
+     "SPEECH OUTPUT: '27'",
+     "SPEECH OUTPUT: '28'",
+     "SPEECH OUTPUT: '29'",
+     "SPEECH OUTPUT: '30'",
+     "SPEECH OUTPUT: '31'",
+     "SPEECH OUTPUT: 'leaving table.'",
+     "SPEECH OUTPUT: 'So is this.'"]))
+
+sequence.append(KeyComboAction("<Alt>F4"))
+
+sequence.append(utils.AssertionSummaryAction())
+sequence.start()
diff --git a/test/keystrokes/oowriter/say_all_table.settings b/test/keystrokes/oowriter/say_all_table.settings
new file mode 100644
index 0000000..d36600d
--- /dev/null
+++ b/test/keystrokes/oowriter/say_all_table.settings
@@ -0,0 +1,165 @@
+{
+    "general": {
+        "enabledSpokenTextAttributes": "size:; family-name:; weight:400; indent:0; underline:none; 
strikethrough:false; justification:left; style:normal; paragraph-style:; text-spelling:none; fg-color:; 
bg-color:;",
+        "orcaModifierKeys": [
+            "Insert",
+            "KP_Insert"
+        ],
+        "skipBlankCells": false,
+        "onlySpeakDisplayedText": false,
+        "enableMnemonicSpeaking": false,
+        "chatAnnounceBuddyTyping": false,
+        "messagesAreDetailed": true,
+        "speakProgressBarUpdates": true,
+        "speakCellCoordinates": true,
+        "enableAlphabeticKeys": true,
+        "enableBraille": false,
+        "brailleAlignmentStyle": 0,
+        "playSoundForPositionInSet": false,
+        "sayAllStyle": 1,
+        "enableEchoBySentence": false,
+        "chatSpeakRoomName": false,
+        "soundVolume": 0.5,
+        "activeProfile": [
+            "Default",
+            "default"
+        ],
+        "brailleVerbosityLevel": 1,
+        "sayAllContextTable": true,
+        "enableTutorialMessages": false,
+        "wrappedStructuralNavigation": true,
+        "capitalizationStyle": "none",
+        "findResultsMinimumLength": 4,
+        "enableContractedBraille": false,
+        "presentDateFormat": "%x",
+        "enableSpeechIndentation": false,
+        "brailleContractionTable": "",
+        "structNavTriggersFocusMode": false,
+        "enablePauseBreaks": true,
+        "speakNumbersAsDigits": false,
+        "spellcheckSpellError": true,
+        "useColorNames": true,
+        "speakContextTable": true,
+        "readFullRowInGUITable": true,
+        "enabledBrailledTextAttributes": "size:; family-name:; weight:400; indent:0; underline:none; 
strikethrough:false; justification:left; style:normal; text-spelling:none;",
+        "enableSpace": true,
+        "brailleSelectorIndicator": 192,
+        "profile": [
+            "Default",
+            "default"
+        ],
+        "verbalizePunctuationStyle": 1,
+        "enableBrailleContext": true,
+        "enableNavigationKeys": false,
+        "structNavInSayAll": false,
+        "enableSound": true,
+        "speakCellSpan": true,
+        "speechVerbosityLevel": 1,
+        "brailleRolenameStyle": 1,
+        "mouseDwellDelay": null,
+        "enableSpeech": true,
+        "caretNavTriggersFocusMode": false,
+        "enableDiacriticalKeys": false,
+        "findResultsVerbosity": 2,
+        "sayAllContextBlockquote": true,
+        "speakBlankLines": true,
+        "speakSpreadsheetCoordinates": true,
+        "flashIsPersistent": false,
+        "enableNumericKeys": true,
+        "enableFlashMessages": true,
+        "progressBarVerbosity": 1,
+        "brailleLinkIndicator": 192,
+        "presentTimeFormat": "%X",
+        "enablePunctuationKeys": true,
+        "enableKeyEcho": false,
+        "playSoundForState": false,
+        "beepProgressBarUpdates": false,
+        "enableFunctionKeys": true,
+        "speakMisspelledIndicator": true,
+        "textAttributesBrailleIndicator": 0,
+        "voices": {
+            "default": {
+                "established": false
+            },
+            "system": {
+                "average-pitch": 3.0
+            },
+            "uppercase": {
+                "average-pitch": 7.0
+            },
+            "hyperlink": {
+                "established": false
+            }
+        },
+        "enableBrailleMonitor": true,
+        "layoutMode": true,
+        "brailleFlashTime": 5000,
+        "largeObjectTextLength": 75,
+        "speakContextList": true,
+        "ignoreStatusBarProgressBars": true,
+        "keyboardLayout": 1,
+        "brailleProgressBarUpdates": false,
+        "readFullRowInSpreadSheet": false,
+        "enableActionKeys": true,
+        "enablePositionSpeaking": false,
+        "structuralNavigationEnabled": true,
+        "playSoundForRole": false,
+        "disableBrailleEOL": false,
+        "presentToolTips": false,
+        "enableMouseReview": false,
+        "speechServerFactory": "speechdispatcherfactory",
+        "chatMessageVerbosity": 0,
+        "enableEchoByWord": false,
+        "spellcheckSpellSuggestion": true,
+        "enableModifierKeys": true,
+        "speakMultiCaseStringsAsWords": false,
+        "flashIsDetailed": true,
+        "speakCellHeaders": true,
+        "rewindAndFastForwardInSayAll": false,
+        "sayAllContextList": true,
+        "speakContextBlockquote": true,
+        "enableEchoByCharacter": false,
+        "playSoundForValue": false,
+        "progressBarUpdateInterval": 10,
+        "spellcheckPresentContext": true,
+        "speechServerInfo": null,
+        "chatRoomHistories": false,
+        "readFullRowInDocumentTable": true,
+        "startingProfile": [
+            "Default",
+            "default"
+        ]
+    },
+    "keybindings": {},
+    "profiles": {
+        "default": {
+            "profile": [
+                "Default",
+                "default"
+            ],
+            "brailleContractionTable": "/usr/share/liblouis/tables/en-us-compbrl.ctb",
+            "voices": {
+                "default": {
+                    "established": false
+                },
+                "system": {
+                    "average-pitch": 3.0
+                },
+                "uppercase": {
+                    "average-pitch": 7.0
+                },
+                "hyperlink": {
+                    "established": false
+                }
+            },
+            "pronunciations": {},
+            "speechServerInfo": [
+                "Default Synthesizer",
+                "default"
+            ],
+            "keybindings": {},
+            "speechServerFactory": "orca.speechdispatcherfactory"
+        }
+    },
+    "pronunciations": {}
+}
\ No newline at end of file
diff --git a/test/keystrokes/oowriter/say_all_table_no_context.params 
b/test/keystrokes/oowriter/say_all_table_no_context.params
new file mode 100644
index 0000000..6952e8c
--- /dev/null
+++ b/test/keystrokes/oowriter/say_all_table_no_context.params
@@ -0,0 +1 @@
+PARAMS=$TEST_DIR/../../documents/table-sample.odt
diff --git a/test/keystrokes/oowriter/say_all_table_no_context.py 
b/test/keystrokes/oowriter/say_all_table_no_context.py
new file mode 100644
index 0000000..f8e2a72
--- /dev/null
+++ b/test/keystrokes/oowriter/say_all_table_no_context.py
@@ -0,0 +1,62 @@
+#!/usr/bin/python
+
+"""Test to verify SayAll works in Writer."""
+
+from macaroon.playback import *
+import utils
+
+sequence = MacroSequence()
+sequence.append(PauseAction(2000))
+sequence.append(KeyComboAction("<Control>Home"))
+sequence.append(PauseAction(2000))
+
+sequence.append(utils.StartRecordingAction())
+sequence.append(KeyComboAction("KP_Add"))
+sequence.append(utils.AssertPresentationAction(
+    "1. Say all",
+    ["SPEECH OUTPUT: 'December 2006'",
+     "SPEECH OUTPUT: 'This is a test.'",
+     "SPEECH OUTPUT: 'Sun'",
+     "SPEECH OUTPUT: 'Mon'",
+     "SPEECH OUTPUT: 'Tue'",
+     "SPEECH OUTPUT: 'Wed'",
+     "SPEECH OUTPUT: 'Thu'",
+     "SPEECH OUTPUT: 'Fri'",
+     "SPEECH OUTPUT: 'Sat'",
+     "SPEECH OUTPUT: '1'",
+     "SPEECH OUTPUT: '2'",
+     "SPEECH OUTPUT: '3'",
+     "SPEECH OUTPUT: '4'",
+     "SPEECH OUTPUT: '5'",
+     "SPEECH OUTPUT: '6'",
+     "SPEECH OUTPUT: '7'",
+     "SPEECH OUTPUT: '8'",
+     "SPEECH OUTPUT: '9'",
+     "SPEECH OUTPUT: '10'",
+     "SPEECH OUTPUT: '11'",
+     "SPEECH OUTPUT: '12'",
+     "SPEECH OUTPUT: '13'",
+     "SPEECH OUTPUT: '14'",
+     "SPEECH OUTPUT: '15'",
+     "SPEECH OUTPUT: '16'",
+     "SPEECH OUTPUT: '17'",
+     "SPEECH OUTPUT: '18'",
+     "SPEECH OUTPUT: '19'",
+     "SPEECH OUTPUT: '20'",
+     "SPEECH OUTPUT: '21'",
+     "SPEECH OUTPUT: '22'",
+     "SPEECH OUTPUT: '23'",
+     "SPEECH OUTPUT: '24'",
+     "SPEECH OUTPUT: '25'",
+     "SPEECH OUTPUT: '26'",
+     "SPEECH OUTPUT: '27'",
+     "SPEECH OUTPUT: '28'",
+     "SPEECH OUTPUT: '29'",
+     "SPEECH OUTPUT: '30'",
+     "SPEECH OUTPUT: '31'",
+     "SPEECH OUTPUT: 'So is this.'"]))
+
+sequence.append(KeyComboAction("<Alt>F4"))
+
+sequence.append(utils.AssertionSummaryAction())
+sequence.start()
diff --git a/test/keystrokes/oowriter/say_all_table_no_context.settings 
b/test/keystrokes/oowriter/say_all_table_no_context.settings
new file mode 100644
index 0000000..e6a6d5c
--- /dev/null
+++ b/test/keystrokes/oowriter/say_all_table_no_context.settings
@@ -0,0 +1,165 @@
+{
+    "general": {
+        "enabledSpokenTextAttributes": "size:; family-name:; weight:400; indent:0; underline:none; 
strikethrough:false; justification:left; style:normal; paragraph-style:; text-spelling:none; fg-color:; 
bg-color:;",
+        "orcaModifierKeys": [
+            "Insert",
+            "KP_Insert"
+        ],
+        "skipBlankCells": false,
+        "onlySpeakDisplayedText": false,
+        "enableMnemonicSpeaking": false,
+        "chatAnnounceBuddyTyping": false,
+        "messagesAreDetailed": true,
+        "speakProgressBarUpdates": true,
+        "speakCellCoordinates": true,
+        "enableAlphabeticKeys": true,
+        "enableBraille": false,
+        "brailleAlignmentStyle": 0,
+        "playSoundForPositionInSet": false,
+        "sayAllStyle": 1,
+        "enableEchoBySentence": false,
+        "chatSpeakRoomName": false,
+        "soundVolume": 0.5,
+        "activeProfile": [
+            "Default",
+            "default"
+        ],
+        "brailleVerbosityLevel": 1,
+        "sayAllContextTable": false,
+        "enableTutorialMessages": false,
+        "wrappedStructuralNavigation": true,
+        "capitalizationStyle": "none",
+        "findResultsMinimumLength": 4,
+        "enableContractedBraille": false,
+        "presentDateFormat": "%x",
+        "enableSpeechIndentation": false,
+        "brailleContractionTable": "",
+        "structNavTriggersFocusMode": false,
+        "enablePauseBreaks": true,
+        "speakNumbersAsDigits": false,
+        "spellcheckSpellError": true,
+        "useColorNames": true,
+        "speakContextTable": false,
+        "readFullRowInGUITable": true,
+        "enabledBrailledTextAttributes": "size:; family-name:; weight:400; indent:0; underline:none; 
strikethrough:false; justification:left; style:normal; text-spelling:none;",
+        "enableSpace": true,
+        "brailleSelectorIndicator": 192,
+        "profile": [
+            "Default",
+            "default"
+        ],
+        "verbalizePunctuationStyle": 1,
+        "enableBrailleContext": true,
+        "enableNavigationKeys": false,
+        "structNavInSayAll": false,
+        "enableSound": true,
+        "speakCellSpan": true,
+        "speechVerbosityLevel": 1,
+        "brailleRolenameStyle": 1,
+        "mouseDwellDelay": null,
+        "enableSpeech": true,
+        "caretNavTriggersFocusMode": false,
+        "enableDiacriticalKeys": false,
+        "findResultsVerbosity": 2,
+        "sayAllContextBlockquote": false,
+        "speakBlankLines": true,
+        "speakSpreadsheetCoordinates": true,
+        "flashIsPersistent": false,
+        "enableNumericKeys": true,
+        "enableFlashMessages": true,
+        "progressBarVerbosity": 1,
+        "brailleLinkIndicator": 192,
+        "presentTimeFormat": "%X",
+        "enablePunctuationKeys": true,
+        "enableKeyEcho": false,
+        "playSoundForState": false,
+        "beepProgressBarUpdates": false,
+        "enableFunctionKeys": true,
+        "speakMisspelledIndicator": true,
+        "textAttributesBrailleIndicator": 0,
+        "voices": {
+            "default": {
+                "established": false
+            },
+            "system": {
+                "average-pitch": 3.0
+            },
+            "uppercase": {
+                "average-pitch": 7.0
+            },
+            "hyperlink": {
+                "established": false
+            }
+        },
+        "enableBrailleMonitor": true,
+        "layoutMode": true,
+        "brailleFlashTime": 5000,
+        "largeObjectTextLength": 75,
+        "speakContextList": false,
+        "ignoreStatusBarProgressBars": true,
+        "keyboardLayout": 1,
+        "brailleProgressBarUpdates": false,
+        "readFullRowInSpreadSheet": false,
+        "enableActionKeys": true,
+        "enablePositionSpeaking": false,
+        "structuralNavigationEnabled": true,
+        "playSoundForRole": false,
+        "disableBrailleEOL": false,
+        "presentToolTips": false,
+        "enableMouseReview": false,
+        "speechServerFactory": "speechdispatcherfactory",
+        "chatMessageVerbosity": 0,
+        "enableEchoByWord": false,
+        "spellcheckSpellSuggestion": true,
+        "enableModifierKeys": true,
+        "speakMultiCaseStringsAsWords": false,
+        "flashIsDetailed": true,
+        "speakCellHeaders": true,
+        "rewindAndFastForwardInSayAll": false,
+        "sayAllContextList": false,
+        "speakContextBlockquote": false,
+        "enableEchoByCharacter": false,
+        "playSoundForValue": false,
+        "progressBarUpdateInterval": 10,
+        "spellcheckPresentContext": true,
+        "speechServerInfo": null,
+        "chatRoomHistories": false,
+        "readFullRowInDocumentTable": true,
+        "startingProfile": [
+            "Default",
+            "default"
+        ]
+    },
+    "keybindings": {},
+    "profiles": {
+        "default": {
+            "profile": [
+                "Default",
+                "default"
+            ],
+            "brailleContractionTable": "/usr/share/liblouis/tables/en-us-compbrl.ctb",
+            "voices": {
+                "default": {
+                    "established": false
+                },
+                "system": {
+                    "average-pitch": 3.0
+                },
+                "uppercase": {
+                    "average-pitch": 7.0
+                },
+                "hyperlink": {
+                    "established": false
+                }
+            },
+            "pronunciations": {},
+            "speechServerInfo": [
+                "Default Synthesizer",
+                "default"
+            ],
+            "keybindings": {},
+            "speechServerFactory": "orca.speechdispatcherfactory"
+        }
+    },
+    "pronunciations": {}
+}
\ No newline at end of file


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