[orca] Merge braille generator refactor (bgo#570658)



commit f7b40d177af75490f532636295f986a3b1def824
Author: Willie Walker <william walker sun com>
Date:   Wed Jul 8 13:34:57 2009 -0400

    Merge braille generator refactor (bgo#570658)
    
    Squashed commit of the following:
    
    commit dfe6bbf9cf5b68aaccd201084b4f0741e7820e6a
    Author: Willie Walker <william walker sun com>
    Date:   Wed Jul 8 12:37:19 2009 -0400
    
        Adjust POTFILES.in to reflect just files that have translatable strings
    
    commit ab227615e3b8fb49116f9819fa6ecf5da443458b
    Author: Willie Walker <william walker sun com>
    Date:   Tue Jul 7 20:34:51 2009 -0400
    
        Get rid of old code
    
    commit 75036bf9531fefb829b678aa5f678814e690f640
    Author: Willie Walker <william walker sun com>
    Date:   Tue Jul 7 20:10:09 2009 -0400
    
        Update regression tests to reflect reality
    
    commit ff7175672a6fe0020e41f6346cc12729809615f0
    Author: Willie Walker <william walker sun com>
    Date:   Tue Jul 7 19:58:23 2009 -0400
    
        Use table cell delimiter when dealing with multiple objects in a cell
    
    commit f729e7409f7a8c3eef2e31c5536c8e48eb21e61e
    Author: Willie Walker <william walker sun com>
    Date:   Tue Jul 7 19:57:08 2009 -0400
    
        Include an empty Component region for blank table cells
    
        Just because it is empty doesn't mean it doesn't exist
    
    commit 8f97ffccaee04ad84d37b039e648ade14c16940e
    Author: Willie Walker <william walker sun com>
    Date:   Tue Jul 7 19:55:48 2009 -0400
    
        In tables, include accessible's parent when searching for focused region
    
    commit 7d50c2dd7a406e22fb1aa7cd616c61adf9aeb9cd
    Author: Willie Walker <william walker sun com>
    Date:   Tue Jul 7 12:22:03 2009 -0400
    
        Adjust tests to reflect table row being in braille line
    
    commit 897af506784be8ccd0510714c277e0f0db6a2088
    Author: Willie Walker <william walker sun com>
    Date:   Tue Jul 7 11:41:51 2009 -0400
    
        Update OOo tests based upon new braille generator changes
    
        There's one last thing to do, which is make sure we have a Component
        region in the line even if we're in an empty cell or empty line.
    
    commit 1c5844fa97fe6ac73af4d0c372e4efa3ebc1ca73
    Author: Willie Walker <william walker sun com>
    Date:   Tue Jul 7 11:41:21 2009 -0400
    
        Work on tables for OOo braille generator
    
    commit 5f734e74780cca83f3ba1acba10e566113068f0d
    Author: Willie Walker <william walker sun com>
    Date:   Tue Jul 7 11:39:35 2009 -0400
    
        Work on including ancestors and context
    
        For radio buttons, we do not want to include the radio button group,
        but we want to include other encapsulating labeled panels.  For
        text, we only want to include context when we're on the first line
        of text in a document.
    
    commit bbccd2fcc7409a8558b59a12358d03f739543282
    Author: Willie Walker <william walker sun com>
    Date:   Tue Jul 7 11:38:33 2009 -0400
    
        Only add space before role name if we're presenting text
    
    commit 213714bd21be39b71f5c5a3f76d0d98e3c3442dc
    Author: Willie Walker <william walker sun com>
    Date:   Tue Jul 7 11:38:03 2009 -0400
    
        Remove debug line
    
    commit 81523b9ec5134f220c2905118685fcdfcc13b4f6
    Author: Joanmarie Diggs <joanmarie diggs gmail com>
    Date:   Mon Jul 6 13:11:44 2009 -0400
    
        Fix for the redundant filler/radio button group label
    
    commit 5fc6d07defe984c9e69a4b10263f5a2615941e5b
    Author: Joanmarie Diggs <joanmarie diggs gmail com>
    Date:   Mon Jul 6 12:49:53 2009 -0400
    
        Updated regression test.
    
    commit 48be501cf1b832837a91af126d677c5c92eb1c68
    Author: Joanmarie Diggs <joanmarie diggs gmail com>
    Date:   Sun Jul 5 20:44:53 2009 -0400
    
        Present the same thing for XUL combo boxes as we do Gtk+ combo boxes
    
        I took a look at what we present for a labelled combo box for which we are
        not doing any special scripting (the Show combo box in packagemanager). In
        that case, we always present the label but move the cursor to the beginning
        of the selected item if the combo box is collapsed. For expanded combo boxes,
        the label and the currently displayed item in the combo box are included as
        part of the braille context, but only the selected/highlighted item in the
        menu is shown on the display. Done and done.
    
    commit 6f724ecdde4e38b1c8e925b1d60961453aa30eff
    Author: Joanmarie Diggs <joanmarie diggs gmail com>
    Date:   Sun Jul 5 17:18:10 2009 -0400
    
        Updated this test. Again.
    
        The maintainers of the dojo archive moved this test on us. Also, it
        appears to have changed slightly. This has nothing to do with the
        refactor, but I'm only checking it into the branch.
    
    commit 9720b41cfc0cf3f6125352e054458f51516d5845
    Author: Joanmarie Diggs <joanmarie diggs gmail com>
    Date:   Sun Jul 5 17:01:43 2009 -0400
    
        Fix for the dojo_button.py test regression.
    
    commit f08abdf93f6eb454f0854a3a384fa1ffb43b207c
    Author: Joanmarie Diggs <joanmarie diggs gmail com>
    Date:   Sun Jul 5 16:35:30 2009 -0400
    
        Added a formatting string for custom handling of radio buttons.
    
        This solves the regression in the moz_tabpanel.py test in which
        the label associated with the radio button was presented three
        times.
    
    commit 54d3d02aa024d67a6b55f43e7b0bf2de704f0e0a
    Author: Joanmarie Diggs <joanmarie diggs gmail com>
    Date:   Sun Jul 5 14:09:01 2009 -0400
    
        Tentative fix for the extra space in line_nav_bug_555055.py
    
        This fixes the regression (initial space before the rolename for
        non-linked images which lack associated/alternative text). Will
        suggested that it would be harder than it proved to be. Therefore,
        after running the regression tests I might back this out. :-)
    
    commit fd5a3922f30734473d14a5da8179c444b7854fd4
    Author: Joanmarie Diggs <joanmarie diggs gmail com>
    Date:   Sun Jul 5 13:29:29 2009 -0400
    
        Updated regression tests.
    
    commit cdec9e54c78aa99ff52b0bd2d6859160cc3c51e5
    Author: Joanmarie Diggs <joanmarie diggs gmail com>
    Date:   Sun Jul 5 00:30:37 2009 -0400
    
        Updated regression test.
    
        We used to do a bad job with presenting XUL combo boxes in braille. The
        changes made in the refactor clean a lot of that up (correct whitespace,
        label included, etc.). The one problem that remains seems to be the
        duplication of the displayed/selected item at the end of the context. I've
        updated this regression test to reflect what we should be doing, which makes
        it much easier to see where the true failures are.
    
    commit ef09bf6de87295945d10c5a9bea838f844590dc1
    Author: Joanmarie Diggs <joanmarie diggs gmail com>
    Date:   Sat Jul 4 23:50:45 2009 -0400
    
        Updated regression tests.
    
        Marking a couple of tests with "BUG?". We're duplicating some text
        in the braille context.
    
    commit 97298853d498f1ff7d2534a0649bc6fbcfeccd66
    Author: Joanmarie Diggs <joanmarie diggs gmail com>
    Date:   Sat Jul 4 22:05:38 2009 -0400
    
        Fix for the xul_role_list_item bug.
    
        The problem turned out to be that we were getting the focused item
        as part of the context for what happened to be the focused (list)
        item. After trying to find other ways to identify this condition
        (e.g. looking at states and the value of 'recursing'), I wound up
        comparing the focused item with the locusOfFocus as that seems to
        be the most reliable.
    
    commit cc189a072edbe49488a191283cb364f97c903545
    Author: Joanmarie Diggs <joanmarie diggs gmail com>
    Date:   Sat Jul 4 17:04:24 2009 -0400
    
        Updated regression tests. Also added FF 3.5b4 to utils.py.
    
    commit a94cdeda95455b95d34939c9ea37f498347c36a7
    Author: Willie Walker <william walker sun com>
    Date:   Sat Jul 4 03:58:01 2009 -0400
    
        Use realActiveDescendantRoleName for table cell contents
    
    commit d074243b1337b9a9bdc0b6f3c832d7ebb1f22f59
    Author: Willie Walker <william walker sun com>
    Date:   Sat Jul 4 03:56:09 2009 -0400
    
        Add _generateRealActiveDescendantRoleName
    
        This is for presenting table cell contents.  We *may* want to consider
        just finding the active descendant and presenting the generator results
        for it, but for now I'm going to keep it simple.
    
    commit a563bea99edff2b6a94d3a28b0b1fc4c5c866d74
    Author: Willie Walker <william walker sun com>
    Date:   Sat Jul 4 03:55:44 2009 -0400
    
        Cache realActiveDescendant
    
    commit 8a6a1f26be9da779f3e8b4a473b7a058f781de09
    Author: Willie Walker <william walker sun com>
    Date:   Sat Jul 4 03:26:03 2009 -0400
    
        Start work on soffice braille generator
    
    commit eb5241234f681cfa27ef3979b82876d28dcb265a
    Author: Willie Walker <william walker sun com>
    Date:   Sat Jul 4 03:24:05 2009 -0400
    
        Make docs more speech/braille agnositc
    
    commit cfb3d409b882d45b8ece18d1920d915290ed73c5
    Author: Francisco Javier Dorado Martinez (tiflolinux <javier tiflolinux org>
    Date:   Sat Jun 27 15:17:57 2009 +0200
    
        Updated Spanish translation
        Signed-off-by: Jorge Gonzalez <jorgegonz svn gnome org>
    
        Author:    Francisco Javier Dorado Martinez (tiflolinux) <javier tiflolinux org>
    
    commit 72c58a698dbece5063a481b4bb26eb9ec72a7f9c
    Author: Willie Walker <william walker sun com>
    Date:   Fri Jun 26 13:15:35 2009 -0400
    
        Fix for doo#9676 - Orca fails to launch
    
        Make sure setting the PATH follows sh syntax and not bash
    
    commit f99e7ae4a32aa6fae1e813ac223b4957ee88b8c0
    Author: Willie Walker <william walker sun com>
    Date:   Wed Jun 24 17:28:55 2009 -0400
    
        Mark as Orca v2.27.4pre so as not to confuse some people building from source
    
    commit e753ea385ff509118d92f50dd995b456038557f1
    Author: Willie Walker <william walker sun com>
    Date:   Thu Jul 2 21:04:34 2009 -0400
    
        Pylinting - fix many references to old braille generator
    
    commit fea05b93fcb208eb84b749bd92976e2fd6f75732
    Author: Willie Walker <william walker sun com>
    Date:   Thu Jul 2 15:35:04 2009 -0400
    
        Remove old code that was there as a reference
    
    commit 20a99842ec3fcf9d2c4c0cfe6036b14db7bcfc51
    Author: Willie Walker <william walker sun com>
    Date:   Thu Jul 2 14:31:01 2009 -0400
    
        Fix CheckBox formatting for inside/outside document content
    
    commit f2e1d6b60b3283451dd78fefe35987ff36e906c9
    Author: Willie Walker <william walker sun com>
    Date:   Thu Jul 2 14:30:12 2009 -0400
    
        Adjust calls to inDocumentContent to take an object
    
        Also add _generateInDocumentContent method for use by formatting strings
    
    commit 05690074dc283867246542bcec287f6cceccd350
    Author: Willie Walker <william walker sun com>
    Date:   Thu Jul 2 14:29:01 2009 -0400
    
        Cache inDocumentContent results
    
    commit 6d56f678886d69cb29324e28bfe122afd50f9a1e
    Author: Willie Walker <william walker sun com>
    Date:   Thu Jul 2 10:30:23 2009 -0400
    
        Use default formatting when dealing with a non-focusable list.
    
    commit 3d085b8c4baefe201fbae3693acc2f4a5765bc2d
    Author: Willie Walker <william walker sun com>
    Date:   Thu Jul 2 10:22:47 2009 -0400
    
        Change 'isAria' to 'useDefaultFormatting'
    
        The directive to use the default formatting can go beyond whether the widget
        is an ARIA widget or not.
    
    commit 66b53deda1bf5fd87a230b50bf6ca635bd7edd1b
    Author: Willie Walker <william walker sun com>
    Date:   Thu Jul 2 10:22:10 2009 -0400
    
        Cache isAriaWidget calculation
    
    commit 465b20875b9af56effb6abced0dd40a956fc2083
    Author: Willie Walker <william walker sun com>
    Date:   Thu Jul 2 10:12:59 2009 -0400
    
        Fix lists for new braille generator (I hope)
    
    commit b3ea19eca5b6a219fff57e33af7472a4256de1bb
    Author: Willie Walker <william walker sun com>
    Date:   Thu Jul 2 09:44:34 2009 -0400
    
        Fix comboboxes for new braille generator (I hope)
    
    commit 42b0bf4fff7de35326616fd34f1ab68daec34a09
    Author: Willie Walker <william walker sun com>
    Date:   Wed Jul 1 15:32:56 2009 -0400
    
        Fix list items for braille generator
    
        This was adding a string instead of a Region
    
    commit d5565a57439a175c092f7e15e240ef7eb7ca11fe
    Author: Willie Walker <william walker sun com>
    Date:   Wed Jul 1 14:46:42 2009 -0400
    
        Don't label guess password entries in braille or we'll end up with double labels
    
    commit e15301ffa5dd90ca782f26837cfeadbc832c1628
    Author: Willie Walker <william walker sun com>
    Date:   Wed Jul 1 13:06:53 2009 -0400
    
        Fix braille for images and links
    
    commit da05c0c20d09b802667fb8b3024a1497fd24ee76
    Author: Willie Walker <william walker sun com>
    Date:   Wed Jul 1 10:40:34 2009 -0400
    
        Do not guess the label for ROLE_ENTRY, ROLE_COMBO_BOX, and ROLE_TOGGLE_BUTTON
    
    commit 3e58c2621657d608027bea48d93f8e47cc180380
    Author: Willie Walker <william walker sun com>
    Date:   Wed Jul 1 10:39:57 2009 -0400
    
        Adjust what we present for Links to better match the old generator
    
    commit d1812fdb5d96af6f77f723e3dd091f031d573749
    Author: Willie Walker <william walker sun com>
    Date:   Wed Jul 1 10:39:09 2009 -0400
    
        Make sure we deal with unicode internally, but UTF-8 externally
    
    commit a7fbabffe584491cc0b85a71a9b9d66425743670
    Author: Willie Walker <william walker sun com>
    Date:   Wed Jul 1 08:58:20 2009 -0400
    
        Get braille context when not in document content
    
        This is what the old braille generator was doing.
    
    commit dd69b38571cc2f0348da78f472ff419ba5b94d0c
    Author: Willie Walker <william walker sun com>
    Date:   Tue Jun 30 16:23:20 2009 -0400
    
        Add ROLE_ENTRY support to braille
    
    commit bac7c4a51165f05daffc33a3fc6ecd96c8faaea6
    Author: Willie Walker <william walker sun com>
    Date:   Tue Jun 30 13:53:23 2009 -0400
    
        Work on Gecko braille generator for links and images
    
        All the bug_*.py tests run well with this latest set of changes.
    
    commit 2c06ad4756f4f863c1e3933ef2169119a92d0f2c
    Author: Willie Walker <william walker sun com>
    Date:   Tue Jun 30 13:52:45 2009 -0400
    
        Move _generateCurrentLine text to generator.py for speech/braille sharing
    
    commit ad036e8ac8fa93893bb3b2ddf199120c247b08cf
    Author: Willie Walker <william walker sun com>
    Date:   Tue Jun 30 13:51:23 2009 -0400
    
        Move _generateCurrentLine text to generator.py for speech/braille sharing
    
    commit 14259296e499e572334155b66bec817fea98920c
    Author: Willie Walker <william walker sun com>
    Date:   Tue Jun 30 10:52:34 2009 -0400
    
        Begin work on Gecko's braille generator
    
        This is very minimalist and not at all complete.  Much work to do,
        but I needed to do something so as to prevent the gtk-demo tests
        from failing (the orca-customizations.py for the test was importing
        Gecko, so Gecko needed to migrate to the new generator).
    
    commit b318abb2671895d47db44c6d89222c28a5ac2759
    Author: Willie Walker <william walker sun com>
    Date:   Mon Jun 29 17:28:40 2009 -0400
    
        Update comments to reflect new module/method name for braille generator
    
    commit 9be4a8cc2e2384ffb8b211a367b9a7638473131b
    Author: Willie Walker <william walker sun com>
    Date:   Mon Jun 29 17:20:58 2009 -0400
    
        Port J2SE Access Bridge to new braille generator
    
        Something is still a little odd about arrowing up and down tables.
        We braille the line correctly, but then immediately braille "Tree".
        I think it may be a timing issue with selection events.
    
    commit f0c29bbe7afee9a88e6821a4a08c38775971272b
    Author: Willie Walker <william walker sun com>
    Date:   Mon Jun 29 16:55:24 2009 -0400
    
        Port planner script to new braille generator
    
        I had a rough time deciding on whether to do multiple inheritance or not
        to share the logic between the two generators.  I decided that the
        complexity of extending orca.generator, orca.braille_generator, and
        orca.speech_generator just wasn't worth it.
    
    commit 6c3d3d58011b6ee313e71e78e235a28250c67fea
    Author: Willie Walker <william walker sun com>
    Date:   Mon Jun 29 16:52:11 2009 -0400
    
        Port rhythmbox script to the new braille generator
    
    commit d7c4e26e6ae622b7674719aa198ae2fe27b0e99a
    Author: Willie Walker <william walker sun com>
    Date:   Mon Jun 29 16:44:49 2009 -0400
    
        Remove the old default braillegenerator.py altogether
    
    commit 7e0ce9f8e90a6d66a72e67bdba9c1227a1a07840
    Author: Willie Walker <william walker sun com>
    Date:   Mon Jun 29 09:30:40 2009 -0400
    
        Ignore typical output files obtained when running the tests
    
    commit b56b64f55b58165fcd0440160fe3d9b429264919
    Author: Willie Walker <william walker sun com>
    Date:   Sat Jun 27 10:35:59 2009 -0400
    
        Make sure the label of a combo box is part of the braille component region
    
        Prior to this, it was a separate Region object and was scrolled off the
        braille display.  I think this represents a good bug fix.
    
    commit d0f8f0b80535578f69b306e767e9010ba4549cd9
    Author: Willie Walker <william walker sun com>
    Date:   Sat Jun 27 10:17:24 2009 -0400
    
        Fix up braille generator for comboboxes.
    
        With this, the default braille generator has been fully migrated to use
        the new formatting strings.  One question remains, which whether or not
        we want to always include the entire row of a table in braille (with
        focus put on the appropriate cell) if read-by-row is enabled.  We did
        this in earlier versions, but it disappeared somewhere along the line.
        This new generator code has restored that ability.
    
    commit 58e4a6481a745673f1e6305ae8053864eef98810
    Author: Willie Walker <william walker sun com>
    Date:   Sat Jun 27 06:53:03 2009 -0400
    
        Get spin buttons working with new braille generator
    
        This leaves comboboxes as the last thing to do for GTK+ widgets
    
    commit 8d18d21be4a19976eb582247bb8aa32e5793763d
    Author: Willie Walker <william walker sun com>
    Date:   Sat Jun 27 06:39:09 2009 -0400
    
        More work on braille generator
    
        Fixed a lot with row/column headers, text context, tree/list level, etc.
        Comboboxes and spin buttons still need work (the tests are failing).
    
    commit 2eab54e576625a6e6c9e968ebdb2ca81bcaee7b9
    Author: Willie Walker <william walker sun com>
    Date:   Fri Jun 26 19:50:47 2009 -0400
    
        Adjust braille spacing for tables and fix broken braille ancestry
    
    commit 90b80a42a760dda8887b1584007eb8c5867ae166
    Author: Willie Walker <william walker sun com>
    Date:   Fri Jun 26 17:50:34 2009 -0400
    
        Hook the new braile generator up
    
        This can be turned off by setting braillegenerator.py:EXPERIMENTAL to False
    
    commit d406d55ae11ed578f2452fd23d6b97bd39d696d4
    Author: Willie Walker <william walker sun com>
    Date:   Fri Jun 26 17:23:10 2009 -0400
    
        Add in guessing of braille region of focus
    
        This merely makes sure that there is a Component region in the list.
        The region of focus is the first Component region we find whose
        accessible is the object we generated the braille for.
    
    commit 2727d000ab591076bb39bc41eb15aa0648ed59b5
    Author: Willie Walker <william walker sun com>
    Date:   Fri Jun 26 16:09:49 2009 -0400
    
        More work on braille formatting. Start looking at braille context.
    
    commit 0719bac5011a3510811ef61826ecffc92d144b6e
    Author: Willie Walker <william walker sun com>
    Date:   Fri Jun 26 16:09:17 2009 -0400
    
        Move more methods from speech_generator.py to generator.py
    
    commit c21f9466065f5ea413563551f54cfe1d9a147608
    Author: Willie Walker <william walker sun com>
    Date:   Fri Jun 26 16:08:00 2009 -0400
    
        Add __str__ methods to braille regions to help debugging
    
    commit 9ecb02ff5b58b4e413b2c12ac0a883739d01d386
    Author: Willie Walker <william walker sun com>
    Date:   Fri Jun 26 02:24:47 2009 -0400
    
        Do the equivalent of setting the braille verbosity level to brief
    
        This was done in the old speech generator, and the goal was to get
        rid of the "CheckBox" role from bring repeated on the braille line
        when viewing the entire row.
    
    commit 99d51cf755dcc98f99fda19ce97ba131024d4a9b
    Author: Willie Walker <william walker sun com>
    Date:   Fri Jun 26 02:23:33 2009 -0400
    
        Fix bugs where arrays weren't being created, add in node level, and format to make things a little easier to read
    
    commit 29f3f0cc8a25e85161ae79018dc9f5e008a24c3a
    Author: Willie Walker <william walker sun com>
    Date:   Fri Jun 26 02:22:16 2009 -0400
    
        Eliminate double speaking of column header
    
    commit 02d960749c120d4642ef775d2bf3726195fd0f78
    Author: Willie Walker <william walker sun com>
    Date:   Thu Jun 25 18:10:46 2009 -0400
    
        Add braille formatting for ROLE_TABLE_CELL
    
        This was a substantial change and I moved a lot of code up into
        generator.py.  The benefit is that we now share a ton of logic
        between braille and speech when it comes to tables.  I need to
        figure out how to get rid of the CheckBox role when brailling
        table lines with checkboxes, though, and I'm now hearing some
        double-speaking of the header name when arrowing left to right
        across a row of checkboxes.  The test example is the "Tree Store"
        demo of gtk-demo.
    
    commit 78bdc6adba0007e65520606f2c565687452a5aa0
    Author: Willie Walker <william walker sun com>
    Date:   Thu Jun 25 15:34:09 2009 -0400
    
        Add braille formatting for ROLE_COMBO_BOX
    
    commit 59255017248a10f2c2591ddacfa13a9c8daba06e
    Author: Willie Walker <william walker sun com>
    Date:   Thu Jun 25 13:42:11 2009 -0400
    
        Add braille formatting for ROLE_MENU
    
    commit d3860ee0d25d5b92c7eab0fa12cf8d5f64b0cf50
    Author: Willie Walker <william walker sun com>
    Date:   Thu Jun 25 13:34:28 2009 -0400
    
        Add braille formatting for ROLE_SCROLL_PANE
    
    commit cf7869bba1775a98fc0f86e45689cfcb5d3a1794
    Author: Willie Walker <william walker sun com>
    Date:   Thu Jun 25 12:11:49 2009 -0400
    
        Add support for LIST_ITEM in braille formatting
    
        This also involved moving the node level information to generator.py
        and moving the strings to settings.py.  Note also that the computed
        node level is now part of the generator cache.
    
    commit 6ba7d3579626e6f95f9fb2b0aeb734f8b1426d4b
    Author: Willie Walker <william walker sun com>
    Date:   Thu Jun 25 10:56:54 2009 -0400
    
        Add formatting for ROLE_FRAME
    
    commit 5eb69fd42e02e341d1ce0bb50c945527ce76a697
    Author: Willie Walker <william walker sun com>
    Date:   Thu Jun 25 10:39:29 2009 -0400
    
        Implement text-like objects in braille formatting
    
    commit 99036afe8d70e96b5635371eeb43ad648aee86c3
    Author: Willie Walker <william walker sun com>
    Date:   Thu Jun 25 09:57:26 2009 -0400
    
        Implement some of the easier roles
    
        This also adds in the notion of the 'focused' formatting string being used
        if the object is the locus of focus.
    
    commit e56ee013fd70a6cfa28ca71fed827b3350f2c221
    Author: Willie Walker <william walker sun com>
    Date:   Wed Jun 24 21:32:15 2009 -0400
    
        Have asString add the delimiters instead of requiring space()
    
        This simplifies the formatting strings somewhat.
    
    commit f8ece49c9c7ff5aedcd8f2d797f78541d734a591
    Author: Willie Walker <william walker sun com>
    Date:   Wed Jun 24 13:17:28 2009 -0400
    
        Initial playing with format-driven braille generator

 po/POTFILES.in                                     |   20 +-
 src/orca/Makefile.am                               |    2 +-
 src/orca/braille.py                                |   18 +-
 src/orca/braille_generator.py                      |  351 ++++
 src/orca/braillegenerator.py                       | 1866 --------------------
 src/orca/default.py                                |   67 +-
 src/orca/formatting.py                             |  243 +++-
 src/orca/generator.py                              |  577 ++++++-
 src/orca/script.py                                 |    4 +-
 src/orca/scripts/apps/acroread.py                  |    6 +-
 src/orca/scripts/apps/evolution/script.py          |   12 +-
 src/orca/scripts/apps/liferea.py                   |    2 +-
 src/orca/scripts/apps/planner/braille_generator.py |   78 +-
 src/orca/scripts/apps/planner/speech_generator.py  |    2 +-
 .../scripts/apps/rhythmbox/braille_generator.py    |   40 +-
 src/orca/scripts/apps/rhythmbox/script.py          |   10 +
 .../scripts/apps/rhythmbox/speech_generator.py     |    8 +-
 src/orca/scripts/apps/soffice/braille_generator.py |  383 ++---
 src/orca/scripts/apps/soffice/formatting.py        |   18 +
 src/orca/scripts/apps/soffice/script.py            |    4 +-
 .../scripts/toolkits/Gecko/braille_generator.py    |  654 ++-----
 src/orca/scripts/toolkits/Gecko/formatting.py      |   66 +-
 src/orca/scripts/toolkits/Gecko/script.py          |   26 +-
 .../scripts/toolkits/Gecko/speech_generator.py     |    4 +-
 .../toolkits/J2SE-access-bridge/Makefile.am        |    1 -
 .../toolkits/J2SE-access-bridge/__init__.py        |    1 -
 .../J2SE-access-bridge/braillegenerator.py         |   89 -
 .../toolkits/J2SE-access-bridge/formatting.py      |    5 +
 .../scripts/toolkits/J2SE-access-bridge/script.py  |    8 +-
 src/orca/settings.py                               |   31 +
 src/orca/speech_generator.py                       |  458 +-----
 test/harness/utils.py                              |    2 +-
 test/keystrokes/firefox/codetalks_treegrid.py      |   20 +-
 test/keystrokes/firefox/dojo_bug_570566.py         |   18 +-
 test/keystrokes/firefox/dojo_spinner.py            |  104 +-
 test/keystrokes/firefox/dojo_tree.py               |   40 +-
 test/keystrokes/firefox/html_role_combo_box.py     |    6 +-
 .../firefox/label_guess_bugzilla_search.py         |   53 +-
 .../keystrokes/firefox/line_nav_bugzilla_search.py |  120 +-
 test/keystrokes/firefox/line_nav_enter_bug.py      |   10 +-
 test/keystrokes/firefox/line_nav_simple_form.py    |    8 +-
 test/keystrokes/firefox/line_nav_wiki.py           |    8 +-
 test/keystrokes/firefox/ms_tree_bug_570571.py      |   56 +-
 test/keystrokes/firefox/uiuc_tree.py               |   36 +-
 test/keystrokes/firefox/xul_role_combo_box.py      |   44 +-
 test/keystrokes/firefox/xul_role_radio_button.py   |    8 +-
 test/keystrokes/firefox/xul_role_tree.py           |   58 +-
 test/keystrokes/firefox/xul_role_tree_table.py     |   14 +-
 test/keystrokes/gtk-demo/role_column_header.py     |   12 +-
 test/keystrokes/gtk-demo/role_combo_box.py         |    2 +-
 test/keystrokes/gtk-demo/role_combo_box2.py        |   12 +-
 test/keystrokes/gtk-demo/role_radio_button.py      |   14 +-
 test/keystrokes/gtk-demo/role_spin_button.py       |    4 +-
 test/keystrokes/gtk-demo/role_table.py             |    4 +-
 test/keystrokes/gtk-demo/role_tree_table.py        |   20 +-
 test/keystrokes/oocalc/bug_361167.py               |   14 +-
 test/keystrokes/oocalc/bug_364407.py               |    7 +-
 test/keystrokes/oowriter/bug_350219.py             |    3 +-
 test/keystrokes/oowriter/bug_353268.py             |   16 +-
 test/keystrokes/oowriter/bug_362979.py             |    4 +-
 test/keystrokes/oowriter/bug_382408.py             |    8 +-
 test/keystrokes/oowriter/bug_382415.py             |    8 +-
 test/keystrokes/oowriter/bug_382880.py             |    8 +-
 test/keystrokes/oowriter/bug_382888.py             |    8 +-
 test/keystrokes/oowriter/bug_385828.py             |    6 +-
 test/keystrokes/oowriter/bug_435201.py             |   14 +-
 test/keystrokes/oowriter/bug_435226.py             |    6 +-
 test/keystrokes/oowriter/table_cells.py            |   10 +-
 .../oowriter/table_cells_structural_navigation1.py |   12 +-
 69 files changed, 2213 insertions(+), 3638 deletions(-)
---
diff --git a/po/POTFILES.in b/po/POTFILES.in
index 30711ab..780eb05 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -4,7 +4,7 @@
 orca.desktop.in
 src/orca/app_gui_prefs.py
 src/orca/bookmarks.py
-src/orca/braillegenerator.py
+src/orca/braille_generator.py
 src/orca/braille.py
 src/orca/chnames.py
 src/orca/default.py
@@ -20,35 +20,29 @@ src/orca/liveregions.py
 src/orca/mag.py
 src/orca/orca_console_prefs.py
 src/orca/orca-find.glade
-src/orca/orca_glade.py
 src/orca/orca_gui_find.py
-src/orca/orca_gui_main.py
 src/orca/orca_gui_prefs.py
 src/orca/orca.in
 src/orca/orca-mainwin.glade
 src/orca/orca.py
 src/orca/orca-quit.glade
-src/orca/orca_quit.py
 src/orca/orca-setup.glade
 src/orca/phonnames.py
-src/orca/pronunciation_dict.py
 src/orca/rolenames.py
 src/orca/scripts/apps/acroread.py
-src/orca/scripts/apps/ekiga.py
 src/orca/scripts/apps/evolution/script.py
 src/orca/scripts/apps/evolution/speech_generator.py
 src/orca/scripts/apps/gcalctool/script.py
 src/orca/scripts/apps/gedit/script.py
-src/orca/scripts/apps/gnome-keyring-ask.py
 src/orca/scripts/apps/gnome-mud.py
 src/orca/scripts/apps/gnome-search-tool.py
-src/orca/scripts/apps/gnome_segv2.py
+src/orca/scripts/apps/gtk-window-decorator.py
 src/orca/scripts/apps/liferea.py
 src/orca/scripts/apps/metacity.py
+src/orca/scripts/apps/nautilus.py
 src/orca/scripts/apps/notification-daemon.py
 src/orca/scripts/apps/notify-osd.py
 src/orca/scripts/apps/pidgin/script.py
-src/orca/scripts/apps/pidgin/speech_generator.py
 src/orca/scripts/apps/planner/braille_generator.py
 src/orca/scripts/apps/planner/speech_generator.py
 src/orca/scripts/apps/soffice/script.py
@@ -56,19 +50,15 @@ src/orca/scripts/apps/soffice/speech_generator.py
 src/orca/scripts/apps/soffice/structural_navigation.py
 src/orca/scripts/apps/Thunderbird/script.py
 src/orca/scripts/apps/Thunderbird/speech_generator.py
-src/orca/scripts/apps/gtk-window-decorator.py
 src/orca/scripts/toolkits/Gecko/bookmarks.py
+src/orca/scripts/toolkits/Gecko/braille_generator.py
 src/orca/scripts/toolkits/Gecko/script.py
 src/orca/scripts/toolkits/Gecko/speech_generator.py
-src/orca/scripts/toolkits/Gecko/structural_navigation.py
-src/orca/scripts/toolkits/J2SE-access-bridge/braillegenerator.py
-src/orca/scripts/toolkits/J2SE-access-bridge/speech_generator.py
 src/orca/settings.py
 src/orca/speechdispatcherfactory.py
 src/orca/speech_generator.py
-src/orca/speechserver.py
 src/orca/speech.py
+src/orca/speechserver.py
 src/orca/structural_navigation.py
 src/orca/text_attribute_names.py
 src/orca/tutorialgenerator.py
-src/orca/where_am_I.py
diff --git a/src/orca/Makefile.am b/src/orca/Makefile.am
index 2f980e7..e1266af 100644
--- a/src/orca/Makefile.am
+++ b/src/orca/Makefile.am
@@ -13,7 +13,7 @@ orca_python_PYTHON = \
 	app_prefs.py \
 	bookmarks.py \
 	braille.py \
-	braillegenerator.py \
+	braille_generator.py \
 	brlmon.py \
 	chnames.py \
 	dbusserver.py \
diff --git a/src/orca/braille.py b/src/orca/braille.py
index 501f877..11803e2 100644
--- a/src/orca/braille.py
+++ b/src/orca/braille.py
@@ -323,6 +323,9 @@ class Region:
             self.string = self.rawLine
             self.cursorOffset = cursorOffset
 
+    def __str__(self):
+        return "Region: '%s', %d" % (self.string, self.cursorOffset)
+
     def processRoutingKey(self, offset):
         """Processes a cursor routing key press on this Component.  The offset
         is 0-based, where 0 represents the leftmost character of string
@@ -453,6 +456,9 @@ class Component(Region):
 
         self.accessible = accessible
 
+    def __str__(self):
+        return "Component: '%s', %d" % (self.string, self.cursorOffset)
+
     def getCaretOffset(self, offset):
         """Returns the caret position of the given offset if the object
         has text with a caret.  Otherwise, returns -1.
@@ -494,6 +500,9 @@ class Link(Component):
         have the region expand on cursor."""
         Component.__init__(self, accessible, string, cursorOffset, '', True)
 
+    def __str__(self):
+        return "Link: '%s', %d" % (self.string, self.cursorOffset)
+
     def getAttributeMask(self, getLinkMask=True):
         """Creates a string which can be used as the attrOr field of brltty's
         write structure for the purpose of indicating text attributes and
@@ -528,12 +537,14 @@ class Text(Region):
         """
 
         self.accessible = accessible
-        if orca_state.activeScript:
+        if orca_state.activeScript and self.accessible:
             [string, self.caretOffset, self.lineOffset] = \
                  orca_state.activeScript.getTextLineAtCaret(self.accessible,
                                                             startOffset)
         else:
             string = ""
+            self.caretOffset = 0
+            self.lineOffset = 0
 
         string = string.decode("UTF-8")
         if label:
@@ -575,6 +586,9 @@ class Text(Region):
         if not self.contracted and not settings.disableBrailleEOL:
             self.string += self.eol
 
+    def __str__(self):
+        return "Text: '%s', %d" % (self.string, self.cursorOffset)
+
     def repositionCursor(self):
         """Attempts to reposition the cursor in response to a new
         caret position.  If it is possible (i.e., the caret is on
@@ -1165,7 +1179,7 @@ def refresh(panToCursor=True, targetCursorCell=0, getLinkMask=True):
 def displayRegions(regionInfo):
     """Displays a list of regions on a single line, setting focus to the
        specified region.  The regionInfo parameter is something that is
-       typically returned by a call to braillegenerator.getBrailleRegions.
+       typically returned by a call to braille_generator.generateBraille.
 
     Arguments:
     - regionInfo: a list where the first element is a list of regions
diff --git a/src/orca/braille_generator.py b/src/orca/braille_generator.py
new file mode 100644
index 0000000..3cc37cd
--- /dev/null
+++ b/src/orca/braille_generator.py
@@ -0,0 +1,351 @@
+# Orca
+#
+# Copyright 2005-2009 Sun Microsystems Inc.
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Library General Public
+# License as published by the Free Software Foundation; either
+# version 2 of the License, or (at your option) any later version.
+#
+# This library is 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.  See the GNU
+# Library General Public License for more details.
+#
+# You should have received a copy of the GNU Library General Public
+# License along with this library; if not, write to the
+# Free Software Foundation, Inc., Franklin Street, Fifth Floor,
+# Boston MA  02110-1301 USA.
+
+"""Utilities for obtaining braille presentations for objects."""
+
+__id__        = "$Id$"
+__version__   = "$Revision$"
+__date__      = "$Date$"
+__copyright__ = "Copyright (c) 2005-2009 Sun Microsystems Inc."
+__license__   = "LGPL"
+
+import pyatspi
+
+import braille
+import generator
+import orca_state
+import rolenames
+import settings
+
+from orca_i18n import ngettext  # for ngettext support
+
+class Space:
+    """A dummy class to indicate we want to insert a space into an
+    utterance, but only if there is text prior to the space."""
+    def __init__(self, delimiter=" "):
+        self.delimiter = delimiter
+
+SPACE = [Space()]
+
+class BrailleGenerator(generator.Generator):
+    """Takes accessible objects and produces a list of braille Regions
+    for those objects.  See the generateBraille method, which is the
+    primary entry point.  Subclasses can feel free to override/extend
+    the brailleGenerators instance field as they see fit."""
+
+    SKIP_CONTEXT_ROLES = (pyatspi.ROLE_MENU,
+                          pyatspi.ROLE_MENU_BAR,
+                          pyatspi.ROLE_PAGE_TAB_LIST,
+                          pyatspi.ROLE_COMBO_BOX)
+
+    def __init__(self, script):
+        generator.Generator.__init__(self, script, "braille")
+
+    def _addGlobals(self, globalsDict):
+        """Other things to make available from the formatting string.
+        """
+        generator.Generator._addGlobals(self, globalsDict)
+        globalsDict['space'] = self.space
+        globalsDict['Component'] = braille.Component
+        globalsDict['Region'] = braille.Region
+        globalsDict['Text'] = braille.Text
+        globalsDict['Link'] = braille.Link
+        globalsDict['asString'] = self.asString
+
+    def generateBraille(self, obj, **args):
+        if obj == orca_state.locusOfFocus \
+           and not args.get('formatType', None):
+            args['formatType'] = 'focused'
+        result = self.generate(obj, **args)
+
+        # We guess at the focused region.  It's going to be a
+        # Component or Text region whose accessible is the same
+        # as the object we're generating braille for.  There is
+        # a small hack-like thing here where we include knowledge
+        # that we represent the text area of editable comboboxes
+        # instead of the combobox itself.  We also do the same
+        # for table cells because they sometimes have children
+        # that we present.
+        #
+        try:
+            focusedRegion = result[0]
+        except:
+            focusedRegion = None
+        for region in result:
+            if isinstance(region, (braille.Component, braille.Text)) \
+               and region.accessible == obj:
+                focusedRegion = region
+                break
+            elif isinstance(region, braille.Text) \
+                 and obj.getRole() == pyatspi.ROLE_COMBO_BOX \
+                 and region.accessible.parent == obj:
+                focusedRegion = region
+                break
+            elif isinstance(region, braille.Component) \
+                 and obj.getRole() == pyatspi.ROLE_TABLE_CELL \
+                 and region.accessible.parent == obj:
+                focusedRegion = region
+                break
+
+        return [result, focusedRegion]
+
+    #####################################################################
+    #                                                                   #
+    # Name, role, and label information                                 #
+    #                                                                   #
+    #####################################################################
+
+    def _generateRoleName(self, obj, **args):
+        """Returns the role name for the object in an array of strings, with
+        the exception that the pyatspi.ROLE_UNKNOWN role will yield an
+        empty array.  Note that a 'role' attribute in args will
+        override the accessible role of the obj.
+        """
+        result = []
+        role = args.get('role', obj.getRole())
+        if (settings.brailleVerbosityLevel \
+            == settings.VERBOSITY_LEVEL_VERBOSE)\
+           and not args.get('readingRow', False)\
+           and (role != pyatspi.ROLE_UNKNOWN):
+            result.append(rolenames.getBrailleForRoleName(obj, role))
+        return result
+
+    #####################################################################
+    #                                                                   #
+    # Keyboard shortcut information                                     #
+    #                                                                   #
+    #####################################################################
+
+    def _generateAccelerator(self, obj, **args):
+        """Returns an array of strings (and possibly voice and audio
+        specifications) that represent the accelerator for the object,
+        or an empty array if no accelerator can be found.
+        """
+        result = []
+        [mnemonic, shortcut, accelerator] = self._script.getKeyBinding(obj)
+        if accelerator:
+            result.append("(" + accelerator + ")")
+        return result
+
+    #####################################################################
+    #                                                                   #
+    # Hierarchy and related dialog information                          #
+    #                                                                   #
+    #####################################################################
+
+    def _generateAlertAndDialogCount(self, obj,  **args):
+        """Returns an array of strings that says how many alerts and dialogs
+        are associated with the application for this object.  [[[WDW -
+        I wonder if this string should be moved to settings.py.]]]
+        """
+        result = []
+        alertAndDialogCount = \
+            self._script.getUnfocusedAlertAndDialogCount(obj)
+        if alertAndDialogCount > 0:
+            # Translators: this tells the user how many unfocused
+            # alert and dialog windows plus the total number of
+            # windows that this application has.
+            #
+            result.append(ngettext("(%d dialog)",
+                                   "(%d dialogs)",
+                                   alertAndDialogCount) % alertAndDialogCount)
+        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
+        the object.  This is typically used to present the context for
+        an object (e.g., the names of the window, the panels, etc.,
+        that the object is contained in).  If the 'priorObj' attribute
+        of the args dictionary is set, only the differences in
+        ancestry between the 'priorObj' and the current obj will be
+        computed.  The 'priorObj' is typically set by Orca to be the
+        previous object with focus.
+        """
+        result = []
+        if not settings.enableBrailleContext:
+            return result
+        args['includeContext'] = False
+
+        # Radio button group names are treated separately from the
+        # ancestors.  However, they can appear in the ancestry as a
+        # labeled panel.  So, we need to exlude the first one of
+        # these things we come across.  See also the
+        # generator.py:_generateRadioButtonGroup method that is
+        # used to find the radio button group name.
+        #
+        role = args.get('role', obj.getRole())
+        excludeRadioButtonGroup = role == pyatspi.ROLE_RADIO_BUTTON
+
+        parent = obj.parent
+        if parent and (parent.getRole() in self.SKIP_CONTEXT_ROLES):
+            parent = parent.parent
+        while parent and (parent.parent != parent):
+            parentResult = []
+            # [[[TODO: WDW - we might want to include more things here
+            # besides just those things that have labels.  For example,
+            # page tab lists might be a nice thing to include. Logged
+            # as bugzilla bug 319751.]]]
+            #
+            if (parent.getRole() != pyatspi.ROLE_FILLER) \
+                and (parent.getRole() != pyatspi.ROLE_SECTION) \
+                and (parent.getRole() != pyatspi.ROLE_SPLIT_PANE) \
+                and (not self._script.isLayoutOnly(parent)):
+                args['role'] = parent.getRole()
+                parentResult = self.generate(parent, **args)
+            # [[[TODO: HACK - we've discovered oddness in hierarchies
+            # such as the gedit Edit->Preferences dialog.  In this
+            # dialog, we have labeled groupings of objects.  The
+            # grouping is done via a FILLER with two children - one
+            # child is the overall label, and the other is the
+            # container for the grouped objects.  When we detect this,
+            # we add the label to the overall context.]]]
+            #
+            if parent.getRole() in [pyatspi.ROLE_FILLER,
+                                    pyatspi.ROLE_PANEL]:
+                label = self._script.getDisplayedLabel(parent)
+                if label and len(label) and not label.isspace():
+                    if not excludeRadioButtonGroup:
+                        args['role'] = parent.getRole()
+                        parentResult = self.generate(parent, **args)
+                    else:
+                        excludeRadioButtonGroup = False
+            if result and parentResult:
+                result.append(braille.Region(" "))
+            result.extend(parentResult)
+            parent = parent.parent
+        result.reverse()
+        return result
+
+    #####################################################################
+    #                                                                   #
+    # Unfortunate hacks.                                                #
+    #                                                                   #
+    #####################################################################
+
+    def _generateAsPageTabOrScrollPane(self, obj, **args):
+        """If this scroll pane is labelled by a page tab, then return the page
+        tab information for the braille context instead. Thunderbird
+        folder properties is such a case. See bug #507922 for more
+        details.
+        """
+        result = []
+        relations = obj.getRelationSet()
+        for relation in relations:
+            if relation.getRelationType() ==  pyatspi.RELATION_LABELLED_BY:
+                labelledBy = relation.getTarget(0)
+                result.extend(self.generate(labelledBy, **args))
+                break
+        if not result:
+            # NOTE: there is no REAL_ROLE_SCROLL_PANE in formatting.py
+            # because currently fallback to the default formatting.
+            # We will provide the support for someone to override this,
+            # however, so we use REAL_ROLE_SCROLL_PANE here.
+            #
+            oldRole = self._overrideRole('REAL_ROLE_SCROLL_PANE', args)
+            result.extend(self.generate(obj, **args))
+            self._restoreRole(oldRole, args)
+        return result
+
+    def _generateComboBoxTextObj(self, obj, **args):
+        """For a combo box, we check to see if the text is editable. If so,
+        then we want to show the text attributes (such as selection --
+        see bug 496846 for more details).  This will return an array
+        containing a single object, which is the accessible for the
+        text object. Note that this is different from the rest of the
+        generators, which all return an array of strings.  Yes, this
+        is a hack.
+        """
+        result = []
+        textObj = None
+        for child in obj:
+            if child and child.getRole() == pyatspi.ROLE_TEXT:
+                textObj = child
+        if textObj and textObj.getState().contains(pyatspi.STATE_EDITABLE):
+            result.append(textObj)
+        return result
+
+    def _generateIncludeContext(self, obj, **args):
+        """Returns True or False to indicate whether context should be
+        included or not.
+        """
+        # For multiline text areas, we only show the context if we
+        # are on the very first line.  Otherwise, we show only the
+        # line.
+        #
+        include = True
+        try:
+            text = obj.queryText()
+        except NotImplementedError:
+            text = None
+        if text and self._script.isTextArea(obj):
+            [lineString, startOffset, endOffset] = text.getTextAtOffset(
+                text.caretOffset,
+                pyatspi.TEXT_BOUNDARY_LINE_START)
+            include = startOffset == 0
+            if include:
+                for relation in obj.getRelationSet():
+                    if relation.getRelationType() \
+                            == pyatspi.RELATION_FLOWS_FROM:
+                        include = \
+                            not self._script.isTextArea(relation.getTarget(0))
+        return include
+
+    #####################################################################
+    #                                                                   #
+    # Other things for spacing                                          #
+    #                                                                   #
+    #####################################################################
+
+    def _generateEol(self, obj, **args):
+        result = []
+        if not args.get('mode', None):
+            args['mode'] = self._mode
+        args['stringType'] = 'eol'
+        result.append(self._script.formatting.getString(**args))
+        return result
+
+    def space(self, delimiter=" "):
+        if delimiter == " ":
+            return SPACE
+        else:
+            return [Space(delimiter)]
+
+    def asString(self, content, delimiter=" "):
+        combined = ""
+        prior = None
+        if isinstance(content, basestring):
+            combined = content
+        elif content and isinstance(content, list):
+            # Strip off leading and trailing spaces.
+            #
+            while content and isinstance(content[0], Space):
+                content = content[1:]
+            while content and isinstance(content[-1], Space):
+                content = content[0:-1]
+            for element in content:
+                if isinstance(element, Space) and prior:
+                    combined += element.delimiter
+                    prior = None
+                else:
+                    prior = self.asString(element)
+                    combined = self._script.appendString(combined,
+                                                         prior,
+                                                         delimiter)
+        return combined
diff --git a/src/orca/default.py b/src/orca/default.py
index 6d45a6f..06d84dd 100644
--- a/src/orca/default.py
+++ b/src/orca/default.py
@@ -75,6 +75,9 @@ class Script(script.Script):
     DISPLAYED_LABEL = 'displayedLabel'
     DISPLAYED_TEXT = 'displayedText'
     KEY_BINDING = 'keyBinding'
+    NESTING_LEVEL = 'nestingLevel'
+    NODE_LEVEL = 'nodeLevel'
+    REAL_ACTIVE_DESCENDANT = 'realActiveDescendant'
 
     def __init__(self, app):
         """Creates a new script for the given application.
@@ -3136,16 +3139,8 @@ class Script(script.Script):
             text = obj.queryText()
         except NotImplementedError:
             text = None
-        if text and self.isTextArea(obj):
-            [lineString, startOffset, endOffset] = text.getTextAtOffset(
-                text.caretOffset,
-                pyatspi.TEXT_BOUNDARY_LINE_START)
-            if startOffset == 0:
-                line.addRegions(self.brailleGenerator.getBrailleContext(obj))
-        else:
-            line.addRegions(self.brailleGenerator.getBrailleContext(obj))
 
-        result = self.brailleGenerator.getBrailleRegions(obj)
+        result = self.brailleGenerator.generateBraille(obj)
         line.addRegions(result[0])
 
         if extraRegion:
@@ -6251,6 +6246,13 @@ class Script(script.Script):
         manages its descendants.
         """
 
+        try:
+            return self.generatorCache[self.REAL_ACTIVE_DESCENDANT][obj]
+        except:
+            if not self.generatorCache.has_key(self.REAL_ACTIVE_DESCENDANT):
+                self.generatorCache[self.REAL_ACTIVE_DESCENDANT] = {}
+            realActiveDescendant = None
+
         # If obj is a table cell and all of it's children are table cells
         # (probably cell renderers), then return the first child which has
         # a non zero length text string. If no such object is found, just
@@ -6270,7 +6272,7 @@ class Script(script.Script):
                         continue
                     else:
                         if text.getText(0, -1):
-                            return child
+                            realActiveDescendant = child
 
         # [[[TODO: WDW - this is an odd hacky thing I've somewhat drawn
         # from Gnopernicus.  The notion here is that we get an active
@@ -6287,10 +6289,12 @@ class Script(script.Script):
         # comment is here to remind us this is being done in poor taste
         # and we need to eventually clean up our act.]]]
         #
-        if obj and obj.childCount:
-            return obj[-1]
-        else:
-            return obj
+        if not realActiveDescendant and obj and obj.childCount:
+            realActiveDescendant = obj[-1]
+
+        self.generatorCache[self.REAL_ACTIVE_DESCENDANT][obj] = \
+            realActiveDescendant or obj
+        return self.generatorCache[self.REAL_ACTIVE_DESCENDANT][obj]
 
     def isDesiredFocusedItem(self, obj, rolesList):
         """Called to determine if the given object and it's hierarchy of
@@ -6949,6 +6953,32 @@ class Script(script.Script):
 
         return [content.encode("UTF-8"), text.caretOffset, startOffset]
 
+    def getNestingLevel(self, obj):
+        """Determines the nesting level of this object in a list.  If this
+        object is not in a list relation, then 0 will be returned.
+
+        Arguments:
+        -obj: the Accessible object
+        """
+
+        if not obj:
+            return 0
+
+        try:
+            return self.generatorCache[self.NESTING_LEVEL][obj]
+        except:
+            if not self.generatorCache.has_key(self.NESTING_LEVEL):
+                self.generatorCache[self.NESTING_LEVEL] = {}
+
+        nestingLevel = 0
+        parent = obj.parent
+        while parent.parent.getRole() == pyatspi.ROLE_LIST:
+            nestingLevel += 1
+            parent = parent.parent
+
+        self.generatorCache[self.NESTING_LEVEL][obj] = nestingLevel
+        return self.generatorCache[self.NESTING_LEVEL][obj]
+
     def getNodeLevel(self, obj):
         """Determines the node level of this object if it is in a tree
         relation, with 0 being the top level node.  If this object is
@@ -6961,6 +6991,12 @@ class Script(script.Script):
         if not obj:
             return -1
 
+        try:
+            return self.generatorCache[self.NODE_LEVEL][obj]
+        except:
+            if not self.generatorCache.has_key(self.NODE_LEVEL):
+                self.generatorCache[self.NODE_LEVEL] = {}
+
         nodes = []
         node = obj
         done = False
@@ -6988,7 +7024,8 @@ class Script(script.Script):
             else:
                 done = True
 
-        return len(nodes) - 1
+        self.generatorCache[self.NODE_LEVEL][obj] = len(nodes) - 1
+        return self.generatorCache[self.NODE_LEVEL][obj]
 
     def getChildNodes(self, obj):
         """Gets all of the children that have RELATION_NODE_CHILD_OF pointing
diff --git a/src/orca/formatting.py b/src/orca/formatting.py
index 4ba9ec3..9b6791e 100644
--- a/src/orca/formatting.py
+++ b/src/orca/formatting.py
@@ -36,7 +36,19 @@ import settings
 TUTORIAL = '(tutorial and (pause + tutorial) or [])'
 MNEMONIC = '(mnemonic and (pause + mnemonic + lineBreak) or [])'
 
+BRAILLE_TEXT = '[Text(obj, asString(label), asString(eol))]\
+                + (required and [Region(" " + asString(required))])\
+                + (readOnly and [Region(" " + asString(readOnly))])'
+
 formatting = {
+
+    ####################################################################
+    #                                                                  #
+    # Strings Orca includes on its own (versus getting them from the   #
+    # application.                                                     #
+    #                                                                  #
+    ####################################################################
+
     'strings' : {
         'speech' : {
             'required'     : settings.speechRequiredStateString,
@@ -46,6 +58,8 @@ formatting = {
             'radiobutton'  : settings.speechRadioButtonIndicators,
             'togglebutton' : settings.speechToggleButtonIndicators,
             'expansion'    : settings.speechExpansionIndicators,
+            'nodelevel'    : settings.speechNodeLevelString,
+            'nestinglevel' : settings.speechNestingLevelString,
             'multiselect'  : settings.speechMultiSelectString,
         },
         'braille' : {
@@ -57,9 +71,17 @@ formatting = {
             'radiobutton'  : settings.brailleRadioButtonIndicators,
             'togglebutton' : settings.brailleToggleButtonIndicators,
             'expansion'    : settings.brailleExpansionIndicators,
+            'nodelevel'    : settings.brailleNodeLevelString,
+            'nestinglevel' : settings.brailleNestingLevelString,
         },
     },
 
+    ####################################################################
+    #                                                                  #
+    # Formatting for speech.                                           #
+    #                                                                  #
+    ####################################################################
+
     'speech': {
         'prefix': {
             'focused': '[]',
@@ -233,7 +255,8 @@ formatting = {
             'basicWhereAmI': 'labelAndName + allTextSelection + roleName + availability + noChildren'
             },
         pyatspi.ROLE_TABLE_CELL: {
-            'focused': '(tableCell2ChildLabel + tableCell2ChildToggle) or cellCheckedState + (expandableState and (expandableState + numberOfChildren))',
+            'focused': '(tableCell2ChildLabel + tableCell2ChildToggle)\
+                        or (cellCheckedState + (expandableState and (expandableState + numberOfChildren)))',
             'unfocused': 'tableCellRow',
             'basicWhereAmI': 'parentRoleName + columnHeader + rowHeader + roleName + cellCheckedState + (realActiveDescendantDisplayedText or imageDescription + image) + columnAndRow + expandableState + nodeLevel',
             'detailedWhereAmI': 'parentRoleName + columnHeader + rowHeader + roleName + cellCheckedState + (realActiveDescendantDisplayedText or imageDescription + image) + columnAndRow + tableCellRow + expandableState + nodeLevel'
@@ -244,8 +267,14 @@ formatting = {
             # read a whole row. It calls REAL_ROLE_TABLE_CELL internally.
             # maybe it can be done in a cleaner way?
             #
-            'focused': '(tableCell2ChildLabel + tableCell2ChildToggle) or cellCheckedState + (expandableState and (expandableState + numberOfChildren))',
-            'unfocused': '(tableCell2ChildLabel + tableCell2ChildToggle) or cellCheckedState + (realActiveDescendantDisplayedText or imageDescription + image) + (expandableState and (expandableState + numberOfChildren)) + required'
+            'focused':   '(tableCell2ChildLabel + tableCell2ChildToggle)\
+                          or (cellCheckedState + (expandableState and (expandableState + numberOfChildren)))',
+            'unfocused': '(tableCell2ChildLabel + tableCell2ChildToggle)\
+                          or (columnHeaderIfToggleAndNoText\
+                              + cellCheckedState\
+                              + (realActiveDescendantDisplayedText or imageDescription + image)\
+                              + (expandableState and (expandableState + numberOfChildren))\
+                              + required)'
             },
         pyatspi.ROLE_TEAROFF_MENU_ITEM: {
             'focused': '[]',
@@ -272,6 +301,214 @@ formatting = {
             'unfocused': 'labelAndName',
             'basicWhereAmI': 'labelAndName'
             },
+    },
+
+    ####################################################################
+    #                                                                  #
+    # Formatting for braille.                                          #
+    #                                                                  #
+    ####################################################################
+
+    'braille': {
+        'prefix': {
+#            'focused':   'ancestors\
+#                         + (rowHeader and [Region(" " + asString(rowHeader))])\
+#                         + (columnHeader and [Region(" " + asString(columnHeader))])\
+#                         + (radioButtonGroup and [Region(" " + asString(radioButtonGroup))])\
+#                         + [Region(" ")]',
+#            'unfocused': 'ancestors\
+#                         + (rowHeader and [Region(" " + asString(rowHeader))])\
+#                         + (columnHeader and [Region(" " + asString(columnHeader))])\
+#                         + (radioButtonGroup and [Region(" " + asString(radioButtonGroup))])\
+#                         + [Region(" ")]',
+            'focused':   '(includeContext\
+                           and (ancestors\
+                                + (rowHeader and [Region(" " + asString(rowHeader))])\
+                                + (columnHeader and [Region(" " + asString(columnHeader))])\
+                                + (radioButtonGroup and [Region(" " + asString(radioButtonGroup))])\
+                                + [Region(" ")])\
+                           or [])',
+            'unfocused': '(includeContext\
+                           and (ancestors\
+                                + (rowHeader and [Region(" " + asString(rowHeader))])\
+                                + (columnHeader and [Region(" " + asString(columnHeader))])\
+                                + (radioButtonGroup and [Region(" " + asString(radioButtonGroup))])\
+                                + [Region(" ")])\
+                           or [])',
+            },
+        'suffix': {
+            'focused':   '(nodeLevel and [Region(" " + asString(nodeLevel))])',
+            'unfocused': '(nodeLevel and [Region(" " + asString(nodeLevel))])',
+            },
+        'default': {
+            'focused':   '[Component(obj,\
+                                     asString(label + displayedText + value + roleName + required))]',
+            'unfocused': '[Component(obj,\
+                                     asString(label + displayedText + value + roleName + required))]',
+            },
+        #pyatspi.ROLE_ALERT: 'default'
+        pyatspi.ROLE_ANIMATION: {
+            'unfocused': '[Component(obj,\
+                                     asString(label + displayedText + roleName + (description and space(": ") + description)))]',
+            },
+        #pyatspi.ROLE_ARROW: 'default'
+        pyatspi.ROLE_CHECK_BOX: {
+            'unfocused': '[Component(obj,\
+                                     asString(label + displayedText + roleName),\
+                                     indicator=asString(checkedState))]'
+            },
+        pyatspi.ROLE_CHECK_MENU_ITEM: {
+            'unfocused': '[Component(obj,\
+                                     asString(label + displayedText + roleName + availability) + asString(accelerator),\
+                                     indicator=asString(checkedState))]'
+            },
+        #pyatspi.ROLE_COLUMN_HEADER: 'default'
+        pyatspi.ROLE_COMBO_BOX: {
+            # [[[TODO: WDW - maybe pass the label into the region constructor?
+            # We could then use the cursorOffset field to indicate where the
+            # combobox starts.]]]
+            #
+            'unfocused': '((comboBoxTextObj and [Text(comboBoxTextObj[0], asString(label))])\
+                           or [Component(obj, asString(label + displayedText), label and (len(asString(label)) + 1) or 0)])\
+                          + [Region(" " + asString(roleName))]'
+            },
+        #pyatspi.ROLE_DESKTOP_ICON: 'default'
+        #pyatspi.ROLE_DIAL: 'default'
+        #pyatspi.ROLE_DIALOG: 'default'
+        #pyatspi.ROLE_DIRECTORY_PANE: 'default'
+        pyatspi.ROLE_EMBEDDED: {
+            'unfocused': '[Component(obj,\
+                                     asString(label + displayedText) or asString(applicationName))]'
+            },
+        pyatspi.ROLE_ENTRY: {
+            'unfocused': BRAILLE_TEXT
+            },
+        pyatspi.ROLE_FRAME: {
+            'unfocused': '[Component(obj,\
+                                     asString(((label + displayedText) or name) + value + roleName + alertAndDialogCount))]'
+            },
+        #pyatspi.ROLE_HTML_CONTAINER: 'default'
+        pyatspi.ROLE_ICON: {
+            'unfocused': '[Component(obj,\
+                                     asString(label + displayedText + imageDescription + roleName))]'
+            },
+        #pyatspi.ROLE_IMAGE: 'default'
+        pyatspi.ROLE_LABEL: {
+            'unfocused': '[Text(obj,\
+                                asString(label),\
+                                asString(eol))]'
+            },
+        #pyatspi.ROLE_LIST: 'default'
+        pyatspi.ROLE_LIST_ITEM: {
+            'focused':   '[Component(obj,\
+                                     asString(label + displayedText + expandableState + roleName + availability) + asString(accelerator))]\
+                          + (nestingLevel and [Region(" " + asString(nestingLevel))])',
+            'unfocused': '[Component(obj,\
+                                     asString(label + displayedText + expandableState))]\
+                          + (nestingLevel and [Region(" " + asString(nestingLevel))])',
+            },
+        pyatspi.ROLE_MENU: {
+            'focused':   '[Component(obj,\
+                                     asString(label + displayedText + roleName + availability) + asString(accelerator))]',
+            'unfocused': '[Component(obj,\
+                                     asString(label + displayedText + roleName))]',
+            },
+        #pyatspi.ROLE_MENU_BAR: 'default'
+        pyatspi.ROLE_MENU_ITEM: {
+            'unfocused': '[Component(obj,\
+                                     asString(label + displayedText + availability) + asString(accelerator),\
+                                     indicator=asString(menuItemCheckedState))]'
+            },
+        #pyatspi.ROLE_OPTION_PANE: 'default'
+        pyatspi.ROLE_PAGE_TAB: {
+            'focused':   '[Component(obj,\
+                                     asString(label + displayedText + roleName + availability) + asString(accelerator))]',
+            'unfocused': '[Component(obj,\
+                                     asString(label + displayedText + roleName))]'
+            },
+        #pyatspi.ROLE_PAGE_TAB_LIST: 'default'
+        pyatspi.ROLE_PANEL: {
+            'unfocused': '[Component(obj,\
+                                     asString((label or displayedText) + roleName))]'
+            },
+        pyatspi.ROLE_PARAGRAPH: {
+            'unfocused': BRAILLE_TEXT
+            },
+        pyatspi.ROLE_PASSWORD_TEXT: {
+            'unfocused': BRAILLE_TEXT
+            },
+        #pyatspi.ROLE_PROGRESS_BAR: 'default'
+        pyatspi.ROLE_PUSH_BUTTON: {
+            'unfocused': '[Component(obj,\
+                                     asString(((label + displayedText) or description) + roleName))]'
+            },
+        pyatspi.ROLE_RADIO_BUTTON: {
+            'unfocused': '[Component(obj,\
+                                     asString(((label + displayedText) or description) + roleName),\
+                                     indicator=asString(radioState))]'
+            },
+        pyatspi.ROLE_RADIO_MENU_ITEM: {
+            'focused':   '[Component(obj,\
+                                     asString(((label + displayedText) or description) + roleName + availability)\
+                                     + asString(accelerator),\
+                                     indicator=asString(radioState))]',
+            'unfocused': '[Component(obj,\
+                                     asString((label + displayedText) or description)\
+                                     + asString(accelerator),\
+                                     indicator=asString(radioState))]'
+            },
+        #pyatspi.ROLE_ROW_HEADER: 'default'
+        #pyatspi.ROLE_SCROLL_BAR: 'default'
+        pyatspi.ROLE_SCROLL_PANE: {
+            'unfocused': 'asPageTabOrScrollPane'
+            },
+        #'REAL_ROLE_SCROLL_PANE': 'default'
+        pyatspi.ROLE_SLIDER: {
+            'unfocused': '[Component(obj,\
+                                     asString(label + value + roleName + required))]'
+            },
+        pyatspi.ROLE_SPIN_BUTTON: {
+            'unfocused': '[Text(obj, asString(label), asString(eol))]\
+                          + (required and [Region(" " + asString(required))] or [])\
+                          + (readOnly and [Region(" " + asString(readOnly))] or [])'
+            },
+        #pyatspi.ROLE_SPLIT_PANE: 'default'
+        #pyatspi.ROLE_TABLE: 'default'
+        pyatspi.ROLE_TABLE_CELL: {
+            'unfocused': 'tableCellRow',
+            },
+        'REAL_ROLE_TABLE_CELL' : {
+            'unfocused': '(tableCell2ChildToggle + tableCell2ChildLabel)\
+                          or (cellCheckedState\
+                              + (columnHeaderIfToggleAndNoText and [Region(" "), Component(obj, asString(columnHeaderIfToggleAndNoText))])\
+                              + ((realActiveDescendantDisplayedText and [Component(obj, asString(realActiveDescendantDisplayedText))])\
+                                 or (imageDescription and [Region(" "), Component(obj, asString(imageDescription))]))\
+                              + (realActiveDescendantRoleName and [Component(obj, (realActiveDescendantDisplayedText and " " or "") + asString(realActiveDescendantRoleName))])\
+                              + (expandableState and [Region(" " + asString(expandableState))])\
+                              + (required and [Region(" " + asString(required))]))\
+                          or ([Component(obj,"")])'
+            },
+        #pyatspi.ROLE_TABLE_COLUMN_HEADER: 'default'
+        #pyatspi.ROLE_TABLE_ROW_HEADER: 'default'
+        pyatspi.ROLE_TEAROFF_MENU_ITEM: {
+            'unfocused': '[Component(obj,\
+                                     asString(roleName))]'
+            },
+        pyatspi.ROLE_TERMINAL: {
+            'unfocused': '[Text(obj)]'
+            },
+        pyatspi.ROLE_TEXT: {
+            'unfocused': BRAILLE_TEXT
+            },
+        pyatspi.ROLE_TOGGLE_BUTTON: {
+            'unfocused': '[Component(obj,\
+                                     asString(((label + displayedText) or description) + roleName),\
+                                     indicator=asString(toggleState))]'
+            },
+        #pyatspi.ROLE_TOOL_BAR: 'default'
+        #pyatspi.ROLE_TREE: 'default'
+        #pyatspi.ROLE_TREE_TABLE: 'default'
+        #pyatspi.ROLE_WINDOW: 'default'
     }
 }
 
diff --git a/src/orca/generator.py b/src/orca/generator.py
index 164b7ad..6da06c6 100644
--- a/src/orca/generator.py
+++ b/src/orca/generator.py
@@ -28,10 +28,15 @@ __license__   = "LGPL"
 import sys
 import traceback
 
-import debug
 import pyatspi
+
+import braille
+import debug
+import rolenames
 import settings
 
+from orca_i18n import _         # for gettext support
+
 def _formatExceptionInfo(maxTBlevel=5):
     cla, exc, trbk = sys.exc_info()
     excName = cla.__name__
@@ -211,8 +216,13 @@ class Generator:
             else:
                 firstTimeCalled = False
 
-            debug.println(debug.LEVEL_ALL, "generate %s for %s using '%s'" \
-                          % (self._mode, repr(args), format))
+            debug.println(
+                debug.LEVEL_ALL,
+                "generate %s for %s (args=%s) using '%s'" \
+                % (self._mode,
+                   debug.getAccessibleDetails(obj),
+                   repr(args),
+                   format))
 
             assert(format)
             while True:
@@ -238,8 +248,9 @@ class Generator:
             debug.printException(debug.LEVEL_SEVERE)
             result = []
 
-        debug.println(debug.LEVEL_ALL,
-                      "generate %s generated '%s'" % (self._mode, repr(result)))
+        debug.println(debug.LEVEL_ALL, "generate %s results:" % self._mode)
+        for element in result:
+            debug.println(debug.LEVEL_ALL, "  " + str(element))
 
         return result
 
@@ -249,6 +260,75 @@ class Generator:
     #                                                                   #
     #####################################################################
 
+    def _generateRoleName(self, obj, **args):
+        """Returns the role name for the object in an array of strings, with
+        the exception that the pyatspi.ROLE_UNKNOWN role will yield an
+        empty array.  Note that a 'role' attribute in args will
+        override the accessible role of the obj.
+        """
+        # Subclasses must override this.
+        return []
+
+    def _generateName(self, obj, **args):
+        """Returns an array of strings for use by speech and braille that
+        represent the name of the object.  If the object is directly
+        displaying any text, that text will be treated as the name.
+        Otherwise, the accessible name of the object will be used.  If
+        there is no accessible name, then the description of the
+        object will be used.  This method will return an empty array
+        if nothing can be found.  [[[WDW - I wonder if we should just
+        have _generateName, _generateDescription,
+        _generateDisplayedText, etc., that don't do any fallback.
+        Then, we can allow the formatting to do the fallback (e.g.,
+        'displayedText or name or description'). [[[JD to WDW - I
+        needed a _generateDescription for whereAmI. :-) See below.
+        """
+        result = []
+        name = self._script.getDisplayedText(obj)
+        if name:
+            result.append(name)
+        elif obj.description:
+            result.append(obj.description)
+        return result
+
+    def _generateLabelAndName(self, obj, **args):
+        """Returns the label and the name as an array of strings for speech
+        and braille.  The name will only be present if the name is
+        different from the label.
+        """
+        result = []
+        label = self._generateLabel(obj, **args)
+        name = self._generateName(obj, **args)
+        result.extend(label)
+        if not len(label):
+            result.extend(name)
+        elif len(name) and name[0] != label[0]:
+            result.extend(name)
+        return result
+
+    def _generateLabelOrName(self, obj, **args):
+        """Returns the label as an array of strings for speech and braille.
+        If the label cannot be found, the name will be used instead.
+        If the name cannot be found, an empty array will be returned.
+        """
+        result = []
+        result.extend(self._generateLabel(obj, **args))
+        if not result:
+            if obj.name and (len(obj.name)):
+                result.append(obj.name)
+        return result
+
+    def _generateDescription(self, obj, **args):
+        """Returns an array of strings fo use by speech and braille that
+        represent the description of the object, if that description
+        is different from that of the name and label.
+        """
+        result = []
+        label = self._script.getDisplayedLabel(obj)
+        if obj.description and not obj.description in [obj.name, label]:
+            result.append(obj.description)
+        return result
+
     def _generateLabel(self, obj, **args):
         """Returns the label for an object as an array of strings for use by
         speech and braille.  The label is determined by the
@@ -263,6 +343,28 @@ class Generator:
 
     #####################################################################
     #                                                                   #
+    # Image information                                                 #
+    #                                                                   #
+    #####################################################################
+
+    def _generateImageDescription(self, obj, **args ):
+        """Returns an array of strings for use by speech and braille that
+        represent the description of the image on the object, if it
+        exists.  Otherwise, an empty array is returned.
+        """
+        result = []
+        try:
+            image = obj.queryImage()
+        except NotImplementedError:
+            pass
+        else:
+            description = image.imageDescription
+            if description and len(description):
+                result.append(description)
+        return result
+
+    #####################################################################
+    #                                                                   #
     # State information                                                 #
     #                                                                   #
     #####################################################################
@@ -312,6 +414,30 @@ class Generator:
             result.append(self._script.formatting.getString(**args))
         return result
 
+    def _generateCellCheckedState(self, obj, **args):
+        """Returns an array of strings for use by speech and braille that
+        represent the checked state of the object.  This is typically
+        for check boxes that are in a table. An empty array will be
+        returned if this is not a checkable cell.
+        """
+        result = []
+        try:
+            action = obj.queryAction()
+        except NotImplementedError:
+            action = None
+        if action:
+            for i in range(0, action.nActions):
+                # Translators: this is the action name for
+                # the 'toggle' action. It must be the same
+                # string used in the *.po file for gail.
+                #
+                if action.getName(i) in ["toggle", _("toggle")]:
+                    oldRole = self._overrideRole(pyatspi.ROLE_CHECK_BOX,
+                                            args)
+                    result.extend(self.generate(obj, **args))
+                    self._restoreRole(oldRole, args)
+        return result
+
     def _generateCheckedState(self, obj, **args):
         """Returns an array of strings for use by speech and braille that
         represent the checked state of the object.  This is typically
@@ -406,10 +532,346 @@ class Generator:
 
     #####################################################################
     #                                                                   #
+    # Table interface information                                       #
+    #                                                                   #
+    #####################################################################
+
+    def _generateRowHeader(self, obj, **args):
+        """Returns an array of strings to be used in speech and braille that
+        represent the row header for an object that is in a table, if
+        it exists.  Otherwise, an empty array is returned.
+        """
+        result = []
+
+        # Do not return yourself as a header.
+        #
+        role = args.get('role', obj.getRole())
+        if role in [pyatspi.ROLE_ROW_HEADER,
+                    pyatspi.ROLE_TABLE_ROW_HEADER]:
+            return result
+
+        if not args.get('mode', None):
+            args['mode'] = self._mode
+        try:
+            table = obj.parent.queryTable()
+        except:
+            pass
+        else:
+            index = self._script.getCellIndex(obj)
+            rowIndex = table.getRowAtIndex(index)
+            if rowIndex >= 0:
+                # Get the header information.  In Java Swing, the
+                # information is not exposed via the description
+                # but is instead a header object, so we fall back
+                # to that if it exists.
+                #
+                # [[[TODO: WDW - the more correct thing to do, I
+                # think, is to look at the row header object.
+                # We've been looking at the description for so
+                # long, though, that we'll give the description
+                # preference for now.]]]
+                #
+                desc = table.getRowDescription(rowIndex)
+                if not desc:
+                    header = table.getRowHeader(rowIndex)
+                    if header:
+                        desc = self._script.getDisplayedText(header)
+                if desc and len(desc):
+                    text = desc
+                    if args['mode'] == 'speech':
+                        if settings.speechVerbosityLevel \
+                           == settings.VERBOSITY_LEVEL_VERBOSE \
+                           and not args.get('formatType', None) \
+                                   in ['basicWhereAmI', 'detailedWhereAmI']:
+                            text += " " + rolenames.rolenames[\
+                                    pyatspi.ROLE_ROW_HEADER].speech
+                    elif args['mode'] == 'braille':
+                        if settings.brailleVerbosityLevel \
+                           == settings.VERBOSITY_LEVEL_VERBOSE:
+                            if settings.brailleRolenameStyle \
+                               == settings.BRAILLE_ROLENAME_STYLE_LONG:
+                                text = desc + " " + rolenames.rolenames[\
+                                       pyatspi.ROLE_ROW_HEADER].brailleLong
+                            else:
+                                text = desc + " " + rolenames.rolenames[\
+                                       pyatspi.ROLE_ROW_HEADER].brailleShort
+                    result.append(text)
+        return result
+
+    def _generateColumnHeader(self, obj, **args):
+        """Returns an array of strings (and possibly voice and audio
+        specifications) that represent the column header for an object
+        that is in a table, if it exists.  Otherwise, an empty array
+        is returned.
+        """
+        result = []
+
+        # Do not return yourself as a header.
+        #
+        role = args.get('role', obj.getRole())
+        if role in [pyatspi.ROLE_COLUMN_HEADER,
+                    pyatspi.ROLE_TABLE_COLUMN_HEADER]:
+            return result
+
+        try:
+            table = obj.parent.queryTable()
+        except:
+            pass
+        else:
+            index = self._script.getCellIndex(obj)
+            columnIndex = table.getColumnAtIndex(index)
+            if columnIndex >= 0:
+                # Get the header information.  In Java Swing, the
+                # information is not exposed via the description
+                # but is instead a header object, so we fall back
+                # to that if it exists.
+                #
+                # [[[TODO: WDW - the more correct thing to do, I
+                # think, is to look at the column header object.
+                # We've been looking at the description for so
+                # long, though, that we'll give the description
+                # preference for now.]]]
+                #
+                desc = table.getColumnDescription(columnIndex)
+                if not desc:
+                    header = table.getColumnHeader(columnIndex)
+                    if header:
+                        desc = self._script.getDisplayedText(header)
+                if desc and len(desc):
+                    text = desc
+                    if args['mode'] == 'speech':
+                        if settings.speechVerbosityLevel \
+                           == settings.VERBOSITY_LEVEL_VERBOSE \
+                           and not args.get('formatType', None) \
+                                   in ['basicWhereAmI', 'detailedWhereAmI']:
+                            text += " " + rolenames.rolenames[\
+                                    pyatspi.ROLE_COLUMN_HEADER].speech
+                    elif args['mode'] == 'braille':
+                        if settings.brailleVerbosityLevel \
+                           == settings.VERBOSITY_LEVEL_VERBOSE:
+                            if settings.brailleRolenameStyle \
+                               == settings.BRAILLE_ROLENAME_STYLE_LONG:
+                                text = desc + " " + rolenames.rolenames[\
+                                       pyatspi.ROLE_COLUMN_HEADER].brailleLong
+                            else:
+                                text = desc + " " + rolenames.rolenames[\
+                                       pyatspi.ROLE_COLUMN_HEADER].brailleShort
+                    result.append(text)
+        return result
+
+    def _generateTableCell2ChildLabel(self, obj, **args):
+        """Returns an array of strings for use by speech and braille for the
+        label of a toggle in a table cell that has a special 2 child
+        pattern that we run into.  Otherwise, an empty array is
+        returned.
+        """
+        result = []
+
+        # If this table cell has 2 children and one of them has a
+        # 'toggle' action and the other does not, then present this
+        # as a checkbox where:
+        # 1) we get the checked state from the cell with the 'toggle' action
+        # 2) we get the label from the other cell.
+        # See Orca bug #376015 for more details.
+        #
+        if obj.childCount == 2:
+            cellOrder = []
+            hasToggle = [False, False]
+            for i, child in enumerate(obj):
+                try:
+                    action = child.queryAction()
+                except NotImplementedError:
+                    continue
+                else:
+                    for j in range(0, action.nActions):
+                        # Translators: this is the action name for
+                        # the 'toggle' action. It must be the same
+                        # string used in the *.po file for gail.
+                        #
+                        if action.getName(j) in ["toggle", _("toggle")]:
+                            hasToggle[i] = True
+                            break
+            if hasToggle[0] and not hasToggle[1]:
+                cellOrder = [ 1, 0 ]
+            elif not hasToggle[0] and hasToggle[1]:
+                cellOrder = [ 0, 1 ]
+            if cellOrder:
+                for i in cellOrder:
+                    if not hasToggle[i]:
+                        result.extend(self.generate(obj[i], **args))
+        return result
+
+    def _generateTableCell2ChildToggle(self, obj, **args):
+        """Returns an array of strings for use by speech and braille for the
+        toggle value of a toggle in a table cell that has a special 2
+        child pattern that we run into.  Otherwise, an empty array is
+        returned.
+        """
+        result = []
+
+        # If this table cell has 2 children and one of them has a
+        # 'toggle' action and the other does not, then present this
+        # as a checkbox where:
+        # 1) we get the checked state from the cell with the 'toggle' action
+        # 2) we get the label from the other cell.
+        # See Orca bug #376015 for more details.
+        #
+        if obj.childCount == 2:
+            cellOrder = []
+            hasToggle = [False, False]
+            for i, child in enumerate(obj):
+                try:
+                    action = child.queryAction()
+                except NotImplementedError:
+                    continue
+                else:
+                    for j in range(0, action.nActions):
+                        # Translators: this is the action name for
+                        # the 'toggle' action. It must be the same
+                        # string used in the *.po file for gail.
+                        #
+                        if action.getName(j) in ["toggle", _("toggle")]:
+                            hasToggle[i] = True
+                            break
+
+            if hasToggle[0] and not hasToggle[1]:
+                cellOrder = [ 1, 0 ]
+            elif not hasToggle[0] and hasToggle[1]:
+                cellOrder = [ 0, 1 ]
+            if cellOrder:
+                for i in cellOrder:
+                    if hasToggle[i]:
+                        result.extend(self.generate(obj[i], **args))
+        return result
+
+    def _generateColumnHeaderIfToggleAndNoText(self, obj, **args):
+        """If this table cell has a "toggle" action, and doesn't have any
+        label associated with it then also speak the table column
+        header.  See Orca bug #455230 for more details.
+        """
+        # If we're reading just a single cell in speech, the new
+        # header portion is going to give us this information.
+        #
+        if args['mode'] == 'speech' and not args.get('readingRow', False):
+            return []
+
+        result = []
+        try:
+            parentTable = obj.parent.queryTable()
+        except:
+            return result
+        try:
+            action = obj.queryAction()
+            label = self._script.getDisplayedText(
+                        self._script.getRealActiveDescendant(obj))
+        except NotImplementedError:
+            action = None
+            label = None
+        if action and (label == None or len(label) == 0):
+            index = self._script.getCellIndex(obj)
+            column = parentTable.getColumnAtIndex(index)
+            for j in range(0, action.nActions):
+                # Translators: this is the action name for
+                # the 'toggle' action. It must be the same
+                # string used in the *.po file for gail.
+                #
+                if action.getName(j) in ["toggle",
+                                         _("toggle")]:
+                    accHeader = \
+                        parentTable.getColumnHeader(column)
+                    result.append(accHeader.name)
+        return result
+
+    def _generateRealTableCell(self, obj, **args):
+        """Orca has a feature to automatically read an entire row of a table
+        as the user arrows up/down the roles.  This leads to
+        complexity in the code.  This method is used to return an
+        array of strings for use by speech and braille for a single
+        table cell itself.  The string, 'blank', is added for empty
+        cells.
+        """
+        result = []
+        oldRole = self._overrideRole('REAL_ROLE_TABLE_CELL', args)
+        result.extend(self.generate(obj, **args))
+        self._restoreRole(oldRole, args)
+        return result
+
+    def _generateTableCellRow(self, obj, **args):
+        """Orca has a feature to automatically read an entire row of a table
+        as the user arrows up/down the roles.  This leads to complexity in
+        the code.  This method is used to return an array of strings
+        (and possibly voice and audio specifications) for an entire row
+        in a table if that's what the user has requested and if the row
+        has changed.  Otherwise, it will return an array for just the
+        current cell.
+        """
+        result = []
+
+        try:
+            parentTable = obj.parent.queryTable()
+        except:
+            parentTable = None
+        isDetailedWhereAmI = args.get('formatType', None) == 'detailedWhereAmI'
+        if (settings.readTableCellRow or isDetailedWhereAmI) and parentTable \
+           and (not self._script.isLayoutOnly(obj.parent)):
+            parent = obj.parent
+            index = self._script.getCellIndex(obj)
+            row = parentTable.getRowAtIndex(index)
+            column = parentTable.getColumnAtIndex(index)
+
+            # This is an indication of whether we should speak all the
+            # table cells (the user has moved focus up or down a row),
+            # or just the current one (focus has moved left or right in
+            # the same row).
+            #
+            presentAll = True
+            if isDetailedWhereAmI:
+                if parentTable.nColumns <= 1:
+                    return result
+            elif "lastRow" in self._script.pointOfReference \
+               and "lastColumn" in self._script.pointOfReference:
+                pointOfReference = self._script.pointOfReference
+                presentAll = \
+                    (self._mode == 'braille') \
+                    or \
+                    ((pointOfReference["lastRow"] != row) \
+                     or ((row == 0 or row == parentTable.nRows-1) \
+                         and pointOfReference["lastColumn"] == column))
+            if presentAll:
+                args['readingRow'] = True
+                for i in range(0, parentTable.nColumns):
+                    cell = parentTable.getAccessibleAt(row, i)
+                    if not cell:
+                        continue
+                    state = cell.getState()
+                    showing = state.contains(pyatspi.STATE_SHOWING)
+                    if showing:
+                        cellResult = self._generateRealTableCell(cell, **args)
+                        if cellResult and result and self._mode == 'braille':
+                            result.append(braille.Region(
+                                    settings.brailleTableCellDelimiter))
+                        result.extend(cellResult)
+            else:
+                result.extend(self._generateRealTableCell(obj, **args))
+        else:
+            result.extend(self._generateRealTableCell(obj, **args))
+        return result
+
+    #####################################################################
+    #                                                                   #
     # Text interface information                                        #
     #                                                                   #
     #####################################################################
 
+    def _generateCurrentLineText(self, obj, **args ):
+        """Returns an array of strings for use by speech and braille
+        that represents the current line of text, if
+        this is a text object.  [[[WDW - consider returning an empty
+        array if this is not a text object.]]]
+        """
+        [text, caretOffset, startOffset] = self._script.getTextLineAtCaret(obj)
+        return [text]
+
     def _generateDisplayedText(self, obj, **args ):
         """Returns an array of strings for use by speech and braille that
         represents all the text being displayed by the object. [[[WDW
@@ -420,6 +882,27 @@ class Generator:
 
     #####################################################################
     #                                                                   #
+    # Tree interface information                                        #
+    #                                                                   #
+    #####################################################################
+
+    def _generateNodeLevel(self, obj, **args):
+        """Returns an array of strings for use by speech and braille that
+        represents the tree node level of the object, or an empty
+        array if the object is not a tree node.
+        """
+        result = []
+        if not args.get('mode', None):
+            args['mode'] = self._mode
+        args['stringType'] = 'nodelevel'
+        level = self._script.getNodeLevel(obj)
+        if level >= 0:
+            result.append(self._script.formatting.getString(**args)\
+                          % (level + 1))
+        return result
+
+    #####################################################################
+    #                                                                   #
     # Value interface information                                       #
     #                                                                   #
     #####################################################################
@@ -432,3 +915,87 @@ class Generator:
         consider returning an empty array if there is no value.
         """
         return [self._script.getTextForValue(obj)]
+
+    #####################################################################
+    #                                                                   #
+    # Hierarchy and related dialog information                          #
+    #                                                                   #
+    #####################################################################
+
+    def _generateApplicationName(self, obj, **args):
+        """Returns an array of strings for use by speech and braille that
+        represents the name of the applicaton for the object.
+        """
+        result = []
+        try:
+            result.append(obj.getApplication().name)
+        except:
+            pass
+        return result
+
+    def _generateNestingLevel(self, obj, **args):
+        """Returns an array of strings for use by speech and braille that
+        represent the nesting level of an object in a list.
+        """
+        result = []
+        if not args.get('mode', None):
+            args['mode'] = self._mode
+        args['stringType'] = 'nestinglevel'
+        nestingLevel = self._script.getNestingLevel(obj)
+        if nestingLevel:
+            result.append(self._script.formatting.getString(**args)\
+                          % nestingLevel)
+        return result
+
+    def _generateRadioButtonGroup(self, obj, **args):
+        """Returns an array of strings for use by speech and braille that
+        represents the radio button group label for the object, or an
+        empty array if the object has no such label.
+        """
+        result = []
+        if obj.getRole() == pyatspi.ROLE_RADIO_BUTTON:
+            radioGroupLabel = None
+            relations = obj.getRelationSet()
+            for relation in relations:
+                if (not radioGroupLabel) \
+                    and (relation.getRelationType() \
+                         == pyatspi.RELATION_LABELLED_BY):
+                    radioGroupLabel = relation.getTarget(0)
+                    break
+            if radioGroupLabel:
+                result.append(self._script.getDisplayedText(radioGroupLabel))
+            else:
+                parent = obj.parent
+                while parent and (parent.parent != parent):
+                    if parent.getRole() in [pyatspi.ROLE_PANEL,
+                                            pyatspi.ROLE_FILLER]:
+                        label = self._generateLabelAndName(parent)
+                        if label:
+                            result.extend(label)
+                            break
+                    parent = parent.parent
+        return result
+
+    def _generateRealActiveDescendantDisplayedText(self, obj, **args ):
+        """Objects, such as tables and trees, can represent individual cells
+        via a complicated nested hierarchy.  This method returns an
+        array of strings for use by speech and braille that represents
+        the text actually being painted in the cell, if it can be
+        found.  Otherwise, an empty array is returned.
+        """
+        result = []
+        text = self._script.getDisplayedText(
+          self._script.getRealActiveDescendant(obj))
+        if text:
+            result = [text]
+        return result
+
+    def _generateRealActiveDescendantRoleName(self, obj, **args ):
+        """Objects, such as tables and trees, can represent individual cells
+        via a complicated nested hierarchy.  This method returns an
+        array of strings for use by speech and braille that represents
+        the role of the object actually being painted in the cell.
+        """
+        rad = self._script.getRealActiveDescendant(obj)
+        args['role'] = rad.getRole()
+        return self._generateRoleName(rad, **args)
diff --git a/src/orca/script.py b/src/orca/script.py
index 458e869..5bbca01 100644
--- a/src/orca/script.py
+++ b/src/orca/script.py
@@ -39,7 +39,7 @@ __date__      = "$Date$"
 __copyright__ = "Copyright (c) 2005-2008 Sun Microsystems Inc."
 __license__   = "LGPL"
 
-import braillegenerator
+import braille_generator
 import debug
 import flat_review
 import formatting
@@ -188,7 +188,7 @@ class Script:
     def getBrailleGenerator(self):
         """Returns the braille generator for this script.
         """
-        return braillegenerator.BrailleGenerator(self)
+        return braille_generator.BrailleGenerator(self)
 
     def getSpeechGenerator(self):
         """Returns the speech generator for this script.
diff --git a/src/orca/scripts/apps/acroread.py b/src/orca/scripts/apps/acroread.py
index 175a75f..e52faa5 100644
--- a/src/orca/scripts/apps/acroread.py
+++ b/src/orca/scripts/apps/acroread.py
@@ -442,7 +442,7 @@ class Script(default.Script):
                  self.speechGenerator.generateSpeech(newLocusOfFocus)
             speech.speak(utterances)
             brailleRegions = \
-                 self.brailleGenerator.getBrailleRegions(newLocusOfFocus)
+                 self.brailleGenerator.generateBraille(newLocusOfFocus)
             braille.displayRegions(brailleRegions)
             orca.setLocusOfFocus(
                 event, newLocusOfFocus, notifyPresentationManager=False)
@@ -476,7 +476,7 @@ class Script(default.Script):
                 adjustedUtterances.append(self.adjustForRepeats(utterance))
             speech.speak(adjustedUtterances)
             brailleRegions = \
-                     self.brailleGenerator.getBrailleRegions(newLocusOfFocus)
+                     self.brailleGenerator.generateBraille(newLocusOfFocus)
             braille.displayRegions(brailleRegions)
             orca.setLocusOfFocus(
                 event, newLocusOfFocus, notifyPresentationManager=False)
@@ -558,7 +558,7 @@ class Script(default.Script):
                      self.speechGenerator.generateSpeech(event.source)
                 speech.speak(utterances)
                 brailleRegions = \
-                     self.brailleGenerator.getBrailleRegions(event.source)
+                     self.brailleGenerator.generateBraille(event.source)
                 braille.displayRegions(brailleRegions)
                 orca.setLocusOfFocus(
                     event, event.source, notifyPresentationManager=False)
diff --git a/src/orca/scripts/apps/evolution/script.py b/src/orca/scripts/apps/evolution/script.py
index abd6fb5..625f7d2 100644
--- a/src/orca/scripts/apps/evolution/script.py
+++ b/src/orca/scripts/apps/evolution/script.py
@@ -339,7 +339,7 @@ class Script(default.Script):
         speech.speak(utterances)
         settings.speechVerbosityLevel = savedSpeechVerbosityLevel
 
-        braille.displayRegions(brailleGen.getBrailleRegions(tab))
+        braille.displayRegions(brailleGen.generateBraille(tab))
 
     def getTimeForCalRow(self, row, noIncs):
         """Return a string equivalent to the time of the given row in
@@ -1088,7 +1088,7 @@ class Script(default.Script):
                                 includeContext=False,
                                 priorObj=oldLocusOfFocus)
                             [headerRegions, focusedRegion] = \
-                                         brailleGen.getBrailleRegions(header)
+                                         brailleGen.generateBraille(header)
                             brailleRegions.extend(headerRegions)
                             brailleRegions.append(braille.Region(" "))
 
@@ -1117,7 +1117,7 @@ class Script(default.Script):
                             includeContext=False,
                             priorObj=oldLocusOfFocus)
                         [cellRegions, focusedRegion] = \
-                                           brailleGen.getBrailleRegions(cell)
+                                           brailleGen.generateBraille(cell)
 
                         # Translators: this is the name of the
                         # status column header in the message
@@ -1210,7 +1210,7 @@ class Script(default.Script):
                                                   includeContext=False,
                                                   priorObj=oldLocusOfFocus)
             [brailleRegions, focusedRegion] = \
-                    brailleGen.getBrailleRegions(parent)
+                    brailleGen.generateBraille(parent)
             speech.speak(utterances)
 
             apptExtents = event.source.queryComponent().getExtents(0)
@@ -1229,7 +1229,7 @@ class Script(default.Script):
                                 includeContext=False,
                                 priorObj=oldLocusOfFocus)
                             [apptRegions, focusedRegion] = \
-                                brailleGen.getBrailleRegions(event.source)
+                                brailleGen.generateBraille(event.source)
                             brailleRegions.extend(apptRegions)
                             speech.speak(utterances)
 
@@ -1293,7 +1293,7 @@ class Script(default.Script):
                             includeContext=False,
                             priorObj=oldLocusOfFocus)
                         [apptRegions, focusedRegion] = \
-                            brailleGen.getBrailleRegions(child)
+                            brailleGen.generateBraille(child)
                         brailleRegions.extend(apptRegions)
                         speech.speak(utterances)
 
diff --git a/src/orca/scripts/apps/liferea.py b/src/orca/scripts/apps/liferea.py
index cd70f39..40898a4 100644
--- a/src/orca/scripts/apps/liferea.py
+++ b/src/orca/scripts/apps/liferea.py
@@ -125,7 +125,7 @@ class Script(default.Script):
             #
             speech.speak(utterances)
            
-            regions = brailleGen.getBrailleRegions(event.source)
+            regions = brailleGen.generateBraille(event.source)
             regions[0].insert(0, braille.Region(utterances[0] + " "))
             braille.displayRegions(regions)
            
diff --git a/src/orca/scripts/apps/planner/braille_generator.py b/src/orca/scripts/apps/planner/braille_generator.py
index 3c43b42..b4b643b 100644
--- a/src/orca/scripts/apps/planner/braille_generator.py
+++ b/src/orca/scripts/apps/planner/braille_generator.py
@@ -1,6 +1,6 @@
 # Orca
 #
-# Copyright 2006-2008 Sun Microsystems Inc.
+# Copyright 2006-2009 Sun Microsystems Inc.
 #
 # This library is free software; you can redistribute it and/or
 # modify it under the terms of the GNU Library General Public
@@ -22,66 +22,54 @@
 __id__        = "$Id$"
 __version__   = "$Revision$"
 __date__      = "$Date$"
-__copyright__ = "Copyright (c) 2006-2008 Sun Microsystems Inc."
+__copyright__ = "Copyright (c) 2006-2009 Sun Microsystems Inc."
 __license__   = "LGPL"
 
-import orca.braille as braille
-import orca.settings as settings
-import orca.braillegenerator as braillegenerator
 import pyatspi
 
+import orca.braille_generator as braille_generator
+
 from orca.orca_i18n import _ # for gettext support
 
-class BrailleGenerator(braillegenerator.BrailleGenerator):
+class BrailleGenerator(braille_generator.BrailleGenerator):
     """We make this to appropiately present ribbon's toggle button in
     a toolbar used to display in a menu those options that doesn't
     fill in toolbar when the application is resized. Also for each one
     of the grphics buttons in the main window."""
 
     def __init__(self, script):
-        braillegenerator.BrailleGenerator.__init__(self, script)
-
-    def _getBrailleRegionsForToggleButton(self, obj):
-        """Get the braille for a radio button.  If the button already had
-        focus, then only the state is displayed.
-
-        Arguments:
-        - obj: the check box
+        braille_generator.BrailleGenerator.__init__(self, script)
 
-        Returns a list where the first element is a list of Regions to display
-        and the second element is the Region which should get focus.
+    def _generateDisplayedText(self, obj, **args ):
+        """Returns an array of strings for use by braille that represents all
+        the text being displayed by the object. [[[WDW - consider
+        returning an empty array if this is not a text object.]]]
         """
+        result = []
 
-        self._debugGenerator("_getBrailleRegionsForRadioButton", obj)
-
-        text = ""
-        text = self._script.appendString(text, 
-                                         self._script.getDisplayedLabel(obj))
-        text = self._script.appendString(text, 
-                                         self._script.getDisplayedText(obj))
-
-        # First special toggle button is the one in the toolbar and
-        # that it has no name Application should implement an
-        # accessible name in this component, but until this is made We
-        # speech/braille "display more options" when the focus is in
-        # one of these toggle buttons.
+        # This is the black triangle at the far right of the toolbar.
         #
-        roleList = [pyatspi.ROLE_TOGGLE_BUTTON, pyatspi.ROLE_TOOL_BAR]
+        handleRibbonButton = \
+            obj and not obj.name \
+            and obj.getRole() == pyatspi.ROLE_TOGGLE_BUTTON \
+            and obj.parent.getRole() == pyatspi.ROLE_TOOL_BAR
 
-        if self._script.isDesiredFocusedItem(obj, roleList) and not obj.name:
-            text += _("Display more options")
-
-        text = self._script.appendString(text, self._getTextForRole(obj))
-
-        if obj.getState().contains(pyatspi.STATE_CHECKED):
-            brailleindicatorindex = 1
+        # This is one of the Gantt, Tasks, Resources, etc., buttons on the
+        # left hand side of the main window.
+        #
+        handleTabButton = \
+            obj and not obj.name \
+            and obj.getRole() == pyatspi.ROLE_TOGGLE_BUTTON \
+            and obj.parent.getRole() == pyatspi.ROLE_FILLER \
+            and len(obj.parent) == 2
+
+        if handleRibbonButton:
+            result.append(_("Display more options"))
+        elif handleTabButton:
+            result.append(self._script.getDisplayedText(obj.parent[1]))
         else:
-            brailleindicatorindex = 0
-
-        regions = []
-        indicator = \
-            settings.brailleRadioButtonIndicators[brailleindicatorindex]
-        componentRegion = braille.Component(obj, text, indicator=indicator)
-        regions.append(componentRegion)
+            result.extend(
+                braille_generator.BrailleGenerator._generateDisplayedText(
+                    self, obj, **args))
 
-        return [regions, componentRegion]
+        return result
diff --git a/src/orca/scripts/apps/planner/speech_generator.py b/src/orca/scripts/apps/planner/speech_generator.py
index 0931c44..c405202 100644
--- a/src/orca/scripts/apps/planner/speech_generator.py
+++ b/src/orca/scripts/apps/planner/speech_generator.py
@@ -64,7 +64,7 @@ class SpeechGenerator(speech_generator.SpeechGenerator):
         elif handleTabButton:
             result.append(self._script.getDisplayedText(obj.parent[1]))
         else:
-            result.append(
+            result.extend(
                 speech_generator.SpeechGenerator._generateLabelAndName(
                     self, obj, **args))
 
diff --git a/src/orca/scripts/apps/rhythmbox/braille_generator.py b/src/orca/scripts/apps/rhythmbox/braille_generator.py
index 755245c..e9fcbbc 100644
--- a/src/orca/scripts/apps/rhythmbox/braille_generator.py
+++ b/src/orca/scripts/apps/rhythmbox/braille_generator.py
@@ -1,6 +1,6 @@
 # Orca
 #
-# Copyright 2005-2008 Sun Microsystems Inc.
+# Copyright 2005-2009 Sun Microsystems Inc.
 #
 # This library is free software; you can redistribute it and/or
 # modify it under the terms of the GNU Library General Public
@@ -22,35 +22,21 @@
 __id__ = "$Id$"
 __version__   = "$Revision$"
 __date__      = "$Date$"
-__copyright__ = "Copyright (c) 2005-2008 Sun Microsystems Inc."
+__copyright__ = "Copyright (c) 2005-2009 Sun Microsystems Inc."
 __license__   = "LGPL"
 
-import orca.braillegenerator as braillegenerator
+import orca.braille_generator as braille_generator
 
-class BrailleGenerator(braillegenerator.BrailleGenerator):
-    """Overrides _getBrailleRegionsForTableCell to correctly handle 
-    the table cells in the Library table.
-    """
-
-    def __init__(self, script):
-        braillegenerator.BrailleGenerator.__init__(self, script)
-
-    def _getBrailleRegionsForTableCell(self, obj):
-        """Get the braille for a single table cell
+class BrailleGenerator(braille_generator.BrailleGenerator):
 
-        Arguments:
-        - obj: the table
+    # pylint: disable-msg=W0142
 
-        Returns a list where the first element is a list of Regions to 
-        display and the second element is the Region which should get focus.
-        """
-
-        # Check to see if this is a table cell from the Library table.
-        # If so, it'll have five children and we are interested in the
-        # penultimate one. See bug #512639 for more details.
-        #
-        if obj.childCount == 5:
-            obj = obj[3]
+    """Overrides _generateRealTableCell to correctly handle the table
+    cells in the Library table.
+    """
+    def __init__(self, script):
+        braille_generator.BrailleGenerator.__init__(self, script)
 
-        return braillegenerator.BrailleGenerator.\
-                    _getBrailleRegionsForTableCell(self, obj)
+    def _generateRealTableCell(self, obj, **args):
+        return braille_generator.BrailleGenerator._generateRealTableCell(
+            self, self._script.adjustTableCell(obj), **args)
diff --git a/src/orca/scripts/apps/rhythmbox/script.py b/src/orca/scripts/apps/rhythmbox/script.py
index a965800..0568290 100644
--- a/src/orca/scripts/apps/rhythmbox/script.py
+++ b/src/orca/scripts/apps/rhythmbox/script.py
@@ -54,3 +54,13 @@ class Script(default.Script):
     def getFormatting(self):
         """Returns the formatting strings for this script."""
         return Formatting(self)
+
+    def adjustTableCell(self, obj):
+        # Check to see if this is a table cell from the Library table.
+        # If so, it'll have five children and we are interested in the
+        # penultimate one. See bug #512639 for more details.
+        #
+        if obj.childCount == 5:
+            return obj[3]
+        else:
+            return obj
diff --git a/src/orca/scripts/apps/rhythmbox/speech_generator.py b/src/orca/scripts/apps/rhythmbox/speech_generator.py
index aaf3104..ee4dcea 100644
--- a/src/orca/scripts/apps/rhythmbox/speech_generator.py
+++ b/src/orca/scripts/apps/rhythmbox/speech_generator.py
@@ -38,11 +38,5 @@ class SpeechGenerator(speech_generator.SpeechGenerator):
         speech_generator.SpeechGenerator.__init__(self, script)
 
     def _generateRealTableCell(self, obj, **args):
-        # Check to see if this is a table cell from the Library table.
-        # If so, it'll have five children and we are interested in the
-        # penultimate one. See bug #512639 for more details.
-        #
-        if obj.childCount == 5:
-            obj = obj[3]
         return speech_generator.SpeechGenerator._generateRealTableCell(
-            self, obj, **args)
+            self, self._script.adjustTableCell(obj), **args)
diff --git a/src/orca/scripts/apps/soffice/braille_generator.py b/src/orca/scripts/apps/soffice/braille_generator.py
index b9a6ab1..0d3775d 100644
--- a/src/orca/scripts/apps/soffice/braille_generator.py
+++ b/src/orca/scripts/apps/soffice/braille_generator.py
@@ -1,6 +1,6 @@
 # Orca
 #
-# Copyright 2005-2008 Sun Microsystems Inc.
+# Copyright 2005-2009 Sun Microsystems Inc.
 #
 # This library is free software; you can redistribute it and/or
 # modify it under the terms of the GNU Library General Public
@@ -22,277 +22,219 @@
 __id__        = "$Id$"
 __version__   = "$Revision$"
 __date__      = "$Date$"
-__copyright__ = "Copyright (c) 2005-2008 Sun Microsystems Inc."
+__copyright__ = "Copyright (c) 2005-2009 Sun Microsystems Inc."
 __license__   = "LGPL"
 
 import pyatspi
 
 import orca.braille as braille
-import orca.braillegenerator as braillegenerator
+import orca.braille_generator as braille_generator
 import orca.settings as settings
 
-class BrailleGenerator(braillegenerator.BrailleGenerator):
-    """Overrides _getBrailleRegionsForTableCellRow so that , when we are
-    in a spread sheet, we can braille the dynamic row and column headers
-    (assuming they are set).
-    Overrides _getBrailleRegionsForTableCell so that, when we are in
-    a spread sheet, we can braille the location of the table cell as well
-    as the contents.
-    """
+class BrailleGenerator(braille_generator.BrailleGenerator):
 
-    def __init__(self, script):
-        braillegenerator.BrailleGenerator.__init__(self, script)
-
-    def _getTextForRole(self, obj, role=None):
-        if obj.getRole() == pyatspi.ROLE_DOCUMENT_FRAME \
-           or role == pyatspi.ROLE_DOCUMENT_FRAME:
-            return None
-
-        return braillegenerator.BrailleGenerator.\
-            _getTextForRole(self, obj, role)
-
-    def _getBrailleRegionsForList(self, obj):
-        """Get the braille for a focused list.
-
-        Arguments:
-        - obj: the list
-
-        Returns a list where the first element is a list of Regions to
-        display and the second element is the Region which should get
-        focus.
-        """
-
-        self._debugGenerator("soffice: _getBrailleRegionsForList", obj)
-
-        if not obj.getState().contains(pyatspi.STATE_FOCUSABLE):
-            return braillegenerator.BrailleGenerator.\
-                       _getBrailleRegionsForList(self, obj)
-
-        text = ""
-        label = self._script.getDisplayedLabel(obj)
-        if not label:
-            label = obj.name
-        if label and len(label):
-            text = self._script.appendString(text, label)
-
-        text = self._script.appendString(text, self._getTextForRole(obj))
-        text = self._script.appendString(text,
-                                         self._getTextForRequiredObject(obj))
-        regions = []
-        componentRegion = braille.Component(obj, text)
-        regions.append(componentRegion)
-
-        return [regions, componentRegion]
+    # pylint: disable-msg=W0142
 
-    def _getBrailleRegionsForTableCellRow(self, obj):
-        """Get the braille for a table cell row or a single table cell
-        if settings.readTableCellRow is False.
-
-        Arguments:
-        - obj: the table cell
-
-        Returns a list where the first element is a list of Regions to display
-        and the second element is the Region which should get focus.
+    def __init__(self, script):
+        braille_generator.BrailleGenerator.__init__(self, script)
+
+    def _generateRoleName(self, obj, **args):
+        result = []
+        role = args.get('role', obj.getRole())
+        if role != pyatspi.ROLE_DOCUMENT_FRAME:
+            result.extend(braille_generator.BrailleGenerator._generateRoleName(
+                self, obj, **args))
+        return result
+
+    def _generateRowHeader(self, obj, **args):
+        """Returns an array of strings that represent the row header for an
+        object that is in a table, if it exists.  Otherwise, an empty
+        array is returned. Overridden here so that we can get the
+        dynamic row header(s).
         """
-
-        focusRegion = None
-        regions = []
-
-        # Check to see if this spread sheet cell has either a dynamic
-        # column heading or row heading (or both) associated with it.
-        # If it does, then braille those first before brailling the
-        # cell contents.
-        #
-        table = self._script.getTable(obj)
-        parent = obj.parent
+        result = []
         try:
-            parentTable = parent.queryTable()
-        except NotImplementedError:
-            parentTable = None
-
-        index = self._script.getCellIndex(obj)
-        if "lastColumn" in self._script.pointOfReference and \
-              self._script.pointOfReference["lastColumn"] != \
-              parentTable.getColumnAtIndex(index):
-            if table in self._script.dynamicColumnHeaders:
-                row = self._script.dynamicColumnHeaders[table]
-                header = self._script.getDynamicRowHeaderCell(obj, row)
+            table = obj.parent.queryTable()
+        except:
+            pass
+        else:
+            index = self._script.getCellIndex(obj)
+            rowIndex = table.getRowAtIndex(index)
+            if rowIndex >= 0 \
+               and table in self._script.dynamicRowHeaders:
+                column = self._script.dynamicRowHeaders[table]
+                header = self._script.getDynamicColumnHeaderCell(obj, column)
                 try:
                     headerText = header.queryText()
                 except:
                     headerText = None
-
                 if header.childCount > 0:
                     for child in header:
                         text = self._script.getText(child, 0, -1)
                         if text:
-                            regions.append(braille.Region(" " + text + " "))
+                            result.append(text)
                 elif headerText:
                     text = self._script.getText(header, 0, -1)
                     if text:
-                        regions.append(braille.Region(" " + text + " "))
-
-        if "lastRow" in self._script.pointOfReference and \
-              self._script.pointOfReference['lastRow'] != \
-              parentTable.getRowAtIndex(index):
-            if table in self._script.dynamicRowHeaders:
-                column = self._script.dynamicRowHeaders[table]
-                header = self._script.getDynamicColumnHeaderCell(obj, column)
+                        result.append(text)
+        return result
+
+    def _generateColumnHeader(self, obj, **args):
+        """Returns an array of strings that represent the column header for an
+        object that is in a table, if it exists.  Otherwise, an empty
+        array is returned. Overridden here so that we can get the
+        dynamic column header(s).
+        """
+        result = []
+        try:
+            table = obj.parent.queryTable()
+        except:
+            pass
+        else:
+            index = self._script.getCellIndex(obj)
+            columnIndex = table.getColumnAtIndex(index)
+            if columnIndex >= 0 \
+               and table in self._script.dynamicColumnHeaders:
+                row = self._script.dynamicColumnHeaders[table]
+                header = self._script.getDynamicRowHeaderCell(obj, row)
                 try:
                     headerText = header.queryText()
                 except:
                     headerText = None
-
                 if header.childCount > 0:
                     for child in header:
                         text = self._script.getText(child, 0, -1)
                         if text:
-                            regions.append(braille.Region(" " + text + " "))
+                            result.append(text)
                 elif headerText:
                     text = self._script.getText(header, 0, -1)
                     if text:
-                        regions.append(braille.Region(" " + text + " "))
+                        result.append(text)
+        return result
+
+    def _generateSpreadSheetCell(self, obj, **args):
+        result = []
+        if self._script.inputLineForCell == None:
+            self._script.inputLineForCell = \
+                self._script.locateInputLine(obj)
+        # If the spread sheet table cell has something in it, then we
+        # want to append the name of the cell (which will be its
+        # location).  Note that if the cell was empty, then
+        # self._script.getDisplayedText will have already done this
+        # for us.
+        #
+        try:
+            if obj.queryText():
+                objectText = self._script.getText(obj, 0, -1)
+                if objectText and len(objectText) != 0:
+                    result.append(braille.Component(
+                        obj, objectText + " " + obj.name))
+                else:
+                    result.append(braille.Component(obj, obj.name))
+        except:
+            pass
+        return result
+
+    def _generateRealTableCell(self, obj, **args):
+        """Get the speech for a table cell. If this isn't inside a
+        spread sheet, just return the utterances returned by the default
+        table cell speech handler.
+
+        Arguments:
+        - obj: the table cell
 
+        Returns a list of utterances to be spoken for the object.
+        """
+        result = []
         if self._script.isSpreadSheetCell(obj):
+            result.extend(self._generateSpreadSheetCell(obj, **args))
+        else:
+            # Check to see how many children this table cell has. If it's
+            # just one (or none), then pass it on to the superclass to be
+            # processed.
+            #
+            # If it's more than one, then get the speech for each child,
+            # and call this method again.
+            #
+            if obj.childCount <= 1:
+                result.extend(braille_generator.BrailleGenerator.\
+                              _generateRealTableCell(self, obj, **args))
+            else:
+                for child in obj:
+                    cellResult = self._generateRealTableCell(child, **args)
+                    if cellResult and result and self._mode == 'braille':
+                        result.append(braille.Region(
+                                settings.brailleTableCellDelimiter))
+                    result.extend(cellResult)
+        return result
+
+    def _generateTableCellRow(self, obj, **args):
+        """Get the speech for a table cell row or a single table cell
+        if settings.readTableCellRow is False. If this isn't inside a
+        spread sheet, just return the utterances returned by the default
+        table cell speech handler.
 
+        Arguments:
+        - obj: the table cell
+
+        Returns a list of utterances to be spoken for the object.
+        """
+        result = []
+        if self._script.isSpreadSheetCell(obj):
             # Adding in a check here to make sure that the parent is a
             # valid table. It's possible that the parent could be a
             # table cell too (see bug #351501).
             #
+            parent = obj.parent
+            parentTable = parent.queryTable()
             if settings.readTableCellRow and parentTable:
-                rowRegions = []
-                savedBrailleVerbosityLevel = settings.brailleVerbosityLevel
-                settings.brailleVerbosityLevel = \
-                                             settings.VERBOSITY_LEVEL_BRIEF
-
-                parent = obj.parent
                 index = self._script.getCellIndex(obj)
                 row = parentTable.getRowAtIndex(index)
                 column = parentTable.getColumnAtIndex(index)
-
-                # This is an indication of whether we should speak all the
+                # This is an indication of whether we should present all the
                 # table cells (the user has moved focus up or down a row),
                 # or just the current one (focus has moved left or right in
                 # the same row).
                 #
-                speakAll = True
+                presentAll = True
                 if "lastRow" in self._script.pointOfReference and \
                     "lastColumn" in self._script.pointOfReference:
                     pointOfReference = self._script.pointOfReference
-                    speakAll = \
-                        (pointOfReference["lastRow"] != row) or \
-                           ((row == 0 or row == parentTable.nRows-1) and \
-                            pointOfReference["lastColumn"] == column)
-
-                if speakAll:
+                    presentAll = \
+                        (self._mode == 'braille') \
+                        or ((pointOfReference["lastRow"] != row) \
+                            or ((row == 0 or row == parentTable.nRows-1) \
+                                and pointOfReference["lastColumn"] == column))
+                if presentAll:
                     [startIndex, endIndex] = \
                         self._script.getSpreadSheetRowRange(obj)
                     for i in range(startIndex, endIndex+1):
                         cell = parentTable.getAccessibleAt(row, i)
                         showing = cell.getState().contains( \
-                                        pyatspi.STATE_SHOWING)
+                                      pyatspi.STATE_SHOWING)
                         if showing:
-                            [cellRegions, focusRegion] = \
-                                self._getBrailleRegionsForTableCell(cell)
-                            if len(rowRegions):
-                                rowRegions.append(braille.Region(" "))
-                            rowRegions.append(cellRegions[0])
-                    regions.extend(rowRegions)
-                    settings.brailleVerbosityLevel = savedBrailleVerbosityLevel
+                            cellResult = self._generateRealTableCell(cell,
+                                                                     **args)
+                            if cellResult and result \
+                               and self._mode == 'braille':
+                                result.append(braille.Region(
+                                        settings.brailleTableCellDelimiter))
+                            result.extend(cellResult)
                 else:
-                    [cellRegions, focusRegion] = \
-                                self._getBrailleRegionsForTableCell(obj)
-                    regions.extend(cellRegions)
+                    result.extend(self._generateRealTableCell(obj, **args))
             else:
-                [cellRegions, focusRegion] = \
-                                self._getBrailleRegionsForTableCell(obj)
-                regions.extend(cellRegions)
-            regions = [regions, focusRegion]
-        else:
-            [cellRegions, focusRegion] = \
-                braillegenerator.BrailleGenerator.\
-                    _getBrailleRegionsForTableCellRow(self, obj)
-            regions.extend(cellRegions)
-            regions = [regions, focusRegion]
-
-        return regions
-
-    def _getBrailleRegionsForTableCell(self, obj):
-        """Get the braille for a table cell. If this isn't inside a
-        spread sheet, just return the regions returned by the default
-        table cell braille handler.
-
-        Arguments:
-        - obj: the table cell
-
-        Returns a list where the first element is a list of Regions to display
-        and the second element is the Region which should get focus.
-        """
-
-        if self._script.isSpreadSheetCell(obj):
-            if self._script.inputLineForCell == None:
-                self._script.inputLineForCell = \
-                            self._script.locateInputLine(obj)
-
-            regions = []
-            text = self._script.getDisplayedText(obj)
-            componentRegion = braille.Component(obj, text)
-            regions.append(componentRegion)
-
-            # If the spread sheet table cell has something in it, then we
-            # want to append the name of the cell (which will be its location).
-            # Note that if the cell was empty, then
-            # self._script.getDisplayedText will have already done this for us.
-            #
-            try:
-                if obj.queryText():
-                    objectText = self._script.getText(obj, 0, -1)
-                    if objectText and len(objectText) != 0:
-                        regions.append(braille.Region(" " + obj.name))
-            except NotImplementedError:
-                pass
-
-            return [regions, componentRegion]
-
+                result.extend(self._generateRealTableCell(obj, **args))
         else:
-            # Check to see how many children this table cell has. If it's
-            # just one (or none), then pass it on to the superclass to be
-            # processed.
-            #
-            # If it's more than one, then get the braille regions for each
-            # child, and call this method again.
-            #
-            if obj.childCount <= 1:
-                regions = braillegenerator.BrailleGenerator.\
-                              _getBrailleRegionsForTableCell(self, obj)
-            else:
-                regions = []
-                for child in obj:
-                    [cellRegions, focusRegion] = \
-                                self._getBrailleRegionsForTableCell(child)
-                    regions.extend(cellRegions)
-                return [regions, focusRegion]
-
-        return regions
-
-    def _getBrailleRegionsForScrollPane(self, obj):
-        """Get the braille for a scroll pane.
-
-        Arguments:
-        - obj: the scroll pane
-
-        Returns a list where the first element is a list of Regions to display
-        and the second element is the Region which should get focus.
+            result.extend(
+                braille_generator.BrailleGenerator._generateTableCellRow(
+                    self, obj, **args))
+        return result
+
+    def _generateChildTab(self, obj, **args):
+        """If we are in the slide presentation scroll pane, also announce the
+        current page tab. See bug #538056 for more details.
         """
-
-        self._debugGenerator("soffice: _getBrailleRegionsForScrollPane", obj)
-
-        scrollRegions = braillegenerator.BrailleGenerator.\
-                               _getBrailleRegionsForScrollPane(self, obj)
-
-        # If we are in the slide presentation scroll pane, also announce
-        # the current page tab. See bug #538056 for more details.
-        #
+        result = []
         rolesList = [pyatspi.ROLE_SCROLL_PANE, \
                      pyatspi.ROLE_PANEL, \
                      pyatspi.ROLE_PANEL, \
@@ -305,9 +247,16 @@ class BrailleGenerator(braillegenerator.BrailleGenerator):
                     for tab in child:
                         eventState = tab.getState()
                         if eventState.contains(pyatspi.STATE_SELECTED):
-                            tabRegions = self.getBrailleRegions(tab)
-                            tabRegions[0].append(braille.Region(" ")) 
-                            tabRegions[0].extend(scrollRegions[0])
-                            return tabRegions
-
-        return scrollRegions
+                            args['role'] = tab.getRole()
+                            result.extend(self.generate(tab, **args))
+        return result
+
+    def generateBraille(self, obj, **args):
+        result = []
+        args['useDefaultFormatting'] = \
+            ((obj.getRole() == pyatspi.ROLE_LIST) \
+                and (not obj.getState().contains(pyatspi.STATE_FOCUSABLE)))
+        result.extend(braille_generator.BrailleGenerator.\
+                          generateBraille(self, obj, **args))
+        del args['useDefaultFormatting']
+        return result
diff --git a/src/orca/scripts/apps/soffice/formatting.py b/src/orca/scripts/apps/soffice/formatting.py
index 8680714..4fffc2c 100644
--- a/src/orca/scripts/apps/soffice/formatting.py
+++ b/src/orca/scripts/apps/soffice/formatting.py
@@ -67,6 +67,17 @@ formatting = {
             #
             'basicWhereAmI': 'roleName + column + columnHeader + row + rowHeader + (textContent or spreadSheetCell) + anyTextSelection'
             },
+    },
+    'braille': {
+        pyatspi.ROLE_LIST: {
+            'unfocused': '[Component(obj,\
+                                     asString(labelOrName + roleName + required))]'
+        },
+        pyatspi.ROLE_SCROLL_PANE: {
+            'unfocused': 'asPageTabOrScrollPane\
+                          + (childTab\
+                             and ([Region(" ")] + childTab) or [])'
+        }
     }
 }
 
@@ -74,3 +85,10 @@ class Formatting(orca.formatting.Formatting):
     def __init__(self, script):
         orca.formatting.Formatting.__init__(self, script)
         self.update(copy.deepcopy(formatting))
+        self._defaultFormatting = orca.formatting.Formatting(script)
+
+    def getFormat(self, **args):
+        if args.get('useDefaultFormatting', False):
+            return self._defaultFormatting.getFormat(**args)
+        else:
+            return orca.formatting.Formatting.getFormat(self, **args)
diff --git a/src/orca/scripts/apps/soffice/script.py b/src/orca/scripts/apps/soffice/script.py
index a8f2714..96fd9e5 100644
--- a/src/orca/scripts/apps/soffice/script.py
+++ b/src/orca/scripts/apps/soffice/script.py
@@ -1507,7 +1507,7 @@ class Script(default.Script):
                 textToSpeak = result[0].decode("UTF-8")
                 self._speakWriterText(event, textToSpeak)
                 braille.displayRegions(\
-                    brailleGen.getBrailleRegions(event.source))
+                    brailleGen.generateBraille(event.source))
                 return
 
         # Check to see if the object that just got focus is in the Setup
@@ -2262,7 +2262,7 @@ class Script(default.Script):
             textToSpeak = result.decode("UTF-8")
             self._speakWriterText(event, textToSpeak)
             braille.displayRegions( \
-                self.brailleGenerator.getBrailleRegions(event.source))
+                self.brailleGenerator.generateBraille(event.source))
         else:
             default.Script.onCaretMoved(self, event)
 
diff --git a/src/orca/scripts/toolkits/Gecko/braille_generator.py b/src/orca/scripts/toolkits/Gecko/braille_generator.py
index de22c19..4ceba60 100644
--- a/src/orca/scripts/toolkits/Gecko/braille_generator.py
+++ b/src/orca/scripts/toolkits/Gecko/braille_generator.py
@@ -1,6 +1,6 @@
 # Orca
 #
-# Copyright 2005-2008 Sun Microsystems Inc.
+# Copyright 2005-2009 Sun Microsystems Inc.
 #
 # This library is free software; you can redistribute it and/or
 # modify it under the terms of the GNU Library General Public
@@ -27,15 +27,15 @@ http://developer.mozilla.org/en/docs/Accessibility/ATSPI_Support
 __id__        = "$Id$"
 __version__   = "$Revision$"
 __date__      = "$Date$"
-__copyright__ = "Copyright (c) 2005-2008 Sun Microsystems Inc."
+__copyright__ = "Copyright (c) 2005-2009 Sun Microsystems Inc."
 __license__   = "LGPL"
 
 import pyatspi
 
-import orca.braille as braille
-import orca.braillegenerator as braillegenerator
-import orca.rolenames as rolenames
-import orca.settings as settings
+import orca.braille_generator as braille_generator
+import orca.orca_state as orca_state
+
+from orca.orca_i18n import _ # for gettext support
 
 ########################################################################
 #                                                                      #
@@ -43,485 +43,217 @@ import orca.settings as settings
 #                                                                      #
 ########################################################################
 
-class BrailleGenerator(braillegenerator.BrailleGenerator):
+class BrailleGenerator(braille_generator.BrailleGenerator):
     """Provides a braille generator specific to Gecko.
     """
 
     def __init__(self, script):
-        braillegenerator.BrailleGenerator.__init__(self, script)
-        self.brailleGenerators[pyatspi.ROLE_AUTOCOMPLETE] = \
-             self._getBrailleRegionsForAutocomplete
-        self.brailleGenerators[pyatspi.ROLE_ENTRY]        = \
-             self._getBrailleRegionsForText
-        self.brailleGenerators[pyatspi.ROLE_LINK]         = \
-             self._getBrailleRegionsForLink
-
-    def _getTextForRole(self, obj, role=None):
-        if settings.brailleVerbosityLevel == settings.VERBOSITY_LEVEL_VERBOSE \
-           and not obj.getRole() in [pyatspi.ROLE_SECTION,
-                                     pyatspi.ROLE_FORM,
-                                     pyatspi.ROLE_UNKNOWN]:
-            return rolenames.getBrailleForRoleName(obj, role)
-        else:
-            return None
-
-    def _getBrailleRegionsForAutocomplete(self, obj):
-        """Gets the braille for an autocomplete box.  We let the
-        handlers for the children do the rest.
+        braille_generator.BrailleGenerator.__init__(self, script)
 
-        Arguments:
-        - obj: an Accessible
-
-        Returns a list where the first element is a list of Regions to
-        display and the second element is the Region which should get
-        focus.
+    def _generateInDocumentContent(self, obj, **args):
+        """Returns True if this object is in HTML document content.
         """
+        return self._script.inDocumentContent(obj)
 
-        self._debugGenerator("Gecko._getBrailleRegionsForAutocomplete", obj)
-
-        # [[[TODO: WDW - we're doing very little here.  The goal for
-        # autocomplete boxes at the moment is that their children (e.g.,
-        # a text area, a menu, etc., do all the interactive work and
-        # the autocomplete acts as more of a container.]]]
-        #
-        regions = []
-        if settings.brailleVerbosityLevel == settings.VERBOSITY_LEVEL_VERBOSE:
-            regions.append(braille.Region(
-                rolenames.getBrailleForRoleName(obj)))
-        else:
-            regions.append(braille.Region(""))
-
-        return (regions, regions[0])
-
-    def _getBrailleRegionsForCheckBox(self, obj):
-        """Get the braille for a check box.  If the check box already had
-        focus, then only the state is displayed.
-
-        Arguments:
-        - obj: the check box
-
-        Returns a list where the first element is a list of Regions to display
-        and the second element is the Region which should get focus.
+    def _generateImageLink(self, obj, **args):
+        """Returns the link (if any) for this image.
         """
-
-        self._debugGenerator("Gecko._getBrailleRegionsForCheckBox", obj)
-
-        # Treat ARIA widgets like default.py widgets
-        #
-        if self._script.isAriaWidget(obj):
-            return braillegenerator.BrailleGenerator.\
-                       _getBrailleRegionsForCheckBox(self, obj)
-        
-        # In document content (I'm not sure about XUL widgets yet), a
-        # checkbox is its own little beast with no text.  So...  if it
-        # is in document content and has a label, we're likely to be
-        # displaying that label already.  If it doesn't have a label,
-        # though, we'll display its name.
-        #
-        text = ""
-        if not self._script.inDocumentContent():
-            text = self._script.appendString(
-                text, self._script.getDisplayedLabel(obj))
-            text = self._script.appendString(
-                text, self._script.getDisplayedText(obj))
-        else:
-            isLabelled = False
-            relationSet = obj.getRelationSet()
-            if relationSet:
-                for relation in relationSet:
-                    if relation.getRelationType() \
-                        == pyatspi.RELATION_LABELLED_BY:
-                        isLabelled = True
-                        break
-            if not isLabelled and obj.name and len(obj.name):
-                text = self._script.appendString(text, obj.name)
-
-        text = self._script.appendString(text, self._getTextForRole(obj))
-
-        # get the Braille indicator
-        state = obj.getState()
-        if state.contains(pyatspi.STATE_INDETERMINATE):
-            indicatorIndex = 2
-        elif state.contains(pyatspi.STATE_CHECKED):
-            indicatorIndex = 1
+        imageLink = None
+        role = args.get('role', obj.getRole())
+        if role == pyatspi.ROLE_IMAGE:
+            imageLink = self._script.getAncestor(obj,
+                                                 [pyatspi.ROLE_LINK],
+                                                 [pyatspi.ROLE_DOCUMENT_FRAME])
+        return imageLink
+
+    def _generateRoleName(self, obj, **args):
+        """Prevents some roles from being spoken."""
+        result = []
+        role = args.get('role', obj.getRole())
+        if not obj.getRole() in [pyatspi.ROLE_SECTION,
+                                 pyatspi.ROLE_FORM,
+                                 pyatspi.ROLE_UNKNOWN]:
+            result.extend(braille_generator.BrailleGenerator._generateRoleName(
+                self, obj, **args))
+        return result
+
+    def _generateName(self, obj, **args):
+        result = []
+        role = args.get('role', obj.getRole())
+        if role == pyatspi.ROLE_COMBO_BOX:
+            # With Gecko, a combo box has a menu as a child.  The text being
+            # displayed for the combo box can be obtained via the selected
+            # menu item.
+            #
+            menu = None
+            for child in obj:
+                if child.getRole() == pyatspi.ROLE_MENU:
+                    menu = child
+                    break
+            if menu:
+                child = None
+                try:
+                    # This should work...
+                    #
+                    child = menu.querySelection().getSelectedChild(0)
+                    if not child:
+                        # It's probably a Gtk combo box.
+                        #
+                        result = braille_generator.BrailleGenerator.\
+                            _generateDisplayedText(self, obj, **args)
+                except:
+                    # But just in case, we'll fall back on this.
+                    # [[[TODO - JD: Will we ever have a case where the first
+                    # fails, but this will succeed???]]]
+                    #
+                    for item in menu:
+                        if item.getState().contains(pyatspi.STATE_SELECTED):
+                            child = item
+                            break
+                if child and child.name:
+                    result.append(child.name)
         else:
-            indicatorIndex = 0
-
-        regions = []
-
-        componentRegion = braille.Component(
-            obj, text,
-            indicator=settings.brailleCheckBoxIndicators[indicatorIndex])
-        regions.append(componentRegion)
-
-        return [regions, componentRegion]
-
-    def _getBrailleRegionsForRadioButton(self, obj):
-        """Get the braille for a radio button.  If the radio button already
-        had focus, then only the state is displayed.
+            result.extend(braille_generator.BrailleGenerator._generateName(
+                              self, obj, **args))
+        if not result and role == pyatspi.ROLE_LIST_ITEM:
+            result.append(self._script.expandEOCs(obj))
+
+        link = None
+        if role == pyatspi.ROLE_LINK:
+            link = obj
+        elif role == pyatspi.ROLE_IMAGE and not result:
+            link = self._generateImageLink(obj, **args)
+        if link and (not result or len(result[0].strip()) == 0):
+            # If there's no text for the link, expose part of the
+            # URI to the user.
+            #
+            basename = self._script.getLinkBasename(link)
+            if basename:
+                result.append(basename)
 
-        Arguments:
-        - obj: the radio button
+        return result
 
-        Returns a list where the first element is a list of Regions to display
-        and the second element is the Region which should get focus.
+    def _generateDescription(self, obj, **args):
+        """Returns an array of strings (and possibly voice and audio
+        specifications) that represent the description of the object,
+        if that description is different from that of the name and
+        label.
         """
-
-        self._debugGenerator("Gecko._getBrailleRegionsForRadioButton", obj)
-
-        # Treat ARIA widgets like default.py widgets
-        #
-        if self._script.isAriaWidget(obj):
-            return braillegenerator.BrailleGenerator.\
-                       _getBrailleRegionsForRadioButton(self, obj)
-        
-        # In document content (I'm not sure about XUL widgets yet), a
-        # radio button is its own little beast with no text.  So...  if it
-        # is in document content and has a label, we're likely to be
-        # displaying that label already.  If it doesn't have a label,
-        # though, we'll display its name.
-        #
-        text = ""
-        if not self._script.inDocumentContent():
-            text = self._script.appendString(
-                text, self._script.getDisplayedLabel(obj))
-            text = self._script.appendString(
-                text, self._script.getDisplayedText(obj))
+        if args.get('role', obj.getRole()) == pyatspi.ROLE_LINK \
+           and obj.parent.getRole() == pyatspi.ROLE_IMAGE:
+            result = self._generateName(obj, **args)
+            # Translators: The following string is spoken to let the user
+            # know that he/she is on a link within an image map. An image
+            # map is an image/graphic which has been divided into regions.
+            # Each region can be clicked on and has an associated link.
+            # Please see http://en.wikipedia.org/wiki/Imagemap for more
+            # information and examples.
+            #
+            result.append(_("image map link"))
         else:
-            isLabelled = False
-            relationSet = obj.getRelationSet()
-            if relationSet:
-                for relation in relationSet:
-                    if relation.getRelationType() \
-                        == pyatspi.RELATION_LABELLED_BY:
-                        isLabelled = True
-                        break
-
-            if not isLabelled and obj.name and len(obj.name):
-                text = self._script.appendString(text, obj.name)
-
-        text = self._script.appendString(text, self._getTextForRole(obj))
-
-        indicatorIndex = int(obj.getState().contains(pyatspi.STATE_CHECKED))
-
-        regions = []
-        componentRegion = braille.Component(
-            obj, text,
-            indicator=settings.brailleRadioButtonIndicators[indicatorIndex])
-        regions.append(componentRegion)
-
-        return [regions, componentRegion]
-
-    def _getBrailleRegionsForText(self, obj):
-        """Gets text to be displayed for the entry of an autocomplete box.
-
-        Arguments:
-        - obj: an Accessible
-
-        Returns a list where the first element is a list of Regions to
-        display and the second element is the Region which should get
-        focus.
-        """
-
-        self._debugGenerator("Gecko._getBrailleRegionsForText", obj)
-
-        # Treat ARIA widgets like default.py widgets
+            result = braille_generator.BrailleGenerator.\
+                           _generateDescription(self, obj, **args)
+        return result
+
+    def _generateLabel(self, obj, **args):
+        result = braille_generator.BrailleGenerator._generateLabel(self,
+                                                                   obj,
+                                                                   **args)
+        role = args.get('role', obj.getRole())
+        # We'll attempt to guess the label under some circumstances.
         #
-        if self._script.isAriaWidget(obj):
-            return braillegenerator.BrailleGenerator.\
-                       _getBrailleRegionsForText(self, obj)
-        
-        parent = obj.parent
-        if parent.getRole() != pyatspi.ROLE_AUTOCOMPLETE:
-            return braillegenerator.BrailleGenerator._getBrailleRegionsForText(
-                self, obj)
-
-        regions = []
-
-        # This is the main difference between this class and the default
-        # class - we'll give this thing a name here, and we'll make it
-        # be the name of the autocomplete.
+        # [[[TODO: WDW - ROLE_ENTRY is noticeably absent from here.  If
+        # we include it here, the label_guess_bug_546815.py tests will
+        # end up showing the label twice.  So, I've pulled the ROLE_ENTRY
+        # out of here.  The effect of that is that we go back to the old
+        # way where the entry will appear on the same line as the text.
+        # I think there's a bug lurking there, though, in that the EOC for
+        # the entry seems to still exist on the braille line.  This was
+        # in the old (pre-refactor) code, too]]]
         #
-        label = self._script.getDisplayedLabel(parent)
-        if not label or not len(label):
-            label = parent.name
-
-        textRegion = braille.Text(obj, label, settings.brailleEOLIndicator)
-        regions.append(textRegion)
-
-        if settings.presentReadOnlyText \
-           and self._script.isReadOnlyTextArea(obj):
-            regions.append(braille.Region(" " \
-                                          + settings.brailleReadOnlyString))
-
-        return [regions, textRegion]
-
-    def _getBrailleRegionsForComboBox(self, obj):
-        """Get the braille for a combo box.  If the combo box already has
-        focus, then only the selection is displayed.
-
-        Arguments:
-        - obj: the combo box
-
-        Returns a list where the first element is a list of Regions to display
-        and the second element is the Region which should get focus.
-        """
-
-        self._debugGenerator("Gecko._getBrailleRegionsForComboBox", obj)
-
-        # Treat ARIA widgets like default.py widgets
+        # [[[TODO: WDW - ROLE_COMBO_BOX, ROLE_PASSWORD, ROLE_CHECK_BOX
+        # and ROLE_RADIO_BUTTON are absent for reasons similar to
+        # ROLE_ENTRY.]]]
         #
-        if self._script.isAriaWidget(obj):
-            return braillegenerator.BrailleGenerator.\
-                     _getBrailleRegionsForComboBox(self, obj)
-        
-        regions = []
-
-        label = self._script.getDisplayedLabel(obj)
-        if not label and not self._script.inDocumentContent():
-            label = obj.name
-
-        focusedRegionIndex = 0
-        if label and len(label):
-            regions.append(braille.Region(label + " "))
-            focusedRegionIndex = 1
-
-        # With Gecko, a combo box has a menu as a child.  The text being
-        # displayed for the combo box can be obtained via the selected
-        # menu item.
-        #
-        menu = None
-        for child in obj:
-            if child.getRole() == pyatspi.ROLE_MENU:
-                menu = child
-                break
-        if menu:
-            child = None
-            try:
-                # This should work...
-                #
-                child = menu.querySelection().getSelectedChild(0)
-                if not child:
-                    # It's probably a Gtk combo box.
-                    #
-                    return braillegenerator.BrailleGenerator.\
-                        _getBrailleRegionsForComboBox(self, obj)
-            except:
-                # But just in case, we'll fall back on this.
-                # [[[TODO - JD: Will we ever have a case where the first
-                # fails, but this will succeed???]]]
-                #
-                for item in menu:
-                    if item.getState().contains(pyatspi.STATE_SELECTED):
-                        child = item
-                        break
-            if child:
-                regions.append(braille.Region(child.name))
-
-        if settings.brailleVerbosityLevel == settings.VERBOSITY_LEVEL_VERBOSE:
-            regions.append(braille.Region(
-                " " + rolenames.getBrailleForRoleName(obj)))
-
-        # Things may not have gone as expected above, so we'll do some
-        # defensive programming to make sure we don't get an index out
-        # of bounds.
-        #
-        if focusedRegionIndex >= len(regions):
-            focusedRegionIndex = 0
-
-        if obj.getState().contains(pyatspi.STATE_FOCUSED):
-            focusedRegion = regions[focusedRegionIndex]
-        else:
-            focusedRegion = None
-
-        # [[[TODO: WDW - perhaps if a text area was created, we should
-        # give focus to it.]]]
+        if not len(result) \
+           and role in [pyatspi.ROLE_LIST,
+                        pyatspi.ROLE_PARAGRAPH,
+                        pyatspi.ROLE_TEXT] \
+           and self._script.inDocumentContent(obj) \
+           and not self._script.isAriaWidget(obj):
+            label = self._script.guessTheLabel(obj)
+            if label:
+                result.append(label)
+
+        # XUL combo boxes don't always have a label for/by
+        # relationship.  But, they will make their names be
+        # the string of the thing labelling them.
         #
-        return [regions, focusedRegion]
-
-    def _getBrailleRegionsForMenuItem(self, obj):
-        """Get the braille for a menu item.
-
-        Arguments:
-        - obj: the menu item
-
-        Returns a list where the first element is a list of Regions to display
-        and the second element is the Region which should get focus.
-        """
-
-        self._debugGenerator("Gecko._getBrailleRegionsForMenuItem", obj)
+        if not len(result) \
+           and role == pyatspi.ROLE_COMBO_BOX \
+           and not self._script.inDocumentContent(obj):
+            result.append(obj.name)
 
-        # Treat ARIA widgets like default.py widgets
+        # If this is an autocomplete, and we'll make the label be the
+        # name of the autocomplete.
         #
-        if self._script.isAriaWidget(obj):
-            return braillegenerator.BrailleGenerator.\
-                     _getBrailleRegionsForMenuItem(self, obj)
-        
-        if not self._script.inDocumentContent():
-            return braillegenerator.BrailleGenerator.\
-                       _getBrailleRegionsForMenuItem(self, obj)
-
-        regions = []
-
-        # Displaying "menu item" for a combo box can confuse users. Therefore,
-        # display the combo box role instead.  Also, only do it if the menu
-        # item is not focused (if the menu item is focused, it means we're
-        # navigating in the combo box).
-        #
-        label = self._script.getDisplayedLabel(obj)
-        focusedRegionIndex = 0
-        if label and len(label):
-            regions.append(braille.Region(label + " "))
-            focusedRegionIndex = 1
-        regions.append(braille.Region(obj.name))
-
-        comboBox = \
-                 self._script.getAncestor(obj,
-                                          [pyatspi.ROLE_COMBO_BOX],
-                                          [pyatspi.ROLE_DOCUMENT_FRAME])
-        if comboBox \
-           and not obj.getState().contains(pyatspi.STATE_FOCUSED) \
-           and (settings.brailleVerbosityLevel == \
-                settings.VERBOSITY_LEVEL_VERBOSE):
-            regions.append(braille.Region(
-                " " + rolenames.getBrailleForRoleName(comboBox)))
-
-        return [regions, regions[focusedRegionIndex]]
-
-    def _getBrailleRegionsForList(self, obj):
-        """Get the braille for a list in a form.  If the list already has
-        focus, then only the selection is displayed.
-
-        Arguments:
-        - obj: the list
-
-        Returns a list where the first element is a list of Regions to display
-        and the second element is the Region which should get focus.
-        """
-
-        self._debugGenerator("Gecko._getBrailleRegionsForList", obj)
-
-        # Treat ARIA widgets like default.py widgets
-        #
-        if self._script.isAriaWidget(obj):
-            return braillegenerator.BrailleGenerator.\
-                       _getBrailleRegionsForList(self, obj)
-        
-        if not obj.getState().contains(pyatspi.STATE_FOCUSABLE):
-            return braillegenerator.BrailleGenerator.\
-                       _getBrailleRegionsForList(self, obj)
-
-        regions = []
-        focusedRegionIndex = 0
-
-        if obj.getState().contains(pyatspi.STATE_FOCUSED):
-            label = self._script.getDisplayedLabel(obj)
-            if not label:
-                label = obj.name
-
-            if label and len(label):
-                regions.append(braille.Region(label + " "))
-                focusedRegionIndex = 1
-
+        if not len(result):
+            parent = obj.parent
+            if parent and parent.getRole() == pyatspi.ROLE_AUTOCOMPLETE:
+                label = self._script.getDisplayedLabel(parent)
+                if not label or not len(label):
+                    label = parent.name
+                result.append(label)
+
+        return result
+
+    def _generateExpandedEOCs(self, obj, **args):
+        """Returns the expanded embedded object characters for an object."""
+        result = []
+        text = self._script.expandEOCs(obj)
+        if text:
+            result.append(text)
+        return result
+
+    def _generateFocusedItem(self, obj, **args):
+        result = []
+        role = args.get('role', obj.getRole())
+        if role == pyatspi.ROLE_LIST:
             item = None
             selection = obj.querySelection()
             for i in xrange(obj.childCount):
                 if selection.isChildSelected(i):
                     item = obj[i]
                     break
-            if not item:
-                item = obj[0]
-            regions.append(braille.Region(item.name + " "))
-        elif obj.getState().contains(pyatspi.STATE_FOCUSABLE):
-            focusedRegionIndex = -1
-
-        if settings.brailleVerbosityLevel == settings.VERBOSITY_LEVEL_VERBOSE:
-            regions.append(braille.Region(
-                rolenames.getBrailleForRoleName(obj)))
-
-        if focusedRegionIndex > -1:
-            focusedRegion = regions[focusedRegionIndex]
-        else:
-            focusedRegion = None
-
-        return [regions, focusedRegion]
-
-    def _getBrailleRegionsForImage(self, obj):
-        """Get the braille regions for an image.
-
-        Arguments:
-        - obj: an Accessible
-
-        Returns a list where the first element is a list of Regions to
-        display and the second element is the Region which should get
-        focus.
-        """
-
-        self._debugGenerator("Gecko._getBrailleRegionsForImage", obj)
-
-        # Treat ARIA widgets like default.py widgets
+            item = item or obj[0]
+            if item and (item != orca_state.locusOfFocus):
+                name = self._generateName(item, **args)
+                if name and name != self._generateLabel(obj, **args):
+                    result.extend(name)
+        return result
+
+    def generateBraille(self, obj, **args):
+        result = []
+        # ARIA widgets get treated like regular default widgets.
         #
-        if self._script.isAriaWidget(obj):
-            return braillegenerator.BrailleGenerator.\
-                       _getBrailleRegionsForImage(self, obj)
-        
-        text = ""
-        text = self._script.appendString(text, 
-                                         self._script.getDisplayedLabel(obj))
-        text = self._script.appendString(text,
-                                         self._script.getDisplayedText(obj))
-        link = self._script.getAncestor(obj, 
-                                        [pyatspi.ROLE_LINK],
-                                        [pyatspi.ROLE_DOCUMENT_FRAME])
-        if link:
-            if len(text) == 0:
-                # If there's no text for the link, expose part of the
-                # link to the user if the image is in a link.
-                #
-                basename = self._script.getLinkBasename(link)
-                if basename:
-                    text = basename
-
-        text = self._script.appendString(text,
-                                         self._script.getTextForValue(obj))
-        text = self._script.appendString(text, self._getTextForRole(obj))
-
-        regions = []
-        if link:
-            region = braille.Link(obj, text)
-        else:
-            region = braille.Component(obj, text)
-        regions.append(region)
-
-        return [regions, region]
-
-    def _getBrailleRegionsForLink(self, obj):
-        """Gets text to be displayed for a link.
-
-        Arguments:
-        - obj: an Accessible
-
-        Returns a list where the first element is a list of Regions to
-        display and the second element is the Region which should get
-        focus.
-        """
-
-        self._debugGenerator("Gecko._getBrailleRegionsForLink", obj)
-
-        text, caretOffset, startOffset = self._script.getTextLineAtCaret(obj)
-        if not len(text):
-            text = self._script.getDisplayedText(obj)
-
-        # If there's no text for the link, expose part of the
-        # URI to the user.
+        args['includeContext'] = not self._script.inDocumentContent(obj)
+        args['useDefaultFormatting'] = \
+            self._script.isAriaWidget(obj) \
+            or ((obj.getRole() == pyatspi.ROLE_LIST) \
+                and (not obj.getState().contains(pyatspi.STATE_FOCUSABLE)))
+        # Treat menu items in collapsed combo boxes as if the combo box
+        # had focus. This will make things more consistent with how we
+        # present combo boxes outside of Gecko.
         #
-        if len(text) == 0:
-            basename = self._script.getLinkBasename(obj)
-            if basename:
-                text = basename
-
-        regions = []
-        linkRegion = braille.Link(obj, text, caretOffset - startOffset)
-        regions.append(linkRegion)
-
-        return [regions, linkRegion]
+        if obj.getRole() == pyatspi.ROLE_MENU_ITEM:
+            comboBox = self._script.getAncestor(obj,
+                                                [pyatspi.ROLE_COMBO_BOX],
+                                                [pyatspi.ROLE_FRAME])
+            if comboBox \
+               and not comboBox.getState().contains(pyatspi.STATE_EXPANDED):
+                obj = comboBox
+        result.extend(braille_generator.BrailleGenerator.\
+                          generateBraille(self, obj, **args))
+        del args['includeContext']
+        del args['useDefaultFormatting']
+        return result
diff --git a/src/orca/scripts/toolkits/Gecko/formatting.py b/src/orca/scripts/toolkits/Gecko/formatting.py
index 9232c15..a043bc4 100644
--- a/src/orca/scripts/toolkits/Gecko/formatting.py
+++ b/src/orca/scripts/toolkits/Gecko/formatting.py
@@ -33,6 +33,13 @@ import orca.formatting
 
 # pylint: disable-msg=C0301
 
+########################################################################
+#                                                                      #
+# Formatting for things that are not ARIA widgets.  For things that    #
+# are ARIA widgets, we use the default formatting (see the             #
+# getFormat method).                                                   #
+#                                                                      #
+########################################################################
 formatting = {
     'speech': {
         'suffix': {
@@ -69,6 +76,63 @@ formatting = {
         pyatspi.ROLE_TABLE: {
             'unfocused': '[]'
             },
+    },
+    'braille': {
+        # [[[TODO: WDW - we're doing very little here.  The goal for
+        # autocomplete boxes at the moment is that their children (e.g.,
+        # a text area, a menu, etc., do all the interactive work and
+        # the autocomplete acts as more of a container.]]]
+        #
+        pyatspi.ROLE_AUTOCOMPLETE: {
+            'unfocused': '[Component(obj, asString(roleName))]'
+        },
+        pyatspi.ROLE_CHECK_BOX: {
+            'unfocused': '[Component(obj,\
+                                     asString((not inDocumentContent\
+                                               and (label + displayedText)\
+                                               or (label and [""] or name))\
+                                              + roleName),\
+                                     indicator=asString(checkedState))]'
+        },
+        pyatspi.ROLE_COMBO_BOX: {
+            'unfocused': '[Component(obj,\
+                                     asString(label + name + roleName),\
+                                     asString(label) and (len(asString(label)) + 1) or 0)]'
+            },
+        pyatspi.ROLE_IMAGE: {
+            'unfocused':  '(imageLink\
+                           and [Link(obj, (asString(label + displayedText)\
+                                           or asString(name))\
+                                          + " " + asString(value + roleName))]\
+                           or [Component(obj,\
+                                        asString(label + displayedText + value + roleName))])'
+        },
+        # [[[TODO: WDW - yikes!  We need more parameters to send to
+        # the Link constructor.]]]
+        #
+        pyatspi.ROLE_LINK: {
+            'unfocused': '[Link(obj, asString(currentLineText)\
+                                     or asString(displayedText)\
+                                     or asString(name))]',
+        },
+        pyatspi.ROLE_LIST: {
+            'unfocused': '[Component(obj,\
+                                     asString(label + focusedItem + roleName),\
+                                     asString(label) and (len(asString(label)) + 1) or 0)]'
+        },
+        # If we're in document content, we present the indicator followed
+        # immediately by the role, followed by the label/displayed text,
+        # etc. The label/displayed text is obtained as part of the line
+        # contents, therefore we do not want to include it here.
+        #
+        pyatspi.ROLE_RADIO_BUTTON: {
+            'unfocused': '[Component(obj,\
+                                     asString((not inDocumentContent\
+                                               and ((label + displayedText) or description)\
+                                               or [""])\
+                                             + roleName),\
+                                   indicator=asString(radioState))]'
+        }
     }
 }
 
@@ -87,7 +151,7 @@ class Formatting(orca.formatting.Formatting):
     def getFormat(self, **args):
         # ARIA widgets get treated like regular default widgets.
         #
-        if args.get('isAria', False):
+        if args.get('useDefaultFormatting', False):
             return self._defaultFormatting.getFormat(**args)
         else:
             return orca.formatting.Formatting.getFormat(self, **args)
diff --git a/src/orca/scripts/toolkits/Gecko/script.py b/src/orca/scripts/toolkits/Gecko/script.py
index d4d4501..9901a99 100644
--- a/src/orca/scripts/toolkits/Gecko/script.py
+++ b/src/orca/scripts/toolkits/Gecko/script.py
@@ -2266,7 +2266,7 @@ class Script(default.Script):
                            pyatspi.ROLE_PASSWORD_TEXT,
                            pyatspi.ROLE_LINK]:
                 [regions, fRegion] = \
-                          self.brailleGenerator.getBrailleRegions(obj)
+                          self.brailleGenerator.generateBraille(obj)
 
                 if isFocusedObj:
                     focusedRegion = fRegion
@@ -2690,15 +2690,22 @@ class Script(default.Script):
         """
         if not obj:
             obj = orca_state.locusOfFocus
-
+        try:
+            return self.generatorCache['inDocumentContent'][obj]
+        except:
+            if not self.generatorCache.has_key('inDocumentContent'):
+                self.generatorCache['inDocumentContent'] = {}
+        result = False
         while obj:
             role = obj.getRole()
             if role == pyatspi.ROLE_DOCUMENT_FRAME \
                     or role == pyatspi.ROLE_EMBEDDED:
-                return True
+                result = True
+                break
             else:
                 obj = obj.parent
-        return False
+        self.generatorCache['inDocumentContent'][obj] = result
+        return self.generatorCache['inDocumentContent'][obj]
 
     def getDocumentFrame(self):
         """Returns the document frame that holds the content being shown."""
@@ -2979,9 +2986,16 @@ class Script(default.Script):
         - obj: The accessible object of interest.  If None, the
         locusOfFocus is examined.
         """
+        try:
+            return self.generatorCache['isAria'][obj]
+        except:
+            if not self.generatorCache.has_key('isAria'):
+                self.generatorCache['isAria'] = {}
         obj = obj or orca_state.locusOfFocus
         attrs = self._getAttrDictionary(obj)
-        return ('xml-roles' in attrs and 'live' not in attrs)
+        self.generatorCache['isAria'][obj] = \
+            ('xml-roles' in attrs and 'live' not in attrs)
+        return self.generatorCache['isAria'][obj]
 
     def _getAttrDictionary(self, obj):
         if not obj:
@@ -5020,7 +5034,7 @@ class Script(default.Script):
             candidate, startOffset, endOffset, string = content
             if self.isSameObject(candidate, obj) \
                and (offset is None or (startOffset <= offset <= endOffset)):
-                return string, caretOffset, startOffset
+                return string.encode("UTF-8"), caretOffset, startOffset
 
         # If we're still here, obj presumably is not on this line. This
         # shouldn't happen, but if it does we'll let the default script
diff --git a/src/orca/scripts/toolkits/Gecko/speech_generator.py b/src/orca/scripts/toolkits/Gecko/speech_generator.py
index 6c0dd66..1344376 100644
--- a/src/orca/scripts/toolkits/Gecko/speech_generator.py
+++ b/src/orca/scripts/toolkits/Gecko/speech_generator.py
@@ -505,8 +505,8 @@ class SpeechGenerator(speech_generator.SpeechGenerator):
         # ARIA widgets get treated like regular default widgets.
         #
         else:
-            args['isAria'] = self._script.isAriaWidget(obj)
+            args['useDefaultFormatting'] = self._script.isAriaWidget(obj)
             result.extend(speech_generator.SpeechGenerator.\
                                            generateSpeech(self, obj, **args))
-            del args['isAria']
+            del args['useDefaultFormatting']
         return result
diff --git a/src/orca/scripts/toolkits/J2SE-access-bridge/Makefile.am b/src/orca/scripts/toolkits/J2SE-access-bridge/Makefile.am
index c2025fa..61cfcc3 100644
--- a/src/orca/scripts/toolkits/J2SE-access-bridge/Makefile.am
+++ b/src/orca/scripts/toolkits/J2SE-access-bridge/Makefile.am
@@ -2,7 +2,6 @@ orca_pathdir=$(pyexecdir)
 
 orca_python_PYTHON = \
 	__init__.py \
-	braillegenerator.py \
 	formatting.py \
 	script.py \
 	speech_generator.py
diff --git a/src/orca/scripts/toolkits/J2SE-access-bridge/__init__.py b/src/orca/scripts/toolkits/J2SE-access-bridge/__init__.py
index c9714a9..5707f93 100644
--- a/src/orca/scripts/toolkits/J2SE-access-bridge/__init__.py
+++ b/src/orca/scripts/toolkits/J2SE-access-bridge/__init__.py
@@ -1,3 +1,2 @@
 from script import Script
 from speech_generator import SpeechGenerator
-from braillegenerator import BrailleGenerator
diff --git a/src/orca/scripts/toolkits/J2SE-access-bridge/formatting.py b/src/orca/scripts/toolkits/J2SE-access-bridge/formatting.py
index f8c2095..419cc51 100644
--- a/src/orca/scripts/toolkits/J2SE-access-bridge/formatting.py
+++ b/src/orca/scripts/toolkits/J2SE-access-bridge/formatting.py
@@ -42,6 +42,11 @@ formatting = {
             'unfocused': '(displayedText or roleName) + expandableState',
             'focused': 'expandableState'
             },
+    },
+    'braille': {
+        pyatspi.ROLE_LABEL: {
+            'unfocused': '[Component(obj, asString(displayedText + expandableState))]'
+            },
     }
 }
 
diff --git a/src/orca/scripts/toolkits/J2SE-access-bridge/script.py b/src/orca/scripts/toolkits/J2SE-access-bridge/script.py
index dac1e30..fd627b6 100644
--- a/src/orca/scripts/toolkits/J2SE-access-bridge/script.py
+++ b/src/orca/scripts/toolkits/J2SE-access-bridge/script.py
@@ -31,7 +31,6 @@ import orca.orca as orca
 import orca.orca_state as orca_state
 import orca.keybindings as keybindings
 
-from braillegenerator import BrailleGenerator
 from speech_generator import SpeechGenerator
 from formatting import Formatting
 
@@ -51,13 +50,8 @@ class Script(default.Script):
         """
         default.Script.__init__(self, app)
 
-    def getBrailleGenerator(self):
-        """Returns the braille generator for this script.
-        """
-        return BrailleGenerator(self)
-
     def getSpeechGenerator(self):
-        """Returns the braille generator for this script.
+        """Returns the speech generator for this script.
         """
         return SpeechGenerator(self)
 
diff --git a/src/orca/settings.py b/src/orca/settings.py
index 38755f2..8048d82 100644
--- a/src/orca/settings.py
+++ b/src/orca/settings.py
@@ -1251,6 +1251,19 @@ speechExpansionIndicators = [_("collapsed"), _("expanded")]
 #
 speechMultiSelectString = _("multi-select")
 
+# Translators: this represents the depth of a node in a tree
+# view (i.e., how many ancestors a node has).  It is meant to be
+# spoken.
+#
+speechNodeLevelString = _("tree level %d")
+
+# Translators: this represents a list item in a document.
+# The nesting level is how 'deep' the item is (e.g., a
+# level of 2 represents a list item inside a list that's
+# inside another list). This is meant to be spoken.
+#
+speechNestingLevelString = _("Nesting level %d")
+
 # string to indicate end of printed line for braille displays:
 #
 disableBrailleEOL = False
@@ -1286,3 +1299,21 @@ brailleToggleButtonIndicators = ["& y", "&=y"]
 # children are not showing.
 #
 brailleExpansionIndicators = [_("collapsed"), _("expanded")]
+
+# Translators: this represents the depth of a node in a tree
+# view (i.e., how many ancestors a node has).  It is meant to
+# be presented on a braille display.
+#
+brailleNodeLevelString = _("TREE LEVEL %d")
+
+# Translators: this represents a list item in a document.
+# The nesting level is how 'deep' the item is (e.g., a
+# level of 2 represents a list item inside a list that's
+# inside another list).  It is meant to be presented on
+# the braille display.
+#
+brailleNestingLevelString = _("LEVEL %d")
+
+# String for delimiters between table cells
+#
+brailleTableCellDelimiter = " "
diff --git a/src/orca/speech_generator.py b/src/orca/speech_generator.py
index 318f6da..3ff75f2 100644
--- a/src/orca/speech_generator.py
+++ b/src/orca/speech_generator.py
@@ -89,40 +89,6 @@ class SpeechGenerator(generator.Generator):
     #                                                                   #
     #####################################################################
 
-    def _generateName(self, obj, **args):
-        """Returns an array of strings (and possibly voice and audio
-        specifications) that represent the name of the object.  If the
-        object is directly displaying any text, that text will be
-        treated as the name.  Otherwise, the accessible name of the
-        object will be used.  If there is no accessible name, then the
-        description of the object will be used.  This method will
-        return an empty array if nothing can be found.  [[[WDW - I
-        wonder if we should just have _generateName, _generateDescription,
-        _generateDisplayedText, etc., that don't do any fallback.  Then, we
-        can allow the formatting to do the fallback (e.g.,
-        'displayedText or name or description'). [[[JD to WDW - I needed
-        a _generateDescription for whereAmI. :-) See below.
-        """
-        result = []
-        name = self._script.getDisplayedText(obj)
-        if name:
-            result.append(name)
-        elif obj.description:
-            result.append(obj.description)
-        return result
-
-    def _generateDescription(self, obj, **args):
-        """Returns an array of strings (and possibly voice and audio
-        specifications) that represent the description of the object,
-        if that description is different from that of the name and
-        label.
-        """
-        result = []
-        label = self._script.getDisplayedLabel(obj)
-        if obj.description and not obj.description in [obj.name, label]:
-            result.append(obj.description)
-        return result
-
     def _generateTextRole(self, obj, **args):
         """A convenience method to prevent the pyatspi.ROLE_PARAGRAPH role
         from being spoken. In the case of a pyatspi.ROLE_PARAGRAPH
@@ -164,34 +130,6 @@ class SpeechGenerator(generator.Generator):
         """
         return self._generateRoleName(obj, **args)
 
-    def _generateLabelAndName(self, obj, **args):
-        """Returns the label and the name as an array of strings (and possibly
-        voice and audio specifications).  The name will only be
-        present if the name is different from the label.
-        """
-        result = []
-        label = self._generateLabel(obj, **args)
-        name = self._generateName(obj, **args)
-        result.extend(label)
-        if not len(label):
-            result.extend(name)
-        elif len(name) and name[0] != label[0]:
-            result.extend(name)
-        return result
-
-    def _generateLabelOrName(self, obj, **args):
-        """Returns the label as an array of strings (and possibly voice
-        specifications).  If the label cannot be found, the name will
-        be used instead.  If the name cannot be found, an empty array
-        will be returned.
-        """
-        result = []
-        result.extend(self._generateLabel(obj, **args))
-        if not result:
-            if obj.name and (len(obj.name)):
-                result.append(obj.name)
-        return result
-
     def _generateUnrelatedLabels(self, obj, **args):
         """Returns, as an array of strings (and possibly voice
         specifications), all the labels which are underneath the obj's
@@ -225,31 +163,6 @@ class SpeechGenerator(generator.Generator):
     #                                                                   #
     #####################################################################
 
-    def _generateCellCheckedState(self, obj, **args):
-        """Returns an array of strings (and possibly voice and audio
-        specifications) that represent the checked state of the
-        object.  This is typically for check boxes that are in a
-        table. An empty array will be returned if this is not a
-        checkable cell.
-        """
-        result = []
-        try:
-            action = obj.queryAction()
-        except NotImplementedError:
-            action = None
-        if action:
-            for i in range(0, action.nActions):
-                # Translators: this is the action name for
-                # the 'toggle' action. It must be the same
-                # string used in the *.po file for gail.
-                #
-                if action.getName(i) in ["toggle", _("toggle")]:
-                    oldRole = self._overrideRole(pyatspi.ROLE_CHECK_BOX,
-                                            args)
-                    result.extend(self.generateSpeech(obj, **args))
-                    self._restoreRole(oldRole, args)
-        return result
-
     def _generateMultiselectableState(self, obj, **args):
         """Returns an array of strings (and possibly voice and audio
         specifications) that represent the multiselectable state of
@@ -411,23 +324,6 @@ class SpeechGenerator(generator.Generator):
     #                                                                   #
     #####################################################################
 
-    def _generateImageDescription(self, obj, **args ):
-        """Returns an array of strings (and possibly voice and audio
-        specifications) that represent the description of the image on
-        the object, if it exists.  Otherwise, an empty array is
-        returned.
-        """
-        result = []
-        try:
-            image = obj.queryImage()
-        except NotImplementedError:
-            pass
-        else:
-            description = image.imageDescription
-            if description and len(description):
-                result.append(description)
-        return result
-
     def _generateImage(self, obj, **args):
         """Returns an array of strings (and possibly voice and audio
         specifications) that represent the image on the the object, if
@@ -440,7 +336,7 @@ class SpeechGenerator(generator.Generator):
             pass
         else:
             role = pyatspi.ROLE_IMAGE
-            result.extend(self.generateSpeech(obj, role=role))
+            result.extend(self.generate(obj, role=role))
         return result
 
     #####################################################################
@@ -449,49 +345,6 @@ class SpeechGenerator(generator.Generator):
     #                                                                   #
     #####################################################################
 
-    def _generateRowHeader(self, obj, **args):
-        """Returns an array of strings (and possibly voice and audio
-        specifications) that represent the row header for an object
-        that is in a table, if it exists.  Otherwise, an empty array
-        is returned.
-        """
-        result = []
-        try:
-            table = obj.parent.queryTable()
-        except:
-            pass
-        else:
-            index = self._script.getCellIndex(obj)
-            rowIndex = table.getRowAtIndex(index)
-            if rowIndex >= 0:
-                # Get the header information.  In Java Swing, the
-                # information is not exposed via the description
-                # but is instead a header object, so we fall back
-                # to that if it exists.
-                #
-                # [[[TODO: WDW - the more correct thing to do, I
-                # think, is to look at the row header object.
-                # We've been looking at the description for so
-                # long, though, that we'll give the description
-                # preference for now.]]]
-                #
-                desc = table.getRowDescription(rowIndex)
-                if not desc:
-                    header = table.getRowHeader(rowIndex)
-                    if header:
-                        desc = self._script.getDisplayedText(header)
-                if desc and len(desc):
-                    text = desc
-                    if settings.speechVerbosityLevel \
-                            == settings.VERBOSITY_LEVEL_VERBOSE \
-                       and not args.get('formatType', None) \
-                           in ['basicWhereAmI', 'detailedWhereAmI']:
-                        text += " " \
-                            + rolenames.rolenames[\
-                            pyatspi.ROLE_ROW_HEADER].speech
-                    result.append(text)
-        return result
-
     def _generateNewRowHeader(self, obj, **args):
         """Returns an array of strings (and possibly voice and audio
         specifications) that represent the row header for an object
@@ -538,49 +391,6 @@ class SpeechGenerator(generator.Generator):
                         result = self._generateRowHeader(obj, **args)
         return result
 
-    def _generateColumnHeader(self, obj, **args):
-        """Returns an array of strings (and possibly voice and audio
-        specifications) that represent the column header for an object
-        that is in a table, if it exists.  Otherwise, an empty array
-        is returned.
-        """
-        result = []
-        try:
-            table = obj.parent.queryTable()
-        except:
-            pass
-        else:
-            index = self._script.getCellIndex(obj)
-            columnIndex = table.getColumnAtIndex(index)
-            if columnIndex >= 0:
-                # Get the header information.  In Java Swing, the
-                # information is not exposed via the description
-                # but is instead a header object, so we fall back
-                # to that if it exists.
-                #
-                # [[[TODO: WDW - the more correct thing to do, I
-                # think, is to look at the row header object.
-                # We've been looking at the description for so
-                # long, though, that we'll give the description
-                # preference for now.]]]
-                #
-                desc = table.getColumnDescription(columnIndex)
-                if not desc:
-                    header = table.getColumnHeader(columnIndex)
-                    if header:
-                        desc = self._script.getDisplayedText(header)
-                if desc and len(desc):
-                    text = desc
-                    if settings.speechVerbosityLevel \
-                            == settings.VERBOSITY_LEVEL_VERBOSE \
-                       and not args.get('formatType', None) \
-                           in ['basicWhereAmI', 'detailedWhereAmI']:
-                        text += " " \
-                            + rolenames.rolenames[\
-                            pyatspi.ROLE_COLUMN_HEADER].speech
-                    result.append(text)
-        return result
-
     def _generateNewColumnHeader(self, obj, **args):
         """Returns an array of strings (and possibly voice and audio
         specifications) that represent the column header for an object
@@ -627,91 +437,6 @@ class SpeechGenerator(generator.Generator):
                         result = self._generateColumnHeader(obj, **args)
         return result
 
-    def _generateTableCell2ChildLabel(self, obj, **args):
-        """Returns an array of strings (and possibly voice and audio
-        specifications) for the label of a toggle in a table cell that
-        has a special 2 child pattern that we run into.  Otherwise, an
-        empty array is returned.
-        """
-        result = []
-
-        # If this table cell has 2 children and one of them has a
-        # 'toggle' action and the other does not, then present this
-        # as a checkbox where:
-        # 1) we get the checked state from the cell with the 'toggle' action
-        # 2) we get the label from the other cell.
-        # See Orca bug #376015 for more details.
-        #
-        if obj.childCount == 2:
-            cellOrder = []
-            hasToggle = [False, False]
-            for i, child in enumerate(obj):
-                try:
-                    action = child.queryAction()
-                except NotImplementedError:
-                    continue
-                else:
-                    for j in range(0, action.nActions):
-                        # Translators: this is the action name for
-                        # the 'toggle' action. It must be the same
-                        # string used in the *.po file for gail.
-                        #
-                        if action.getName(j) in ["toggle", _("toggle")]:
-                            hasToggle[i] = True
-                            break
-            if hasToggle[0] and not hasToggle[1]:
-                cellOrder = [ 1, 0 ]
-            elif not hasToggle[0] and hasToggle[1]:
-                cellOrder = [ 0, 1 ]
-            if cellOrder:
-                for i in cellOrder:
-                    if not hasToggle[i]:
-                        result.extend(self.generateSpeech(obj[i], **args))
-        return result
-
-    def _generateTableCell2ChildToggle(self, obj, **args):
-        """Returns an array of strings (and possinly voice and audio
-        specifications) for the toggle value of a toggle in a table
-        cell that has a special 2 child pattern that we run into.
-        Otherwise, an empty array is returned.
-        """
-        result = []
-
-        # If this table cell has 2 children and one of them has a
-        # 'toggle' action and the other does not, then present this
-        # as a checkbox where:
-        # 1) we get the checked state from the cell with the 'toggle' action
-        # 2) we get the label from the other cell.
-        # See Orca bug #376015 for more details.
-        #
-        if obj.childCount == 2:
-            cellOrder = []
-            hasToggle = [False, False]
-            for i, child in enumerate(obj):
-                try:
-                    action = child.queryAction()
-                except NotImplementedError:
-                    continue
-                else:
-                    for j in range(0, action.nActions):
-                        # Translators: this is the action name for
-                        # the 'toggle' action. It must be the same
-                        # string used in the *.po file for gail.
-                        #
-                        if action.getName(j) in ["toggle", _("toggle")]:
-                            hasToggle[i] = True
-                            break
-
-            if hasToggle[0] and not hasToggle[1]:
-                cellOrder = [ 1, 0 ]
-            elif not hasToggle[0] and hasToggle[1]:
-                cellOrder = [ 0, 1 ]
-            if cellOrder:
-                for i in cellOrder:
-                    if hasToggle[i]:
-                        result.extend(self.generateSpeech(obj[i], **args))
-        return result
-
     def _generateRealTableCell(self, obj, **args):
         """Orca has a feature to automatically read an entire row of a table
         as the user arrows up/down the roles.  This leads to complexity in
@@ -721,7 +446,7 @@ class SpeechGenerator(generator.Generator):
         """
         result = []
         oldRole = self._overrideRole('REAL_ROLE_TABLE_CELL', args)
-        result.extend(self.generateSpeech(obj, **args))
+        result.extend(self.generate(obj, **args))
         self._restoreRole(oldRole, args)
         if not result and settings.speakBlankLines \
            and not args.get('readingRow', False):
@@ -731,83 +456,6 @@ class SpeechGenerator(generator.Generator):
             result.append(_("blank"))
         return result
 
-    def _generateTableCellRow(self, obj, **args):
-        """Orca has a feature to automatically read an entire row of a table
-        as the user arrows up/down the roles.  This leads to complexity in
-        the code.  This method is used to return an array of strings
-        (and possibly voice and audio specifications) for an entire row
-        in a table if that's what the user has requested and if the row
-        has changed.  Otherwise, it will return an array for just the
-        current cell.
-        """
-        result = []
-
-        try:
-            parentTable = obj.parent.queryTable()
-        except NotImplementedError:
-            parentTable = None
-        isDetailedWhereAmI = args.get('formatType', None) == 'detailedWhereAmI'
-        if (settings.readTableCellRow or isDetailedWhereAmI) and parentTable \
-           and (not self._script.isLayoutOnly(obj.parent)):
-            parent = obj.parent
-            index = self._script.getCellIndex(obj)
-            row = parentTable.getRowAtIndex(index)
-            column = parentTable.getColumnAtIndex(index)
-
-            # This is an indication of whether we should speak all the
-            # table cells (the user has moved focus up or down a row),
-            # or just the current one (focus has moved left or right in
-            # the same row).
-            #
-            speakAll = True
-            if isDetailedWhereAmI:
-                if parentTable.nColumns <= 1:
-                    return result
-            elif "lastRow" in self._script.pointOfReference \
-               and "lastColumn" in self._script.pointOfReference:
-                pointOfReference = self._script.pointOfReference
-                speakAll = \
-                    (pointOfReference["lastRow"] != row) \
-                     or ((row == 0 or row == parentTable.nRows-1) \
-                     and pointOfReference["lastColumn"] == column)
-            if speakAll:
-                args['readingRow'] = True
-                for i in range(0, parentTable.nColumns):
-                    cell = parentTable.getAccessibleAt(row, i)
-                    if not cell:
-                        continue
-                    state = cell.getState()
-                    showing = state.contains(pyatspi.STATE_SHOWING)
-                    if showing:
-                        # If this table cell has a "toggle" action, and
-                        # doesn't have any label associated with it then
-                        # also speak the table column header.
-                        # See Orca bug #455230 for more details.
-                        #
-                        label = self._script.getDisplayedText(
-                            self._script.getRealActiveDescendant(cell))
-                        try:
-                            action = cell.queryAction()
-                        except NotImplementedError:
-                            action = None
-                        if action and (label == None or len(label) == 0):
-                            for j in range(0, action.nActions):
-                                # Translators: this is the action name for
-                                # the 'toggle' action. It must be the same
-                                # string used in the *.po file for gail.
-                                #
-                                if action.getName(j) in ["toggle",
-                                                         _("toggle")]:
-                                    accHeader = \
-                                        parentTable.getColumnHeader(i)
-                                    result.append(accHeader.name)
-                        result.extend(self._generateRealTableCell(cell, **args))
-            else:
-                result.extend(self._generateRealTableCell(obj, **args))
-        else:
-            result.extend(self._generateRealTableCell(obj, **args))
-        return result
-
     def _generateUnselectedCell(self, obj, **args):
         """Returns an array of strings (and possibly voice and audio
         specifications) if this is an icon within an layered pane or a
@@ -1180,15 +828,6 @@ class SpeechGenerator(generator.Generator):
 
         return [newLine]
 
-    def _generateCurrentLineText(self, obj, **args ):
-        """Returns an array of strings (and possibly voice and audio
-        specifications) that represents the current line of text, if
-        this is a text object.  [[[WDW - consider returning an empty
-        array if this is not a text object.]]]
-        """
-        [text, caretOffset, startOffset] = self._script.getTextLineAtCaret(obj)
-        return [text]
-
     def _generateAnyTextSelection(self, obj, **args):
         """Returns an array of strings (and possibly voice and audio
         specifications) that says if any of the text for the entire
@@ -1237,22 +876,6 @@ class SpeechGenerator(generator.Generator):
     #                                                                   #
     #####################################################################
 
-    def _generateNodeLevel(self, obj, **args):
-        """Returns an array of strings (and possibly voice and audio
-        specifications) that represents the tree node level of the
-        object, or an empty array if the object is not a tree
-        node. [[[WDW - I wonder if this string should be moved to
-        settings.py.]]]
-        """
-        result = []
-        level = self._script.getNodeLevel(obj)
-        if level >= 0:
-            # Translators: this represents the depth of a node in a tree
-            # view (i.e., how many ancestors a node has).
-            #
-            result.append(_("tree level %d") % (level + 1))
-        return result
-
     def _generateNewNodeLevel(self, obj, **args):
         """Returns an array of strings (and possibly voice and audio
         specifications) that represents the tree node level of the
@@ -1260,22 +883,13 @@ class SpeechGenerator(generator.Generator):
         if the node level is not different from the 'priorObj'
         'priorObj' attribute of the args dictionary.  The 'priorObj'
         is typically set by Orca to be the previous object with
-        focus.  [[[WDW - I wonder if this string should be moved to
-        settings.py.]]]
+        focus.
         """
-
-        # [[[TODO: WDW - hate duplicating code from _generateNodeLevel,
-        # but don't want to call it because it will make the same
-        # self._script.getNodeLevel call again.]]]
-        #
         result = []
         oldLevel = self._script.getNodeLevel(args.get('priorObj', None))
         newLevel = self._script.getNodeLevel(obj)
         if (oldLevel != newLevel) and (newLevel >= 0):
-            # Translators: this represents the depth of a node in a tree
-            # view (i.e., how many ancestors a node has).
-            #
-            result.append(_("tree level %d") % (newLevel + 1))
+            result.extend(self._generateNodeLevel(obj, **args))
         return result
 
     #####################################################################
@@ -1312,36 +926,6 @@ class SpeechGenerator(generator.Generator):
     #                                                                   #
     #####################################################################
 
-    def _generateRadioButtonGroup(self, obj, **args):
-        """Returns an array of strings (and possibly voice and audio
-        specifications) that represents the radio button group label
-        for the object, or an empty array if the object has no such
-        label.
-        """
-        result = []
-        if obj.getRole() == pyatspi.ROLE_RADIO_BUTTON:
-            radioGroupLabel = None
-            relations = obj.getRelationSet()
-            for relation in relations:
-                if (not radioGroupLabel) \
-                    and (relation.getRelationType() \
-                         == pyatspi.RELATION_LABELLED_BY):
-                    radioGroupLabel = relation.getTarget(0)
-                    break
-            if radioGroupLabel:
-                result.append(self._script.getDisplayedText(radioGroupLabel))
-            else:
-                parent = obj.parent
-                while parent and (parent.parent != parent):
-                    if parent.getRole() in [pyatspi.ROLE_PANEL,
-                                            pyatspi.ROLE_FILLER]:
-                        label = self._generateLabelAndName(parent)
-                        if label:
-                            result.extend(label)
-                            break
-                    parent = parent.parent
-        return result
-
     def _generateNewRadioButtonGroup(self, obj, **args):
         """Returns an array of strings (and possibly voice and audio
         specifications) that represents the radio button group label
@@ -1378,20 +962,6 @@ class SpeechGenerator(generator.Generator):
                 result.append(self._script.getDisplayedText(radioGroupLabel))
         return result
 
-    def _generateRealActiveDescendantDisplayedText(self, obj, **args ):
-        """Objects, such as tables and trees, can represent individual cells
-        via a complicated nested hierarchy.  This method returns an
-        array of strings (and possibly voice and audio specifications)
-        that represents the text actually being painted in the cell,
-        if it can be found.  Otherwise, an empty array is returned.
-        """
-        result = []
-        text = self._script.getDisplayedText(
-          self._script.getRealActiveDescendant(obj))
-        if text:
-            result = [text]
-        return result
-
     def _generateNumberOfChildren(self, obj, **args):
         """Returns an array of strings (and possibly voice and audio
         specifications) that represents the number of children the
@@ -1727,26 +1297,6 @@ class SpeechGenerator(generator.Generator):
 
         return result
 
-    def _generateNestingLevel(self, obj, **args):
-        """Returns an array of strings (and possibly voice and audio
-        specifications) that represent the nesting level of an object
-        in a list.
-        """
-        result = []
-        nestingLevel = 0
-        parent = obj.parent
-        while parent.parent.getRole() == pyatspi.ROLE_LIST:
-            nestingLevel += 1
-            parent = parent.parent
-        if nestingLevel:
-            # Translators: this represents a list item in a document.
-            # The nesting level is how 'deep' the item is (e.g., a
-            # level of 2 represents a list item inside a list that's
-            # inside another list).
-            #
-            result.append(_("Nesting level %d") % nestingLevel)
-        return result
-
     def _generateDefaultButton(self, obj, **args):
         """Returns an array of strings (and possibly voice and audio
         specifications) that represent the default button in a dialog.
diff --git a/test/harness/utils.py b/test/harness/utils.py
index 20cde2e..e7a1987 100644
--- a/test/harness/utils.py
+++ b/test/harness/utils.py
@@ -29,7 +29,7 @@ htmlURLPrefix = "file://" + htmlDir + "/"
 # These regex's attempt to provide a way to manage those differences.
 #
 firefoxAppNames = "(Firefox|Minefield)"
-firefoxFrameNames = "(Mozilla Firefox|Mozilla Firefox 3.1 Beta 2|Mozilla Firefox 3.1 Beta 3|Minefield)"
+firefoxFrameNames = "(Mozilla Firefox|Mozilla Firefox 3.1 Beta 2|Mozilla Firefox 3.1 Beta 3|Minefield|Mozilla Firefox 3.5 Beta 4)"
 firefoxLocationBarNames = "(Location|Search Bookmarks and History)"
 
 # Various OpenOffice names as a regex.  These are needed because OOo likes
diff --git a/test/keystrokes/firefox/codetalks_treegrid.py b/test/keystrokes/firefox/codetalks_treegrid.py
index d1af8dc..090efa2 100644
--- a/test/keystrokes/firefox/codetalks_treegrid.py
+++ b/test/keystrokes/firefox/codetalks_treegrid.py
@@ -121,8 +121,8 @@ sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
 sequence.append(utils.AssertPresentationAction(
     "Down Arrow into child", 
-    ["BRAILLE LINE:  'ISBN 978-3-453-40540-0 Cell Author Nora Roberts Cell Price $ 9.99 Cell'",
-     "     VISIBLE:  'ISBN 978-3-453-40540-0 Cell Auth', cursor=1",
+    ["BRAILLE LINE:  '978-3-453-40540-0 Cell Nora Roberts Cell $ 9.99 Cell'",
+     "     VISIBLE:  '978-3-453-40540-0 Cell Nora Robe', cursor=1",
      "SPEECH OUTPUT: '978-3-453-40540-0'"]))
 
 ########################################################################
@@ -132,16 +132,16 @@ sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Right"))
 sequence.append(utils.AssertPresentationAction(
     "1. Right Arrow in child", 
-    ["BRAILLE LINE:  'ISBN 978-3-453-40540-0 Cell Author Nora Roberts Cell Price $ 9.99 Cell'",
-     "     VISIBLE:  'Author Nora Roberts Cell Price $', cursor=1",
+    ["BRAILLE LINE:  '978-3-453-40540-0 Cell Nora Roberts Cell $ 9.99 Cell'",
+     "     VISIBLE:  'Nora Roberts Cell $ 9.99 Cell', cursor=1",
      "SPEECH OUTPUT: 'Nora Roberts'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Right"))
 sequence.append(utils.AssertPresentationAction(
     "2. Right Arrow in child", 
-    ["BRAILLE LINE:  'ISBN 978-3-453-40540-0 Cell Author Nora Roberts Cell Price $ 9.99 Cell'",
-     "     VISIBLE:  'Price $ 9.99 Cell', cursor=1",
+    ["BRAILLE LINE:  '978-3-453-40540-0 Cell Nora Roberts Cell $ 9.99 Cell'",
+     "     VISIBLE:  '$ 9.99 Cell', cursor=1",
      "SPEECH OUTPUT: '$ 9.99'"]))
 
 ########################################################################
@@ -151,16 +151,16 @@ sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Left"))
 sequence.append(utils.AssertPresentationAction(
     "1. Left Arrow in child", 
-    ["BRAILLE LINE:  'ISBN 978-3-453-40540-0 Cell Author Nora Roberts Cell Price $ 9.99 Cell'",
-     "     VISIBLE:  'Author Nora Roberts Cell Price $', cursor=1",
+    ["BRAILLE LINE:  '978-3-453-40540-0 Cell Nora Roberts Cell $ 9.99 Cell'",
+     "     VISIBLE:  'Nora Roberts Cell $ 9.99 Cell', cursor=1",
      "SPEECH OUTPUT: 'Nora Roberts'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Left"))
 sequence.append(utils.AssertPresentationAction(
     "2. Left Arrow in child", 
-    ["BRAILLE LINE:  'ISBN 978-3-453-40540-0 Cell Author Nora Roberts Cell Price $ 9.99 Cell'",
-     "     VISIBLE:  'ISBN 978-3-453-40540-0 Cell Auth', cursor=1",
+    ["BRAILLE LINE:  '978-3-453-40540-0 Cell Nora Roberts Cell $ 9.99 Cell'",
+     "     VISIBLE:  '978-3-453-40540-0 Cell Nora Robe', cursor=1",
      "SPEECH OUTPUT: '978-3-453-40540-0'"]))
 
 ########################################################################
diff --git a/test/keystrokes/firefox/dojo_bug_570566.py b/test/keystrokes/firefox/dojo_bug_570566.py
index 9f757c4..d9077f7 100644
--- a/test/keystrokes/firefox/dojo_bug_570566.py
+++ b/test/keystrokes/firefox/dojo_bug_570566.py
@@ -20,7 +20,7 @@ sequence.append(WaitForWindowActivate(utils.firefoxFrameNames, None))
 #
 sequence.append(KeyComboAction("<Control>l"))
 sequence.append(WaitForFocus(acc_role=pyatspi.ROLE_ENTRY))
-sequence.append(TypeAction(utils.DojoNightlyURLPrefix + "test_Editor.html"))
+sequence.append(TypeAction(utils.DojoNightlyURLPrefix + "editor/test_Editor.html"))
 sequence.append(KeyComboAction("Return"))
 sequence.append(WaitForDocLoad())
 sequence.append(WaitForFocus("Editor Test", 
@@ -59,14 +59,14 @@ sequence.append(utils.AssertPresentationAction(
      "     VISIBLE:  'Created from div h2', cursor=1",
      "SPEECH OUTPUT: 'Created from div heading level 2 heading level 2'"]))
 
-sequence.append(utils.StartRecordingAction())
-sequence.append(KeyComboAction("Up"))
-sequence.append(PauseAction(2000))
-sequence.append(utils.AssertPresentationAction(
-    "2. Up Arrow", 
-    ["BRAILLE LINE:  'Created from div h2'",
-     "     VISIBLE:  'Created from div h2', cursor=1",
-     "SPEECH OUTPUT: 'Created from div heading level 2'"]))
+#sequence.append(utils.StartRecordingAction())
+#sequence.append(KeyComboAction("Up"))
+#sequence.append(PauseAction(2000))
+#sequence.append(utils.AssertPresentationAction(
+#    "2. Up Arrow", 
+#    ["BRAILLE LINE:  'Created from div h2'",
+#     "     VISIBLE:  'Created from div h2', cursor=1",
+#     "SPEECH OUTPUT: 'Created from div heading level 2'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
diff --git a/test/keystrokes/firefox/dojo_spinner.py b/test/keystrokes/firefox/dojo_spinner.py
index f4b3103..fec09c5 100644
--- a/test/keystrokes/firefox/dojo_spinner.py
+++ b/test/keystrokes/firefox/dojo_spinner.py
@@ -39,8 +39,8 @@ sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Tab"))
 sequence.append(utils.AssertPresentationAction(
     "Tab to the first spinner",
-    ["BRAILLE LINE:  'Spinbox #1: 900 $l'",
-     "     VISIBLE:  'Spinbox #1: 900 $l', cursor=16",
+    ["BRAILLE LINE:  'Spinbox #1: 900 $l required'",
+     "     VISIBLE:  'Spinbox #1: 900 $l required', cursor=16",
      "SPEECH OUTPUT: 'Spinbox #1: 900 selected spin button required'"]))
 
 ########################################################################
@@ -50,10 +50,10 @@ sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
 sequence.append(utils.AssertPresentationAction(
     "first spinner decrement 1", 
-    ["BRAILLE LINE:  'Spinbox #1: 900 $l'",
-     "     VISIBLE:  'Spinbox #1: 900 $l', cursor=16",
-     "BRAILLE LINE:  'Spinbox #1: 899 $l'",
-     "     VISIBLE:  'Spinbox #1: 899 $l', cursor=16",
+    ["BRAILLE LINE:  'Spinbox #1: 900 $l required'",
+     "     VISIBLE:  'Spinbox #1: 900 $l required', cursor=16",
+     "BRAILLE LINE:  'Spinbox #1: 899 $l required'",
+     "     VISIBLE:  'Spinbox #1: 899 $l required', cursor=16",
      "SPEECH OUTPUT: '899'"]))
 
 ########################################################################
@@ -63,10 +63,10 @@ sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
 sequence.append(utils.AssertPresentationAction(
     "first spinner decrement 2", 
-    ["BRAILLE LINE:  'Spinbox #1: 899 $l'",
-     "     VISIBLE:  'Spinbox #1: 899 $l', cursor=16",
-     "BRAILLE LINE:  'Spinbox #1: 898 $l'",
-     "     VISIBLE:  'Spinbox #1: 898 $l', cursor=16",
+    ["BRAILLE LINE:  'Spinbox #1: 899 $l required'",
+     "     VISIBLE:  'Spinbox #1: 899 $l required', cursor=16",
+     "BRAILLE LINE:  'Spinbox #1: 898 $l required'",
+     "     VISIBLE:  'Spinbox #1: 898 $l required', cursor=16",
      "SPEECH OUTPUT: '898'"]))
 
 ########################################################################
@@ -76,10 +76,10 @@ sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
 sequence.append(utils.AssertPresentationAction(
     "first spinner decrement 3", 
-    ["BRAILLE LINE:  'Spinbox #1: 898 $l'",
-     "     VISIBLE:  'Spinbox #1: 898 $l', cursor=16",
-     "BRAILLE LINE:  'Spinbox #1: 897 $l'",
-     "     VISIBLE:  'Spinbox #1: 897 $l', cursor=16",
+    ["BRAILLE LINE:  'Spinbox #1: 898 $l required'",
+     "     VISIBLE:  'Spinbox #1: 898 $l required', cursor=16",
+     "BRAILLE LINE:  'Spinbox #1: 897 $l required'",
+     "     VISIBLE:  'Spinbox #1: 897 $l required', cursor=16",
      "SPEECH OUTPUT: '897'"]))
 
 ########################################################################
@@ -89,10 +89,10 @@ sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
 sequence.append(utils.AssertPresentationAction(
     "first spinner decrement 4", 
-    ["BRAILLE LINE:  'Spinbox #1: 897 $l'",
-     "     VISIBLE:  'Spinbox #1: 897 $l', cursor=16",
-     "BRAILLE LINE:  'Spinbox #1: 896 $l'",
-     "     VISIBLE:  'Spinbox #1: 896 $l', cursor=16",
+    ["BRAILLE LINE:  'Spinbox #1: 897 $l required'",
+     "     VISIBLE:  'Spinbox #1: 897 $l required', cursor=16",
+     "BRAILLE LINE:  'Spinbox #1: 896 $l required'",
+     "     VISIBLE:  'Spinbox #1: 896 $l required', cursor=16",
      "SPEECH OUTPUT: '896'"]))
 
 ########################################################################
@@ -102,10 +102,10 @@ sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
 sequence.append(utils.AssertPresentationAction(
     "first spinner decrement 5", 
-    ["BRAILLE LINE:  'Spinbox #1: 896 $l'",
-     "     VISIBLE:  'Spinbox #1: 896 $l', cursor=16",
-     "BRAILLE LINE:  'Spinbox #1: 895 $l'",
-     "     VISIBLE:  'Spinbox #1: 895 $l', cursor=16",
+    ["BRAILLE LINE:  'Spinbox #1: 896 $l required'",
+     "     VISIBLE:  'Spinbox #1: 896 $l required', cursor=16",
+     "BRAILLE LINE:  'Spinbox #1: 895 $l required'",
+     "     VISIBLE:  'Spinbox #1: 895 $l required', cursor=16",
      "SPEECH OUTPUT: '895'"]))
 
 ########################################################################
@@ -115,10 +115,10 @@ sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
 sequence.append(utils.AssertPresentationAction(
     "first spinner increment 1", 
-    ["BRAILLE LINE:  'Spinbox #1: 895 $l'",
-     "     VISIBLE:  'Spinbox #1: 895 $l', cursor=16",
-     "BRAILLE LINE:  'Spinbox #1: 896 $l'",
-     "     VISIBLE:  'Spinbox #1: 896 $l', cursor=16",
+    ["BRAILLE LINE:  'Spinbox #1: 895 $l required'",
+     "     VISIBLE:  'Spinbox #1: 895 $l required', cursor=16",
+     "BRAILLE LINE:  'Spinbox #1: 896 $l required'",
+     "     VISIBLE:  'Spinbox #1: 896 $l required', cursor=16",
      "SPEECH OUTPUT: '896'"]))
 
 ########################################################################
@@ -128,10 +128,10 @@ sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
 sequence.append(utils.AssertPresentationAction(
     "first spinner increment 2", 
-    ["BRAILLE LINE:  'Spinbox #1: 896 $l'",
-     "     VISIBLE:  'Spinbox #1: 896 $l', cursor=16",
-     "BRAILLE LINE:  'Spinbox #1: 897 $l'",
-     "     VISIBLE:  'Spinbox #1: 897 $l', cursor=16",
+    ["BRAILLE LINE:  'Spinbox #1: 896 $l required'",
+     "     VISIBLE:  'Spinbox #1: 896 $l required', cursor=16",
+     "BRAILLE LINE:  'Spinbox #1: 897 $l required'",
+     "     VISIBLE:  'Spinbox #1: 897 $l required', cursor=16",
      "SPEECH OUTPUT: '897'"]))
 
 ########################################################################
@@ -141,10 +141,10 @@ sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
 sequence.append(utils.AssertPresentationAction(
     "first spinner increment 3", 
-    ["BRAILLE LINE:  'Spinbox #1: 897 $l'",
-     "     VISIBLE:  'Spinbox #1: 897 $l', cursor=16",
-     "BRAILLE LINE:  'Spinbox #1: 898 $l'",
-     "     VISIBLE:  'Spinbox #1: 898 $l', cursor=16",
+    ["BRAILLE LINE:  'Spinbox #1: 897 $l required'",
+     "     VISIBLE:  'Spinbox #1: 897 $l required', cursor=16",
+     "BRAILLE LINE:  'Spinbox #1: 898 $l required'",
+     "     VISIBLE:  'Spinbox #1: 898 $l required', cursor=16",
      "SPEECH OUTPUT: '898'"]))
 
 ########################################################################
@@ -154,10 +154,10 @@ sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
 sequence.append(utils.AssertPresentationAction(
     "first spinner increment 4", 
-    ["BRAILLE LINE:  'Spinbox #1: 898 $l'",
-     "     VISIBLE:  'Spinbox #1: 898 $l', cursor=16",
-     "BRAILLE LINE:  'Spinbox #1: 899 $l'",
-     "     VISIBLE:  'Spinbox #1: 899 $l', cursor=16",
+    ["BRAILLE LINE:  'Spinbox #1: 898 $l required'",
+     "     VISIBLE:  'Spinbox #1: 898 $l required', cursor=16",
+     "BRAILLE LINE:  'Spinbox #1: 899 $l required'",
+     "     VISIBLE:  'Spinbox #1: 899 $l required', cursor=16",
      "SPEECH OUTPUT: '899'"]))
 
 ########################################################################
@@ -167,10 +167,10 @@ sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
 sequence.append(utils.AssertPresentationAction(
     "first spinner increment 5", 
-    ["BRAILLE LINE:  'Spinbox #1: 899 $l'",
-     "     VISIBLE:  'Spinbox #1: 899 $l', cursor=16",
-     "BRAILLE LINE:  'Spinbox #1: 900 $l'",
-     "     VISIBLE:  'Spinbox #1: 900 $l', cursor=16",
+    ["BRAILLE LINE:  'Spinbox #1: 899 $l required'",
+     "     VISIBLE:  'Spinbox #1: 899 $l required', cursor=16",
+     "BRAILLE LINE:  'Spinbox #1: 900 $l required'",
+     "     VISIBLE:  'Spinbox #1: 900 $l required', cursor=16",
      "SPEECH OUTPUT: '900'"]))
 
 ########################################################################
@@ -180,10 +180,10 @@ sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
 sequence.append(utils.AssertPresentationAction(
     "first spinner increment 6", 
-    ["BRAILLE LINE:  'Spinbox #1: 900 $l'",
-     "     VISIBLE:  'Spinbox #1: 900 $l', cursor=16",
-     "BRAILLE LINE:  'Spinbox #1: 901 $l'",
-     "     VISIBLE:  'Spinbox #1: 901 $l', cursor=16",
+    ["BRAILLE LINE:  'Spinbox #1: 900 $l required'",
+     "     VISIBLE:  'Spinbox #1: 900 $l required', cursor=16",
+     "BRAILLE LINE:  'Spinbox #1: 901 $l required'",
+     "     VISIBLE:  'Spinbox #1: 901 $l required', cursor=16",
      "SPEECH OUTPUT: '901'"]))
 
 ########################################################################
@@ -193,10 +193,10 @@ sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
 sequence.append(utils.AssertPresentationAction(
     "first spinner increment 7", 
-    ["BRAILLE LINE:  'Spinbox #1: 901 $l'",
-     "     VISIBLE:  'Spinbox #1: 901 $l', cursor=16",
-     "BRAILLE LINE:  'Spinbox #1: 902 $l'",
-     "     VISIBLE:  'Spinbox #1: 902 $l', cursor=16",
+    ["BRAILLE LINE:  'Spinbox #1: 901 $l required'",
+     "     VISIBLE:  'Spinbox #1: 901 $l required', cursor=16",
+     "BRAILLE LINE:  'Spinbox #1: 902 $l required'",
+     "     VISIBLE:  'Spinbox #1: 902 $l required', cursor=16",
      "SPEECH OUTPUT: '902'"]))
 
 ########################################################################
@@ -207,8 +207,8 @@ sequence.append(KeyComboAction("KP_Enter"))
 sequence.append(PauseAction(3000))
 sequence.append(utils.AssertPresentationAction(
     "basic whereAmI", 
-    ["BRAILLE LINE:  'Spinbox #1: 902 $l'",
-     "     VISIBLE:  'Spinbox #1: 902 $l', cursor=16",
+    ["BRAILLE LINE:  'Spinbox #1: 902 $l required'",
+     "     VISIBLE:  'Spinbox #1: 902 $l required', cursor=16",
      "SPEECH OUTPUT: 'Spinbox #1: spin button 902 required'"]))
 
 ########################################################################
diff --git a/test/keystrokes/firefox/dojo_tree.py b/test/keystrokes/firefox/dojo_tree.py
index ca435ee..27f20f8 100644
--- a/test/keystrokes/firefox/dojo_tree.py
+++ b/test/keystrokes/firefox/dojo_tree.py
@@ -37,8 +37,8 @@ sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Tab"))
 sequence.append(utils.AssertPresentationAction(
     "tab to continents", 
-    ["BRAILLE LINE:  'Continents ListItem'",
-     "     VISIBLE:  'Continents ListItem', cursor=1",
+    ["BRAILLE LINE:  'Continents expanded ListItem'",
+     "     VISIBLE:  'Continents expanded ListItem', cursor=1",
      "SPEECH OUTPUT: 'Continents expanded tree level 1'"]))
 
 ########################################################################
@@ -48,8 +48,8 @@ sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
 sequence.append(utils.AssertPresentationAction(
     "arrow to Africa", 
-    ["BRAILLE LINE:  'Africa ListItem'",
-     "     VISIBLE:  'Africa ListItem', cursor=1",
+    ["BRAILLE LINE:  'Africa collapsed ListItem'",
+     "     VISIBLE:  'Africa collapsed ListItem', cursor=1",
      "SPEECH OUTPUT: 'Africa collapsed tree level 2'"]))
 
 ########################################################################
@@ -60,8 +60,8 @@ sequence.append(KeyComboAction("KP_Enter"))
 sequence.append(PauseAction(3000))
 sequence.append(utils.AssertPresentationAction(
     "basic whereAmI", 
-    ["BRAILLE LINE:  'Africa ListItem'",
-     "     VISIBLE:  'Africa ListItem', cursor=1",
+    ["BRAILLE LINE:  'Africa collapsed ListItem'",
+     "     VISIBLE:  'Africa collapsed ListItem', cursor=1",
      "SPEECH OUTPUT: 'list item Africa item 1 of 6 collapsed tree level 2'"]))
 
 ########################################################################
@@ -71,8 +71,8 @@ sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Right"))
 sequence.append(utils.AssertPresentationAction(
     "expand Africa", 
-    ["BRAILLE LINE:  'Africa ListItem'",
-     "     VISIBLE:  'Africa ListItem', cursor=1",
+    ["BRAILLE LINE:  'Africa expanded ListItem'",
+     "     VISIBLE:  'Africa expanded ListItem', cursor=1",
      "SPEECH OUTPUT: 'expanded'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -89,48 +89,48 @@ sequence.append(KeyComboAction("Down"))
 sequence.append(WaitForFocus("Kenya", acc_role=pyatspi.ROLE_LIST_ITEM))
 sequence.append(utils.AssertPresentationAction(
     "arrow to Kenya", 
-    ["BRAILLE LINE:  'Kenya ListItem'",
-     "     VISIBLE:  'Kenya ListItem', cursor=1",
+    ["BRAILLE LINE:  'Kenya collapsed ListItem'",
+     "     VISIBLE:  'Kenya collapsed ListItem', cursor=1",
      "SPEECH OUTPUT: 'Kenya collapsed'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Right"))
 sequence.append(utils.AssertPresentationAction(
     "expand Kenya", 
-    ["BRAILLE LINE:  'Kenya ListItem'",
-     "     VISIBLE:  'Kenya ListItem', cursor=1",
+    ["BRAILLE LINE:  'Kenya expanded ListItem'",
+     "     VISIBLE:  'Kenya expanded ListItem', cursor=1",
      "SPEECH OUTPUT: 'expanded'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Left"))
 sequence.append(utils.AssertPresentationAction(
     "collapse Kenya", 
-    ["BRAILLE LINE:  'Kenya ListItem'",
-     "     VISIBLE:  'Kenya ListItem', cursor=1",
+    ["BRAILLE LINE:  'Kenya collapsed ListItem'",
+     "     VISIBLE:  'Kenya collapsed ListItem', cursor=1",
      "SPEECH OUTPUT: 'collapsed'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
 sequence.append(utils.AssertPresentationAction(
     "arrow to Sudan", 
-    ["BRAILLE LINE:  'Sudan ListItem'",
-     "     VISIBLE:  'Sudan ListItem', cursor=1",
+    ["BRAILLE LINE:  'Sudan collapsed ListItem'",
+     "     VISIBLE:  'Sudan collapsed ListItem', cursor=1",
      "SPEECH OUTPUT: 'Sudan collapsed'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
 sequence.append(utils.AssertPresentationAction(
     "arrow to Asia", 
-    ["BRAILLE LINE:  'Asia ListItem'",
-     "     VISIBLE:  'Asia ListItem', cursor=1",
+    ["BRAILLE LINE:  'Asia collapsed ListItem'",
+     "     VISIBLE:  'Asia collapsed ListItem', cursor=1",
      "SPEECH OUTPUT: 'Asia collapsed tree level 2'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Right"))
 sequence.append(utils.AssertPresentationAction(
     "expand Asia", 
-    ["BRAILLE LINE:  'Asia ListItem'",
-     "     VISIBLE:  'Asia ListItem', cursor=1",
+    ["BRAILLE LINE:  'Asia expanded ListItem'",
+     "     VISIBLE:  'Asia expanded ListItem', cursor=1",
      "SPEECH OUTPUT: 'expanded'"]))
 
 sequence.append(utils.StartRecordingAction())
diff --git a/test/keystrokes/firefox/html_role_combo_box.py b/test/keystrokes/firefox/html_role_combo_box.py
index 3e12c0b..47a19e4 100644
--- a/test/keystrokes/firefox/html_role_combo_box.py
+++ b/test/keystrokes/firefox/html_role_combo_box.py
@@ -115,7 +115,7 @@ sequence.append(KeyComboAction("<Alt>Down"))
 sequence.append(utils.AssertPresentationAction(
     "Alt Down to Expand",
     ["BRAILLE LINE:  'Priority: Normal Combo'",
-     "     VISIBLE:  'Priority: Normal Combo', cursor=0",
+     "     VISIBLE:  'Priority: Normal Combo', cursor=11",
      "BRAILLE LINE:  'Normal'",
      "     VISIBLE:  'Normal', cursor=1",
      "SPEECH OUTPUT: 'Normal combo box'",
@@ -198,7 +198,7 @@ sequence.append(KeyComboAction("Down"))
 sequence.append(utils.AssertPresentationAction(
     "Line Down", 
     ["BRAILLE LINE:  'Speech Combo'",
-     "     VISIBLE:  'Speech Combo', cursor=0",
+     "     VISIBLE:  'Speech Combo', cursor=1",
      "SPEECH OUTPUT: 'Speech combo box'"]))
 
 ########################################################################
@@ -210,7 +210,7 @@ sequence.append(KeyComboAction("<Alt>Down"))
 sequence.append(utils.AssertPresentationAction(
     "Alt Down to Expand", 
     ["BRAILLE LINE:  'Speech Combo'",
-     "     VISIBLE:  'Speech Combo', cursor=0",
+     "     VISIBLE:  'Speech Combo', cursor=1",
      "BRAILLE LINE:  'Speech'",
      "     VISIBLE:  'Speech', cursor=1",
      "SPEECH OUTPUT: 'Speech combo box'",
diff --git a/test/keystrokes/firefox/label_guess_bugzilla_search.py b/test/keystrokes/firefox/label_guess_bugzilla_search.py
index 5d0d652..53bd575 100644
--- a/test/keystrokes/firefox/label_guess_bugzilla_search.py
+++ b/test/keystrokes/firefox/label_guess_bugzilla_search.py
@@ -87,8 +87,8 @@ sequence.append(KeyComboAction("Tab"))
 sequence.append(KeyReleaseAction(0, None, "KP_Insert"))
 sequence.append(utils.AssertPresentationAction(
     "Next form field", 
-    ["BRAILLE LINE:  'Admin List'",
-     "     VISIBLE:  'Admin List', cursor=1",
+    ["BRAILLE LINE:  'Classification: Admin List'",
+     "     VISIBLE:  'Classification: Admin List', cursor=17",
      "SPEECH OUTPUT: 'Classification: Admin multi-select List with 8 items'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -97,8 +97,8 @@ sequence.append(KeyComboAction("Tab"))
 sequence.append(KeyReleaseAction(0, None, "KP_Insert"))
 sequence.append(utils.AssertPresentationAction(
     "Next form field", 
-    ["BRAILLE LINE:  'accerciser List'",
-     "     VISIBLE:  'accerciser List', cursor=1",
+    ["BRAILLE LINE:  'Product: accerciser List'",
+     "     VISIBLE:  'Product: accerciser List', cursor=10",
      "SPEECH OUTPUT: 'Product: accerciser multi-select List with 379 items'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -107,8 +107,8 @@ sequence.append(KeyComboAction("Tab"))
 sequence.append(KeyReleaseAction(0, None, "KP_Insert"))
 sequence.append(utils.AssertPresentationAction(
     "Next form field", 
-    ["BRAILLE LINE:  'abiscan List'",
-     "     VISIBLE:  'abiscan List', cursor=1",
+    ["BRAILLE LINE:  'Component: abiscan List'",
+     "     VISIBLE:  'Component: abiscan List', cursor=12",
      "SPEECH OUTPUT: 'Component: abiscan multi-select List with 1248 items'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -117,8 +117,8 @@ sequence.append(KeyComboAction("Tab"))
 sequence.append(KeyReleaseAction(0, None, "KP_Insert"))
 sequence.append(utils.AssertPresentationAction(
     "Next form field", 
-    ["BRAILLE LINE:  '0.0.1 List'",
-     "     VISIBLE:  '0.0.1 List', cursor=1",
+    ["BRAILLE LINE:  'Version: 0.0.1 List'",
+     "     VISIBLE:  'Version: 0.0.1 List', cursor=10",
      "SPEECH OUTPUT: 'Version: 0.0.1 multi-select List with 857 items'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -127,8 +127,8 @@ sequence.append(KeyComboAction("Tab"))
 sequence.append(KeyReleaseAction(0, None, "KP_Insert"))
 sequence.append(utils.AssertPresentationAction(
     "Next form field", 
-    ["BRAILLE LINE:  '--- List'",
-     "     VISIBLE:  '--- List', cursor=1",
+    ["BRAILLE LINE:  'Target Milestone: --- List'",
+     "     VISIBLE:  'Target Milestone: --- List', cursor=19",
      "SPEECH OUTPUT: 'Target Milestone: --- multi-select List with 555 items'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -198,8 +198,8 @@ sequence.append(KeyComboAction("Tab"))
 sequence.append(KeyReleaseAction(0, None, "KP_Insert"))
 sequence.append(utils.AssertPresentationAction(
     "Next form field", 
-    ["BRAILLE LINE:  'UNCONFIRMED List'",
-     "     VISIBLE:  'UNCONFIRMED List', cursor=1",
+    ["BRAILLE LINE:  'Status: UNCONFIRMED List'",
+     "     VISIBLE:  'Status: UNCONFIRMED List', cursor=9",
      "SPEECH OUTPUT: 'Status: UNCONFIRMED multi-select List with 8 items'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -208,8 +208,8 @@ sequence.append(KeyComboAction("Tab"))
 sequence.append(KeyReleaseAction(0, None, "KP_Insert"))
 sequence.append(utils.AssertPresentationAction(
     "Next form field", 
-    ["BRAILLE LINE:  'FIXED List'",
-     "     VISIBLE:  'FIXED List', cursor=1",
+    ["BRAILLE LINE:  'Resolution: FIXED List'",
+     "     VISIBLE:  'Resolution: FIXED List', cursor=13",
      "SPEECH OUTPUT: 'Resolution: FIXED multi-select List with 12 items'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -218,8 +218,8 @@ sequence.append(KeyComboAction("Tab"))
 sequence.append(KeyReleaseAction(0, None, "KP_Insert"))
 sequence.append(utils.AssertPresentationAction(
     "Next form field", 
-    ["BRAILLE LINE:  'blocker List'",
-     "     VISIBLE:  'blocker List', cursor=1",
+    ["BRAILLE LINE:  'Severity: blocker List'",
+     "     VISIBLE:  'Severity: blocker List', cursor=11",
      "SPEECH OUTPUT: 'Severity: blocker multi-select List with 7 items'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -228,8 +228,8 @@ sequence.append(KeyComboAction("Tab"))
 sequence.append(KeyReleaseAction(0, None, "KP_Insert"))
 sequence.append(utils.AssertPresentationAction(
     "Next form field", 
-    ["BRAILLE LINE:  'Immediate List'",
-     "     VISIBLE:  'Immediate List', cursor=1",
+    ["BRAILLE LINE:  'Priority: Immediate List'",
+     "     VISIBLE:  'Priority: Immediate List', cursor=11",
      "SPEECH OUTPUT: 'Priority: Immediate multi-select List with 5 items'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -238,8 +238,8 @@ sequence.append(KeyComboAction("Tab"))
 sequence.append(KeyReleaseAction(0, None, "KP_Insert"))
 sequence.append(utils.AssertPresentationAction(
     "Next form field", 
-    ["BRAILLE LINE:  'All List'",
-     "     VISIBLE:  'All List', cursor=1",
+    ["BRAILLE LINE:  'OS: All List'",
+     "     VISIBLE:  'OS: All List', cursor=5",
      "SPEECH OUTPUT: 'OS: All multi-select List with 21 items'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -432,8 +432,9 @@ sequence.append(KeyComboAction("Tab"))
 sequence.append(KeyReleaseAction(0, None, "KP_Insert"))
 sequence.append(utils.AssertPresentationAction(
     "Next form field", 
-    ["BRAILLE LINE:  '[Bug creation] List'",
-     "     VISIBLE:  '[Bug creation] List', cursor=1",
+    ["BUG? - The VISIBLE line positions the cursor so the first character in the list is showing. Since the list is focused, should the full list be displayed instead?",
+     "BRAILLE LINE:  'where one or more of the following changed: [Bug creation] List'",
+     "     VISIBLE:  'more of the following changed: [', cursor=32",
      "SPEECH OUTPUT: 'where one or more of the following changed: [Bug creation] multi-select List with 26 items'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -453,8 +454,8 @@ sequence.append(KeyComboAction("Tab"))
 sequence.append(KeyReleaseAction(0, None, "KP_Insert"))
 sequence.append(utils.AssertPresentationAction(
     "Next form field", 
-    ["BRAILLE LINE:  'Unspecified List'",
-     "     VISIBLE:  'Unspecified List', cursor=1",
+    ["BRAILLE LINE:  'GNOME version: Unspecified List'",
+     "     VISIBLE:  'GNOME version: Unspecified List', cursor=16",
      "SPEECH OUTPUT: 'GNOME version: Unspecified multi-select List with 14 items'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -463,8 +464,8 @@ sequence.append(KeyComboAction("Tab"))
 sequence.append(KeyReleaseAction(0, None, "KP_Insert"))
 sequence.append(utils.AssertPresentationAction(
     "Next form field", 
-    ["BRAILLE LINE:  'Unspecified List'",
-     "     VISIBLE:  'Unspecified List', cursor=1",
+    ["BRAILLE LINE:  'GNOME target: Unspecified List'",
+     "     VISIBLE:  'GNOME target: Unspecified List', cursor=15",
      "SPEECH OUTPUT: 'GNOME target: Unspecified multi-select List with 12 items'"]))
 
 sequence.append(utils.StartRecordingAction())
diff --git a/test/keystrokes/firefox/line_nav_bugzilla_search.py b/test/keystrokes/firefox/line_nav_bugzilla_search.py
index d41ec57..57e4731 100644
--- a/test/keystrokes/firefox/line_nav_bugzilla_search.py
+++ b/test/keystrokes/firefox/line_nav_bugzilla_search.py
@@ -90,8 +90,8 @@ sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
 sequence.append(utils.AssertPresentationAction(
     "Line Down",
-    ["BRAILLE LINE:  'List'",
-     "     VISIBLE:  'List', cursor=0",
+    ["BRAILLE LINE:  'Admin List'",
+     "     VISIBLE:  'Admin List', cursor=1",
      "SPEECH OUTPUT: 'Admin multi-select List with 8 items'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -106,8 +106,8 @@ sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
 sequence.append(utils.AssertPresentationAction(
     "Line Down",
-    ["BRAILLE LINE:  'List'",
-     "     VISIBLE:  'List', cursor=0",
+    ["BRAILLE LINE:  'accerciser List'",
+     "     VISIBLE:  'accerciser List', cursor=1",
      "SPEECH OUTPUT: 'accerciser multi-select List with 379 items'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -122,8 +122,8 @@ sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
 sequence.append(utils.AssertPresentationAction(
     "Line Down",
-    ["BRAILLE LINE:  'List'",
-     "     VISIBLE:  'List', cursor=0",
+    ["BRAILLE LINE:  'abiscan List'",
+     "     VISIBLE:  'abiscan List', cursor=1",
      "SPEECH OUTPUT: 'abiscan multi-select List with 1248 items'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -138,8 +138,8 @@ sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
 sequence.append(utils.AssertPresentationAction(
     "Line Down",
-    ["BRAILLE LINE:  'List'",
-     "     VISIBLE:  'List', cursor=0",
+    ["BRAILLE LINE:  '0.0.1 List'",
+     "     VISIBLE:  '0.0.1 List', cursor=1",
      "SPEECH OUTPUT: '0.0.1 multi-select List with 857 items'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -154,8 +154,8 @@ sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
 sequence.append(utils.AssertPresentationAction(
     "Line Down",
-    ["BRAILLE LINE:  'List'",
-     "     VISIBLE:  'List', cursor=0",
+    ["BRAILLE LINE:  '--- List'",
+     "     VISIBLE:  '--- List', cursor=1",
      "SPEECH OUTPUT: '--- multi-select List with 555 items'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -202,8 +202,8 @@ sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
 sequence.append(utils.AssertPresentationAction(
     "Line Down",
-    ["BRAILLE LINE:  'List'",
-     "     VISIBLE:  'List', cursor=0",
+    ["BRAILLE LINE:  'UNCONFIRMED List'",
+     "     VISIBLE:  'UNCONFIRMED List', cursor=1",
      "SPEECH OUTPUT: 'UNCONFIRMED' voice=uppercase",
      "SPEECH OUTPUT: 'multi-select List with 8 items'"]))
 
@@ -219,8 +219,8 @@ sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
 sequence.append(utils.AssertPresentationAction(
     "Line Down",
-    ["BRAILLE LINE:  'List'",
-     "     VISIBLE:  'List', cursor=0",
+    ["BRAILLE LINE:  'FIXED List'",
+     "     VISIBLE:  'FIXED List', cursor=1",
      "SPEECH OUTPUT: 'FIXED' voice=uppercase",
      "SPEECH OUTPUT: 'multi-select List with 12 items'"]))
 
@@ -236,8 +236,8 @@ sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
 sequence.append(utils.AssertPresentationAction(
     "Line Down",
-    ["BRAILLE LINE:  'List'",
-     "     VISIBLE:  'List', cursor=0",
+    ["BRAILLE LINE:  'blocker List'",
+     "     VISIBLE:  'blocker List', cursor=1",
      "SPEECH OUTPUT: 'blocker multi-select List with 7 items'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -252,8 +252,8 @@ sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
 sequence.append(utils.AssertPresentationAction(
     "Line Down",
-    ["BRAILLE LINE:  'List'",
-     "     VISIBLE:  'List', cursor=0",
+    ["BRAILLE LINE:  'Immediate List'",
+     "     VISIBLE:  'Immediate List', cursor=1",
      "SPEECH OUTPUT: 'Immediate multi-select List with 5 items'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -268,8 +268,8 @@ sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
 sequence.append(utils.AssertPresentationAction(
     "Line Down",
-    ["BRAILLE LINE:  'List'",
-     "     VISIBLE:  'List', cursor=0",
+    ["BRAILLE LINE:  'All List'",
+     "     VISIBLE:  'All List', cursor=1",
      "SPEECH OUTPUT: 'All multi-select List with 21 items'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -333,7 +333,7 @@ sequence.append(KeyComboAction("Down"))
 sequence.append(utils.AssertPresentationAction(
     "Line Down",
     ["BRAILLE LINE:  'contains Combo'",
-     "     VISIBLE:  'contains Combo', cursor=0",
+     "     VISIBLE:  'contains Combo', cursor=1",
      "SPEECH OUTPUT: 'contains combo box'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -397,7 +397,7 @@ sequence.append(KeyComboAction("Down"))
 sequence.append(utils.AssertPresentationAction(
     "Line Down",
     ["BRAILLE LINE:  'contains Combo'",
-     "     VISIBLE:  'contains Combo', cursor=0",
+     "     VISIBLE:  'contains Combo', cursor=1",
      "SPEECH OUTPUT: 'contains combo box'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -421,7 +421,7 @@ sequence.append(KeyComboAction("Down"))
 sequence.append(utils.AssertPresentationAction(
     "Line Down",
     ["BRAILLE LINE:  'Only include Combo bugs numbered:  $l'",
-     "     VISIBLE:  'Only include Combo bugs numbered', cursor=0",
+     "     VISIBLE:  'Only include Combo bugs numbered', cursor=1",
      "SPEECH OUTPUT: 'Only include combo box bugs numbered: text'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -477,8 +477,8 @@ sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
 sequence.append(utils.AssertPresentationAction(
     "Line Down",
-    ["BRAILLE LINE:  'List'",
-     "     VISIBLE:  'List', cursor=0",
+    ["BRAILLE LINE:  '[Bug creation] List'",
+     "     VISIBLE:  '[Bug creation] List', cursor=1",
      "SPEECH OUTPUT: '[Bug creation] multi-select List with 26 items'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -509,8 +509,8 @@ sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
 sequence.append(utils.AssertPresentationAction(
     "Line Down",
-    ["BRAILLE LINE:  'List'",
-     "     VISIBLE:  'List', cursor=0",
+    ["BRAILLE LINE:  'Unspecified List'",
+     "     VISIBLE:  'Unspecified List', cursor=1",
      "SPEECH OUTPUT: 'Unspecified multi-select List with 14 items'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -525,8 +525,8 @@ sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
 sequence.append(utils.AssertPresentationAction(
     "Line Down",
-    ["BRAILLE LINE:  'List'",
-     "     VISIBLE:  'List', cursor=0",
+    ["BRAILLE LINE:  'Unspecified List'",
+     "     VISIBLE:  'Unspecified List', cursor=1",
      "SPEECH OUTPUT: 'Unspecified multi-select List with 12 items'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -582,7 +582,7 @@ sequence.append(KeyComboAction("Down"))
 sequence.append(utils.AssertPresentationAction(
     "Line Down",
     ["BRAILLE LINE:  '--- Combo --- Combo  $l Or Button'",
-     "     VISIBLE:  '--- Combo --- Combo  $l Or Butto', cursor=0",
+     "     VISIBLE:  '--- Combo --- Combo  $l Or Butto', cursor=1",
      "SPEECH OUTPUT: '--- combo box --- combo box text Or button'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -633,7 +633,7 @@ sequence.append(KeyComboAction("Up"))
 sequence.append(utils.AssertPresentationAction(
     "Line Up",
     ["BRAILLE LINE:  '--- Combo --- Combo  $l Or Button'",
-     "     VISIBLE:  '--- Combo --- Combo  $l Or Butto', cursor=0",
+     "     VISIBLE:  '--- Combo --- Combo  $l Or Butto', cursor=1",
      "SPEECH OUTPUT: '--- combo box --- combo box text Or button'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -688,8 +688,8 @@ sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
 sequence.append(utils.AssertPresentationAction(
     "Line Up",
-    ["BRAILLE LINE:  'List'",
-     "     VISIBLE:  'List', cursor=0",
+    ["BRAILLE LINE:  'Unspecified List'",
+     "     VISIBLE:  'Unspecified List', cursor=1",
      "SPEECH OUTPUT: 'Unspecified multi-select List with 12 items'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -704,8 +704,8 @@ sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
 sequence.append(utils.AssertPresentationAction(
     "Line Up",
-    ["BRAILLE LINE:  'List'",
-     "     VISIBLE:  'List', cursor=0",
+    ["BRAILLE LINE:  'Unspecified List'",
+     "     VISIBLE:  'Unspecified List', cursor=1",
      "SPEECH OUTPUT: 'Unspecified multi-select List with 14 items'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -736,8 +736,8 @@ sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
 sequence.append(utils.AssertPresentationAction(
     "Line Up",
-    ["BRAILLE LINE:  'List'",
-     "     VISIBLE:  'List', cursor=0",
+    ["BRAILLE LINE:  '[Bug creation] List'",
+     "     VISIBLE:  '[Bug creation] List', cursor=1",
      "SPEECH OUTPUT: '[Bug creation] multi-select List with 26 items'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -794,7 +794,7 @@ sequence.append(KeyComboAction("Up"))
 sequence.append(utils.AssertPresentationAction(
     "Line Up",
     ["BRAILLE LINE:  'Only include Combo bugs numbered:  $l'",
-     "     VISIBLE:  'Only include Combo bugs numbered', cursor=0",
+     "     VISIBLE:  'Only include Combo bugs numbered', cursor=1",
      "SPEECH OUTPUT: 'Only include combo box bugs numbered: text'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -818,7 +818,7 @@ sequence.append(KeyComboAction("Up"))
 sequence.append(utils.AssertPresentationAction(
     "Line Up",
     ["BRAILLE LINE:  'contains Combo'",
-     "     VISIBLE:  'contains Combo', cursor=0",
+     "     VISIBLE:  'contains Combo', cursor=1",
      "SPEECH OUTPUT: 'contains combo box'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -882,7 +882,7 @@ sequence.append(KeyComboAction("Up"))
 sequence.append(utils.AssertPresentationAction(
     "Line Up",
     ["BRAILLE LINE:  'contains Combo'",
-     "     VISIBLE:  'contains Combo', cursor=0",
+     "     VISIBLE:  'contains Combo', cursor=1",
      "SPEECH OUTPUT: 'contains combo box'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -945,8 +945,8 @@ sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
 sequence.append(utils.AssertPresentationAction(
     "Line Up",
-    ["BRAILLE LINE:  'List'",
-     "     VISIBLE:  'List', cursor=0",
+    ["BRAILLE LINE:  'All List'",
+     "     VISIBLE:  'All List', cursor=1",
      "SPEECH OUTPUT: 'All multi-select List with 21 items'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -961,8 +961,8 @@ sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
 sequence.append(utils.AssertPresentationAction(
     "Line Up",
-    ["BRAILLE LINE:  'List'",
-     "     VISIBLE:  'List', cursor=0",
+    ["BRAILLE LINE:  'Immediate List'",
+     "     VISIBLE:  'Immediate List', cursor=1",
      "SPEECH OUTPUT: 'Immediate multi-select List with 5 items'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -977,8 +977,8 @@ sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
 sequence.append(utils.AssertPresentationAction(
     "Line Up",
-    ["BRAILLE LINE:  'List'",
-     "     VISIBLE:  'List', cursor=0",
+    ["BRAILLE LINE:  'blocker List'",
+     "     VISIBLE:  'blocker List', cursor=1",
      "SPEECH OUTPUT: 'blocker multi-select List with 7 items'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -993,8 +993,8 @@ sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
 sequence.append(utils.AssertPresentationAction(
     "Line Up",
-    ["BRAILLE LINE:  'List'",
-     "     VISIBLE:  'List', cursor=0",
+    ["BRAILLE LINE:  'FIXED List'",
+     "     VISIBLE:  'FIXED List', cursor=1",
      "SPEECH OUTPUT: 'FIXED' voice=uppercase",
      "SPEECH OUTPUT: 'multi-select List with 12 items'"]))
 
@@ -1010,8 +1010,8 @@ sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
 sequence.append(utils.AssertPresentationAction(
     "Line Up",
-    ["BRAILLE LINE:  'List'",
-     "     VISIBLE:  'List', cursor=0",
+    ["BRAILLE LINE:  'UNCONFIRMED List'",
+     "     VISIBLE:  'UNCONFIRMED List', cursor=1",
      "SPEECH OUTPUT: 'UNCONFIRMED' voice=uppercase",
      "SPEECH OUTPUT: 'multi-select List with 8 items'"]))
 
@@ -1059,8 +1059,8 @@ sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
 sequence.append(utils.AssertPresentationAction(
     "Line Up",
-    ["BRAILLE LINE:  'List'",
-     "     VISIBLE:  'List', cursor=0",
+    ["BRAILLE LINE:  '--- List'",
+     "     VISIBLE:  '--- List', cursor=1",
      "SPEECH OUTPUT: '--- multi-select List with 555 items'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -1075,8 +1075,8 @@ sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
 sequence.append(utils.AssertPresentationAction(
     "Line Up",
-    ["BRAILLE LINE:  'List'",
-     "     VISIBLE:  'List', cursor=0",
+    ["BRAILLE LINE:  '0.0.1 List'",
+     "     VISIBLE:  '0.0.1 List', cursor=1",
      "SPEECH OUTPUT: '0.0.1 multi-select List with 857 items'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -1091,8 +1091,8 @@ sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
 sequence.append(utils.AssertPresentationAction(
     "Line Up",
-    ["BRAILLE LINE:  'List'",
-     "     VISIBLE:  'List', cursor=0",
+    ["BRAILLE LINE:  'abiscan List'",
+     "     VISIBLE:  'abiscan List', cursor=1",
      "SPEECH OUTPUT: 'abiscan multi-select List with 1248 items'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -1107,8 +1107,8 @@ sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
 sequence.append(utils.AssertPresentationAction(
     "Line Up",
-    ["BRAILLE LINE:  'List'",
-     "     VISIBLE:  'List', cursor=0",
+    ["BRAILLE LINE:  'accerciser List'",
+     "     VISIBLE:  'accerciser List', cursor=1",
      "SPEECH OUTPUT: 'accerciser multi-select List with 379 items'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -1123,8 +1123,8 @@ sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
 sequence.append(utils.AssertPresentationAction(
     "Line Up",
-    ["BRAILLE LINE:  'List'",
-     "     VISIBLE:  'List', cursor=0",
+    ["BRAILLE LINE:  'Admin List'",
+     "     VISIBLE:  'Admin List', cursor=1",
      "SPEECH OUTPUT: 'Admin multi-select List with 8 items'"]))
 
 sequence.append(utils.StartRecordingAction())
diff --git a/test/keystrokes/firefox/line_nav_enter_bug.py b/test/keystrokes/firefox/line_nav_enter_bug.py
index 59e2eaa..396b7cc 100644
--- a/test/keystrokes/firefox/line_nav_enter_bug.py
+++ b/test/keystrokes/firefox/line_nav_enter_bug.py
@@ -103,8 +103,8 @@ sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
 sequence.append(utils.AssertPresentationAction(
     "Line Down",
-    ["BRAILLE LINE:  'Version: List Component: List'",
-     "     VISIBLE:  'Version: List Component: List', cursor=1",
+    ["BRAILLE LINE:  'Version: 2.21.x List Component: braille List'",
+     "     VISIBLE:  'Version: 2.21.x List Component: ', cursor=1",
      "SPEECH OUTPUT: 'Version: 2.21.x List with 9 items Component link : braille List with 5 items'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -136,7 +136,7 @@ sequence.append(KeyComboAction("Down"))
 sequence.append(utils.AssertPresentationAction(
     "Line Down",
     ["BRAILLE LINE:  'GNOME Unspecified Combo'",
-     "     VISIBLE:  'GNOME Unspecified Combo', cursor=0",
+     "     VISIBLE:  'GNOME Unspecified Combo', cursor=7",
      "SPEECH OUTPUT: 'GNOME link Unspecified combo box'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -428,8 +428,8 @@ sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
 sequence.append(utils.AssertPresentationAction(
     "Line Up",
-    ["BRAILLE LINE:  'Version: List Component: List'",
-     "     VISIBLE:  'Version: List Component: List', cursor=1",
+    ["BRAILLE LINE:  'Version: 2.21.x List Component: braille List'",
+     "     VISIBLE:  'Version: 2.21.x List Component: ', cursor=1",
      "SPEECH OUTPUT: 'Version: 2.21.x List with 9 items Component link : braille List with 5 items'"]))
 
 sequence.append(utils.StartRecordingAction())
diff --git a/test/keystrokes/firefox/line_nav_simple_form.py b/test/keystrokes/firefox/line_nav_simple_form.py
index bbb7e5b..c32ac1b 100644
--- a/test/keystrokes/firefox/line_nav_simple_form.py
+++ b/test/keystrokes/firefox/line_nav_simple_form.py
@@ -144,8 +144,8 @@ sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
 sequence.append(utils.AssertPresentationAction(
     "13. line Down",
-    ["BRAILLE LINE:  'List'",
-     "     VISIBLE:  'List', cursor=0",
+    ["BRAILLE LINE:  'Hockey List'",
+     "     VISIBLE:  'Hockey List', cursor=1",
      "SPEECH OUTPUT: 'Hockey multi-select List with 4 items'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -181,8 +181,8 @@ sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
 sequence.append(utils.AssertPresentationAction(
     "2. line Up",
-    ["BRAILLE LINE:  'List'",
-     "     VISIBLE:  'List', cursor=0",
+    ["BRAILLE LINE:  'Hockey List'",
+     "     VISIBLE:  'Hockey List', cursor=1",
      "SPEECH OUTPUT: 'Hockey multi-select List with 4 items'"]))
 
 sequence.append(utils.StartRecordingAction())
diff --git a/test/keystrokes/firefox/line_nav_wiki.py b/test/keystrokes/firefox/line_nav_wiki.py
index 975a0ff..35fdea4 100644
--- a/test/keystrokes/firefox/line_nav_wiki.py
+++ b/test/keystrokes/firefox/line_nav_wiki.py
@@ -766,8 +766,8 @@ sequence.append(KeyComboAction("Down"))
 sequence.append(utils.AssertPresentationAction(
     "Line Down",
     ["BUG? - In 3.1 we aren't presenting More Actions at times; other times we are",
-     "BRAILLE LINE:  ' Combo'",
-     "     VISIBLE:  ' Combo', cursor=0",
+     "BRAILLE LINE:  'Combo'",
+     "     VISIBLE:  'Combo', cursor=1",
      "SPEECH OUTPUT: 'combo box'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -786,8 +786,8 @@ sequence.append(KeyComboAction("Up"))
 sequence.append(utils.AssertPresentationAction(
     "Line Up",
     ["BUG? - In 3.1 we aren't presenting More Actions at times; other times we are",
-     "BRAILLE LINE:  ' Combo'",
-     "     VISIBLE:  ' Combo', cursor=0",
+     "BRAILLE LINE:  'Combo'",
+     "     VISIBLE:  'Combo', cursor=1",
      "SPEECH OUTPUT: 'combo box'"]))
 
 sequence.append(utils.StartRecordingAction())
diff --git a/test/keystrokes/firefox/ms_tree_bug_570571.py b/test/keystrokes/firefox/ms_tree_bug_570571.py
index eeb594f..59df07e 100644
--- a/test/keystrokes/firefox/ms_tree_bug_570571.py
+++ b/test/keystrokes/firefox/ms_tree_bug_570571.py
@@ -34,8 +34,8 @@ sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Tab"))
 sequence.append(utils.AssertPresentationAction(
     "Tab to Colors", 
-    ["BRAILLE LINE:  '+Colors ListItem'",
-     "     VISIBLE:  '+Colors ListItem', cursor=1",
+    ["BRAILLE LINE:  '+Colors collapsed ListItem LEVEL 1'",
+     "     VISIBLE:  '+Colors collapsed ListItem LEVEL', cursor=1",
      "SPEECH OUTPUT: '+Colors collapsed tree level 1'"]))
 
 ########################################################################
@@ -47,20 +47,20 @@ sequence.append(PauseAction(3000))
 sequence.append(utils.AssertPresentationAction(
     "basic whereAmI", 
     ["BUG? - There are visually two items here, but we say this is 1 of 1",
-     "BRAILLE LINE:  '+Colors ListItem'",
-     "     VISIBLE:  '+Colors ListItem', cursor=1",
+     "BRAILLE LINE:  '+Colors collapsed ListItem LEVEL 1'",
+     "     VISIBLE:  '+Colors collapsed ListItem LEVEL', cursor=1",
      "SPEECH OUTPUT: 'list item +Colors item 1 of 1 collapsed tree level 1'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Right"))
 sequence.append(utils.AssertPresentationAction(
     "Expand Colors", 
-    ["BRAILLE LINE:  '+Colors ListItem'",
-     "     VISIBLE:  '+Colors ListItem', cursor=1",
-     "BRAILLE LINE:  '-Colors ListItem'",
-     "     VISIBLE:  '-Colors ListItem', cursor=1",
-     "BRAILLE LINE:  '-Colors ListItem'",
-     "     VISIBLE:  '-Colors ListItem', cursor=1",
+    ["BRAILLE LINE:  '+Colors collapsed ListItem LEVEL 1'",
+     "     VISIBLE:  '+Colors collapsed ListItem LEVEL', cursor=1",
+     "BRAILLE LINE:  '-Colors expanded ListItem LEVEL 1'",
+     "     VISIBLE:  '-Colors expanded ListItem LEVEL ', cursor=1",
+     "BRAILLE LINE:  '-Colors expanded ListItem LEVEL 1'",
+     "     VISIBLE:  '-Colors expanded ListItem LEVEL ', cursor=1",
      "SPEECH OUTPUT: 'expanded'"]))
 
 ########################################################################
@@ -71,8 +71,8 @@ sequence.append(KeyComboAction("KP_Enter"))
 sequence.append(PauseAction(3000))
 sequence.append(utils.AssertPresentationAction(
     "basic whereAmI", 
-    ["BRAILLE LINE:  '-Colors ListItem'",
-     "     VISIBLE:  '-Colors ListItem', cursor=1",
+    ["BRAILLE LINE:  '-Colors expanded ListItem LEVEL 1'",
+     "     VISIBLE:  '-Colors expanded ListItem LEVEL ', cursor=1",
      "SPEECH OUTPUT: 'list item -Colors item 1 of 2 expanded tree level 1'"]))
 
 ########################################################################
@@ -100,8 +100,8 @@ sequence.append(utils.AssertPresentationAction(
     "Up Arrow to Colors", 
     ["BRAILLE LINE:  'Red ListItem'",
      "     VISIBLE:  'Red ListItem', cursor=1",
-     "BRAILLE LINE:  '-Colors ListItem'",
-     "     VISIBLE:  '-Colors ListItem', cursor=1",
+     "BRAILLE LINE:  '-Colors expanded ListItem LEVEL 1'",
+     "     VISIBLE:  '-Colors expanded ListItem LEVEL ', cursor=1",
      "SPEECH OUTPUT: 'Red'",
      "SPEECH OUTPUT: '-Colors expanded tree level 1'"]))
 
@@ -109,12 +109,12 @@ sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Left"))
 sequence.append(utils.AssertPresentationAction(
     "Collapse Colors", 
-    ["BRAILLE LINE:  '-Colors ListItem'",
-     "     VISIBLE:  '-Colors ListItem', cursor=1",
-     "BRAILLE LINE:  '+Colors ListItem'",
-     "     VISIBLE:  '+Colors ListItem', cursor=1",
-     "BRAILLE LINE:  '+Colors ListItem'",
-     "     VISIBLE:  '+Colors ListItem', cursor=1",
+    ["BRAILLE LINE:  '-Colors expanded ListItem LEVEL 1'",
+     "     VISIBLE:  '-Colors expanded ListItem LEVEL ', cursor=1",
+     "BRAILLE LINE:  '+Colors collapsed ListItem LEVEL 1'",
+     "     VISIBLE:  '+Colors collapsed ListItem LEVEL', cursor=1",
+     "BRAILLE LINE:  '+Colors collapsed ListItem LEVEL 1'",
+     "     VISIBLE:  '+Colors collapsed ListItem LEVEL', cursor=1",
      "SPEECH OUTPUT: 'collapsed'"]))
 
 ########################################################################
@@ -124,20 +124,20 @@ sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Tab"))
 sequence.append(utils.AssertPresentationAction(
     "Tab to Animals", 
-    ["BRAILLE LINE:  '+Animals ListItem'",
-     "     VISIBLE:  '+Animals ListItem', cursor=1",
+    ["BRAILLE LINE:  '+Animals collapsed ListItem LEVEL 1'",
+     "     VISIBLE:  '+Animals collapsed ListItem LEVE', cursor=1",
      "SPEECH OUTPUT: '+Animals collapsed'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Right"))
 sequence.append(utils.AssertPresentationAction(
     "Expand Animals", 
-    ["BRAILLE LINE:  '+Animals ListItem'",
-     "     VISIBLE:  '+Animals ListItem', cursor=1",
-     "BRAILLE LINE:  '-Animals ListItem'",
-     "     VISIBLE:  '-Animals ListItem', cursor=1",
-     "BRAILLE LINE:  '-Animals ListItem'",
-     "     VISIBLE:  '-Animals ListItem', cursor=1",
+    ["BRAILLE LINE:  '+Animals collapsed ListItem LEVEL 1'",
+     "     VISIBLE:  '+Animals collapsed ListItem LEVE', cursor=1",
+     "BRAILLE LINE:  '-Animals expanded ListItem LEVEL 1'",
+     "     VISIBLE:  '-Animals expanded ListItem LEVEL', cursor=1",
+     "BRAILLE LINE:  '-Animals expanded ListItem LEVEL 1'",
+     "     VISIBLE:  '-Animals expanded ListItem LEVEL', cursor=1",
      "SPEECH OUTPUT: 'expanded'"]))
 
 ########################################################################
diff --git a/test/keystrokes/firefox/uiuc_tree.py b/test/keystrokes/firefox/uiuc_tree.py
index 8d7e69e..00d61ce 100644
--- a/test/keystrokes/firefox/uiuc_tree.py
+++ b/test/keystrokes/firefox/uiuc_tree.py
@@ -34,10 +34,10 @@ sequence.append(KeyComboAction("Tab"))
 sequence.append(WaitForFocus("Fruits", acc_role=pyatspi.ROLE_LIST_ITEM))
 sequence.append(utils.AssertPresentationAction(
     "tab to tree", 
-    ["BRAILLE LINE:  'Fruits ListItem'",
-     "     VISIBLE:  'Fruits ListItem', cursor=1",
-     "BRAILLE LINE:  'Fruits ListItem'",
-     "     VISIBLE:  'Fruits ListItem', cursor=1",
+    ["BRAILLE LINE:  'Fruits expanded'",
+     "     VISIBLE:  'Fruits expanded', cursor=1",
+     "BRAILLE LINE:  'Fruits expanded ListItem'",
+     "     VISIBLE:  'Fruits expanded ListItem', cursor=1",
      "SPEECH OUTPUT: 'Foods tree'",
      "SPEECH OUTPUT: 'Fruits expanded tree level 1'"]))
 
@@ -49,8 +49,8 @@ sequence.append(KeyComboAction("KP_Enter"))
 sequence.append(PauseAction(3000))
 sequence.append(utils.AssertPresentationAction(
     "basic whereAmI", 
-    ["BRAILLE LINE:  'Fruits ListItem'",
-     "     VISIBLE:  'Fruits ListItem', cursor=1",
+    ["BRAILLE LINE:  'Fruits expanded ListItem'",
+     "     VISIBLE:  'Fruits expanded ListItem', cursor=1",
      "SPEECH OUTPUT: 'list item Fruits item 1 of 2 expanded tree level 1'"]))
 
 ########################################################################
@@ -76,16 +76,16 @@ sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
 sequence.append(utils.AssertPresentationAction(
     "arrow to apples", 
-    ["BRAILLE LINE:  'Apples ListItem'",
-     "     VISIBLE:  'Apples ListItem', cursor=1",
+    ["BRAILLE LINE:  'Apples collapsed ListItem'",
+     "     VISIBLE:  'Apples collapsed ListItem', cursor=1",
      "SPEECH OUTPUT: 'Apples collapsed'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Right"))
 sequence.append(utils.AssertPresentationAction(
     "expand apples", 
-    ["BRAILLE LINE:  'Apples ListItem'",
-     "     VISIBLE:  'Apples ListItem', cursor=1",
+    ["BRAILLE LINE:  'Apples expanded ListItem'",
+     "     VISIBLE:  'Apples expanded ListItem', cursor=1",
      "SPEECH OUTPUT: 'expanded'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -100,16 +100,16 @@ sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
 sequence.append(utils.AssertPresentationAction(
     "arrow to granny smith", 
-    ["BRAILLE LINE:  'Granny Smith ListItem'",
-     "     VISIBLE:  'Granny Smith ListItem', cursor=1",
+    ["BRAILLE LINE:  'Granny Smith collapsed ListItem'",
+     "     VISIBLE:  'Granny Smith collapsed ListItem', cursor=1",
      "SPEECH OUTPUT: 'Granny Smith collapsed'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Right"))
 sequence.append(utils.AssertPresentationAction(
     "expand granny smith", 
-    ["BRAILLE LINE:  'Granny Smith ListItem'",
-     "     VISIBLE:  'Granny Smith ListItem', cursor=1",
+    ["BRAILLE LINE:  'Granny Smith expanded ListItem'",
+     "     VISIBLE:  'Granny Smith expanded ListItem', cursor=1",
      "SPEECH OUTPUT: 'expanded'"]))
 
 sequence.append(utils.StartRecordingAction())
@@ -164,16 +164,16 @@ sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
 sequence.append(utils.AssertPresentationAction(
     "arrow to vegetables", 
-    ["BRAILLE LINE:  'Vegetables ListItem'",
-     "     VISIBLE:  'Vegetables ListItem', cursor=1",
+    ["BRAILLE LINE:  'Vegetables expanded ListItem'",
+     "     VISIBLE:  'Vegetables expanded ListItem', cursor=1",
      "SPEECH OUTPUT: 'Vegetables expanded tree level 1'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Left"))
 sequence.append(utils.AssertPresentationAction(
     "collapse vegetables", 
-    ["BRAILLE LINE:  'Vegetables ListItem'",
-     "     VISIBLE:  'Vegetables ListItem', cursor=1",
+    ["BRAILLE LINE:  'Vegetables collapsed ListItem'",
+     "     VISIBLE:  'Vegetables collapsed ListItem', cursor=1",
      "SPEECH OUTPUT: 'collapsed'"]))
 
 ########################################################################
diff --git a/test/keystrokes/firefox/xul_role_combo_box.py b/test/keystrokes/firefox/xul_role_combo_box.py
index 3c0945c..2254531 100644
--- a/test/keystrokes/firefox/xul_role_combo_box.py
+++ b/test/keystrokes/firefox/xul_role_combo_box.py
@@ -35,7 +35,7 @@ sequence.append(KeyComboAction("Tab"))
 sequence.append(utils.AssertPresentationAction(
     "Tab to combobox",
     ["BRAILLE LINE:  '" + utils.firefoxAppNames + " Application " + utils.firefoxAppNames + " Preferences Frame Main ScrollPane Startup Panel When " + utils.firefoxAppNames + " starts: Show a blank page Combo'",
-     "     VISIBLE:  'Show a blank page Combo', cursor=1",
+     "     VISIBLE:  'When " + utils.firefoxAppNames + " starts: Show a blan', cursor=22",
      "SPEECH OUTPUT: 'Main scroll pane Startup panel When " + utils.firefoxAppNames + " starts: Show a blank page combo box'"]))
 
 ########################################################################
@@ -46,10 +46,10 @@ sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
 sequence.append(utils.AssertPresentationAction(
     "Down Arrow in combobox",
-    ["BRAILLE LINE:  '" + utils.firefoxAppNames + " Application " + utils.firefoxAppNames + " Preferences Frame Main ScrollPane Startup Panel  ComboShow my windows and tabs from last timeWhen " + utils.firefoxAppNames + " starts:  Show a blank page'",
-     "     VISIBLE:  'Show a blank page', cursor=1",
-     "BRAILLE LINE:  '" + utils.firefoxAppNames + " Application " + utils.firefoxAppNames + " Preferences Frame Main ScrollPane Startup Panel  ComboShow my windows and tabs from last timeWhen " + utils.firefoxAppNames + " starts:  Show my windows and tabs from last time'",
-     "     VISIBLE:  'Show my windows and tabs from la', cursor=1",
+    ["BRAILLE LINE:  '" + utils.firefoxAppNames + " Application " + utils.firefoxAppNames + " Preferences Frame Main ScrollPane Startup Panel When " + utils.firefoxAppNames + " starts: Show my windows and tabs from last time Combo'",
+     "     VISIBLE:  'When " + utils.firefoxAppNames + " starts: Show my win', cursor=22",
+     "BRAILLE LINE:  '" + utils.firefoxAppNames + " Application " + utils.firefoxAppNames + " Preferences Frame Main ScrollPane Startup Panel When " + utils.firefoxAppNames + " starts: Show my windows and tabs from last time Combo'",
+     "     VISIBLE:  'When " + utils.firefoxAppNames + " starts: Show my win', cursor=22",
      "SPEECH OUTPUT: 'Show a blank page'",
      "SPEECH OUTPUT: 'Show my windows and tabs from last time'"]))
 
@@ -60,8 +60,8 @@ sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
 sequence.append(utils.AssertPresentationAction(
     "Down Arrow in combobox",
-    ["BRAILLE LINE:  '" + utils.firefoxAppNames + " Application " + utils.firefoxAppNames + " Preferences Frame Main ScrollPane Startup Panel  ComboShow my home pageWhen " + utils.firefoxAppNames + " starts:  Show my home page'",
-     "     VISIBLE:  'Show my home page', cursor=1",
+    ["BRAILLE LINE:  '" + utils.firefoxAppNames + " Application " + utils.firefoxAppNames + " Preferences Frame Main ScrollPane Startup Panel When " + utils.firefoxAppNames + " starts: Show my home page Combo'",
+     "     VISIBLE:  'When " + utils.firefoxAppNames + " starts: Show my hom', cursor=22",
      "SPEECH OUTPUT: 'Show my home page'"]))
 
 ########################################################################
@@ -71,8 +71,8 @@ sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
 sequence.append(utils.AssertPresentationAction(
     "Up Arrow in combobox",
-    ["BRAILLE LINE:  '" + utils.firefoxAppNames + " Application " + utils.firefoxAppNames + " Preferences Frame Main ScrollPane Startup Panel  ComboShow my windows and tabs from last timeWhen " + utils.firefoxAppNames + " starts:  Show my windows and tabs from last time'",
-     "     VISIBLE:  'Show my windows and tabs from la', cursor=1",
+    ["BRAILLE LINE:  '" + utils.firefoxAppNames + " Application " + utils.firefoxAppNames + " Preferences Frame Main ScrollPane Startup Panel When " + utils.firefoxAppNames + " starts: Show my windows and tabs from last time Combo'",
+     "     VISIBLE:  'When " + utils.firefoxAppNames + " starts: Show my win', cursor=22",
      "SPEECH OUTPUT: 'Show my windows and tabs from last time'"]))
 
 ########################################################################
@@ -82,8 +82,8 @@ sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
 sequence.append(utils.AssertPresentationAction(
     "Up Arrow in combobox",
-    ["BRAILLE LINE:  '" + utils.firefoxAppNames + " Application " + utils.firefoxAppNames + " Preferences Frame Main ScrollPane Startup Panel  ComboShow a blank pageWhen " + utils.firefoxAppNames + " starts:  Show a blank page'",
-     "     VISIBLE:  'Show a blank page', cursor=1",
+    ["BRAILLE LINE:  '" + utils.firefoxAppNames + " Application " + utils.firefoxAppNames + " Preferences Frame Main ScrollPane Startup Panel When " + utils.firefoxAppNames + " starts: Show a blank page Combo'",
+     "     VISIBLE:  'When " + utils.firefoxAppNames + " starts: Show a blan', cursor=22",
      "SPEECH OUTPUT: 'Show a blank page'"]))
 
 ########################################################################
@@ -103,7 +103,7 @@ sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
 sequence.append(utils.AssertPresentationAction(
     "Down Arrow in expanded combobox",
-    ["BRAILLE LINE:  '" + utils.firefoxAppNames + " Application " + utils.firefoxAppNames + " Preferences Frame Main ScrollPane Startup Panel  ComboShow a blank pageWhen " + utils.firefoxAppNames + " starts:  Show my windows and tabs from last time'",
+    ["BRAILLE LINE:  '" + utils.firefoxAppNames + " Application " + utils.firefoxAppNames + " Preferences Frame Main ScrollPane Startup Panel When " + utils.firefoxAppNames + " starts: Show a blank page Combo Show my windows and tabs from last time'",
      "     VISIBLE:  'Show my windows and tabs from la', cursor=1",
      "SPEECH OUTPUT: 'Show my windows and tabs from last time'"]))
 
@@ -114,7 +114,7 @@ sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
 sequence.append(utils.AssertPresentationAction(
     "Up Arrow in expanded combobox",
-    ["BRAILLE LINE:  '" + utils.firefoxAppNames + " Application " + utils.firefoxAppNames + " Preferences Frame Main ScrollPane Startup Panel  ComboShow a blank pageWhen " + utils.firefoxAppNames + " starts:  Show a blank page'",
+    ["BRAILLE LINE:  '" + utils.firefoxAppNames + " Application " + utils.firefoxAppNames + " Preferences Frame Main ScrollPane Startup Panel When " + utils.firefoxAppNames + " starts: Show a blank page Combo Show a blank page'",
      "     VISIBLE:  'Show a blank page', cursor=1",
      "SPEECH OUTPUT: 'Show a blank page'"]))
 
@@ -126,7 +126,7 @@ sequence.append(KeyComboAction("Return"))
 sequence.append(utils.AssertPresentationAction(
     "Return to collapse combobox",
     ["BRAILLE LINE:  '" + utils.firefoxAppNames + " Application " + utils.firefoxAppNames + " Preferences Frame Main ScrollPane Startup Panel When " + utils.firefoxAppNames + " starts: Show a blank page Combo'",
-     "     VISIBLE:  'Show a blank page Combo', cursor=1",
+     "     VISIBLE:  'When " + utils.firefoxAppNames + " starts: Show a blan', cursor=22",
      "SPEECH OUTPUT: '" + utils.firefoxAppNames + " application " + utils.firefoxAppNames + " Preferences frame Main scroll pane Startup panel When " + utils.firefoxAppNames + " starts: Show a blank page combo box'"]))
 
 ########################################################################
@@ -136,10 +136,10 @@ sequence.append(utils.StartRecordingAction())
 sequence.append(TypeAction("s"))
 sequence.append(utils.AssertPresentationAction(
     "First letter navigation with s",
-    ["BRAILLE LINE:  '" + utils.firefoxAppNames + " Application " + utils.firefoxAppNames + " Preferences Frame Main ScrollPane Startup Panel  ComboShow my home pageWhen " + utils.firefoxAppNames + " starts:  Show a blank page'",
-     "     VISIBLE:  'Show a blank page', cursor=1",
-     "BRAILLE LINE:  '" + utils.firefoxAppNames + " Application " + utils.firefoxAppNames + " Preferences Frame Main ScrollPane Startup Panel  ComboShow my home pageWhen " + utils.firefoxAppNames + " starts:  Show my home page'",
-     "     VISIBLE:  'Show my home page', cursor=1",
+    ["BRAILLE LINE:  '" + utils.firefoxAppNames + " Application " + utils.firefoxAppNames + " Preferences Frame Main ScrollPane Startup Panel When " + utils.firefoxAppNames + " starts: Show my home page Combo'",
+     "     VISIBLE:  'When " + utils.firefoxAppNames + " starts: Show my hom', cursor=22",
+     "BRAILLE LINE:  '" + utils.firefoxAppNames + " Application " + utils.firefoxAppNames + " Preferences Frame Main ScrollPane Startup Panel When " + utils.firefoxAppNames + " starts: Show my home page Combo'",
+     "     VISIBLE:  'When " + utils.firefoxAppNames + " starts: Show my hom', cursor=22",
      "SPEECH OUTPUT: 'Show a blank page'",
      "SPEECH OUTPUT: 'Show my home page'"]))
 
@@ -147,8 +147,8 @@ sequence.append(utils.StartRecordingAction())
 sequence.append(TypeAction("s"))
 sequence.append(utils.AssertPresentationAction(
     "First letter navigation with s",
-    ["BRAILLE LINE:  '" + utils.firefoxAppNames + " Application " + utils.firefoxAppNames + " Preferences Frame Main ScrollPane Startup Panel  ComboShow a blank pageWhen " + utils.firefoxAppNames + " starts:  Show a blank page'",
-     "     VISIBLE:  'Show a blank page', cursor=1",
+    ["BRAILLE LINE:  '" + utils.firefoxAppNames + " Application " + utils.firefoxAppNames + " Preferences Frame Main ScrollPane Startup Panel When " + utils.firefoxAppNames + " starts: Show a blank page Combo'",
+     "     VISIBLE:  'When " + utils.firefoxAppNames + " starts: Show a blan', cursor=22",
      "SPEECH OUTPUT: 'Show a blank page'"]))
 
 ########################################################################
@@ -160,8 +160,8 @@ sequence.append(PauseAction(3000))
 sequence.append(utils.AssertPresentationAction(
     "Basic Where Am I", 
     ["BUG? - We claim this is item 1 of 1. This is how it was before the refactor as well.",
-     "BRAILLE LINE:  '" + utils.firefoxAppNames + " Application " + utils.firefoxAppNames + " Preferences Frame Main ScrollPane Startup Panel  ComboShow a blank pageWhen " + utils.firefoxAppNames + " starts:  Show a blank page'",
-     "     VISIBLE:  'Show a blank page', cursor=1",
+     "BRAILLE LINE:  '" + utils.firefoxAppNames + " Application " + utils.firefoxAppNames + " Preferences Frame Main ScrollPane Startup Panel When " + utils.firefoxAppNames + " starts: Show a blank page Combo'",
+     "     VISIBLE:  'When " + utils.firefoxAppNames + " starts: Show a blan', cursor=22",
      "SPEECH OUTPUT: 'When " + utils.firefoxAppNames + " starts: combo box Show a blank page item 1 of 1'"]))
 
 ########################################################################
diff --git a/test/keystrokes/firefox/xul_role_radio_button.py b/test/keystrokes/firefox/xul_role_radio_button.py
index f451442..4f2686a 100755
--- a/test/keystrokes/firefox/xul_role_radio_button.py
+++ b/test/keystrokes/firefox/xul_role_radio_button.py
@@ -29,7 +29,7 @@ sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("<Alt>a"))
 sequence.append(utils.AssertPresentationAction(
     "Alt a to radio button group",
-    ["BRAILLE LINE:  '" + utils.firefoxAppNames + " Application Print Dialog TabList General Page Range Filler &=y All Pages RadioButton'",
+    ["BRAILLE LINE:  '" + utils.firefoxAppNames + " Application Print Dialog TabList General Page Range &=y All Pages RadioButton'",
      "     VISIBLE:  '&=y All Pages RadioButton', cursor=1",
      "SPEECH OUTPUT: 'Range All Pages selected radio button'"]))
 
@@ -41,7 +41,7 @@ sequence.append(KeyComboAction("KP_Enter"))
 sequence.append(PauseAction(3000))
 sequence.append(utils.AssertPresentationAction(
     "Basic Where Am I", 
-    ["BRAILLE LINE:  '" + utils.firefoxAppNames + " Application Print Dialog TabList General Page Range Filler &=y All Pages RadioButton'",
+    ["BRAILLE LINE:  '" + utils.firefoxAppNames + " Application Print Dialog TabList General Page Range &=y All Pages RadioButton'",
      "     VISIBLE:  '&=y All Pages RadioButton', cursor=1",
      "SPEECH OUTPUT: 'Range All Pages radio button selected item 1 of 3.'",
      "SPEECH OUTPUT: 'Alt a'"]))
@@ -53,7 +53,7 @@ sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
 sequence.append(utils.AssertPresentationAction(
     "Down Arrow to next radio button",
-    ["BRAILLE LINE:  '" + utils.firefoxAppNames + " Application Print Dialog TabList General Page Range Filler & y Pages: RadioButton'",
+    ["BRAILLE LINE:  '" + utils.firefoxAppNames + " Application Print Dialog TabList General Page Range & y Pages: RadioButton'",
      "     VISIBLE:  '& y Pages: RadioButton', cursor=1",
      "SPEECH OUTPUT: 'Pages: not selected radio button'"]))
 
@@ -65,7 +65,7 @@ sequence.append(KeyComboAction("KP_Enter"))
 sequence.append(PauseAction(3000))
 sequence.append(utils.AssertPresentationAction(
     "Basic Where Am I", 
-    ["BRAILLE LINE:  '" + utils.firefoxAppNames + " Application Print Dialog TabList General Page Range Filler &=y Pages: RadioButton'",
+    ["BRAILLE LINE:  '" + utils.firefoxAppNames + " Application Print Dialog TabList General Page Range &=y Pages: RadioButton'",
      "     VISIBLE:  '&=y Pages: RadioButton', cursor=1",
      "SPEECH OUTPUT: 'Range Pages: radio button selected item 3 of 3.'",
      "SPEECH OUTPUT: 'Alt e'"]))
diff --git a/test/keystrokes/firefox/xul_role_tree.py b/test/keystrokes/firefox/xul_role_tree.py
index 2bfac99..8ed44f6 100644
--- a/test/keystrokes/firefox/xul_role_tree.py
+++ b/test/keystrokes/firefox/xul_role_tree.py
@@ -30,15 +30,17 @@ sequence.append(utils.AssertPresentationAction(
      "SPEECH OUTPUT: 'Bookmarks menu'",
      "SPEECH OUTPUT: 'Bookmark This Page Control D'"]))
 
+# Firefox 3.5 introduces a shortcut (Control Shift O) that was not present
+# in earlier versions.
+#
 sequence.append(PauseAction(3000))
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
 sequence.append(utils.AssertPresentationAction(
     "Down Arrow in Bookmarks menu",
-    ["BRAILLE LINE:  '" + utils.firefoxAppNames + " Application " + utils.firefoxFrameNames + " Frame ToolBar Application MenuBar Organize Bookmarks...'",
-     "     VISIBLE:  'Organize Bookmarks...', cursor=1",
-     "SPEECH OUTPUT: 'Organize Bookmarksâ?¦'"]))
-
+    ["BRAILLE LINE:  '" + utils.firefoxAppNames + " Application " + utils.firefoxFrameNames + " Frame ToolBar Application MenuBar Organize Bookmarks...(\(Control Shift O\)|)'",
+     "     VISIBLE:  'Organize Bookmarks...(\(Control Sh|)', cursor=1",
+     "SPEECH OUTPUT: 'Organize Bookmarksâ?¦( Control Shift O|)'"]))
 sequence.append(KeyComboAction("Return"))
 sequence.append(PauseAction(3000))
 
@@ -50,8 +52,8 @@ sequence.append(KeyComboAction("<Shift>Tab", 1000))
 sequence.append(utils.AssertPresentationAction(
     "Shift Tab for tree",
     ["BUG? - We are no longer speaking the Level",
-     "BRAILLE LINE:  '" + utils.firefoxAppNames + " Application Library Frame Tree All Bookmarks ListItem'",
-     "     VISIBLE:  'All Bookmarks ListItem', cursor=1",
+     "BRAILLE LINE:  '" + utils.firefoxAppNames + " Application Library Frame Tree All Bookmarks expanded ListItem TREE LEVEL 1'",
+     "     VISIBLE:  'All Bookmarks expanded ListItem ', cursor=1",
      "SPEECH OUTPUT: 'All Bookmarks expanded'"]))
 
 ########################################################################
@@ -61,16 +63,16 @@ sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
 sequence.append(utils.AssertPresentationAction(
     "Down Arrow in tree",
-    ["BRAILLE LINE:  '" + utils.firefoxAppNames + " Application Library Frame Tree Bookmarks Toolbar ListItem'",
-     "     VISIBLE:  'Bookmarks Toolbar ListItem', cursor=1",
+    ["BRAILLE LINE:  '" + utils.firefoxAppNames + " Application Library Frame Tree Bookmarks Toolbar collapsed ListItem TREE LEVEL 2'",
+     "     VISIBLE:  'Bookmarks Toolbar collapsed List', cursor=1",
      "SPEECH OUTPUT: 'Bookmarks Toolbar collapsed tree level 2'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
 sequence.append(utils.AssertPresentationAction(
     "Down Arrow in tree",
-    ["BRAILLE LINE:  '" + utils.firefoxAppNames + " Application Library Frame Tree Bookmarks Menu ListItem'",
-     "     VISIBLE:  'Bookmarks Menu ListItem', cursor=1",
+    ["BRAILLE LINE:  '" + utils.firefoxAppNames + " Application Library Frame Tree Bookmarks Menu collapsed ListItem TREE LEVEL 2'",
+     "     VISIBLE:  'Bookmarks Menu collapsed ListIte', cursor=1",
      "SPEECH OUTPUT: 'Bookmarks Menu collapsed'"]))
 
 ########################################################################
@@ -81,8 +83,8 @@ sequence.append(KeyComboAction("KP_Enter"))
 sequence.append(PauseAction(3000))
 sequence.append(utils.AssertPresentationAction(
     "Basic Where Am I", 
-    ["BRAILLE LINE:  '" + utils.firefoxAppNames + " Application Library Frame Tree Bookmarks Menu ListItem'",
-     "     VISIBLE:  'Bookmarks Menu ListItem', cursor=1",
+    ["BRAILLE LINE:  '" + utils.firefoxAppNames + " Application Library Frame Tree Bookmarks Menu collapsed ListItem TREE LEVEL 2'",
+     "     VISIBLE:  'Bookmarks Menu collapsed ListIte', cursor=1",
      "SPEECH OUTPUT: 'list item Bookmarks Menu item 2 of 3 collapsed tree level 2'"]))
 
 ########################################################################
@@ -92,8 +94,8 @@ sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Right"))
 sequence.append(utils.AssertPresentationAction(
     "Right Arrow to expand folder", 
-    ["BRAILLE LINE:  '" + utils.firefoxAppNames + " Application Library Frame Tree Bookmarks Menu ListItem'",
-     "     VISIBLE:  'Bookmarks Menu ListItem', cursor=1",
+    ["BRAILLE LINE:  '" + utils.firefoxAppNames + " Application Library Frame Tree Bookmarks Menu expanded ListItem TREE LEVEL 2'",
+     "     VISIBLE:  'Bookmarks Menu expanded ListItem', cursor=1",
      "SPEECH OUTPUT: 'expanded'"]))
 
 ########################################################################
@@ -104,8 +106,8 @@ sequence.append(KeyComboAction("KP_Enter"))
 sequence.append(PauseAction(3000))
 sequence.append(utils.AssertPresentationAction(
     "Basic Where Am I", 
-    ["BRAILLE LINE:  '" + utils.firefoxAppNames + " Application Library Frame Tree Bookmarks Menu ListItem'",
-     "     VISIBLE:  'Bookmarks Menu ListItem', cursor=1",
+    ["BRAILLE LINE:  '" + utils.firefoxAppNames + " Application Library Frame Tree Bookmarks Menu expanded ListItem TREE LEVEL 2'",
+     "     VISIBLE:  'Bookmarks Menu expanded ListItem', cursor=1",
      "SPEECH OUTPUT: 'list item Bookmarks Menu item 2 of 3 expanded tree level 2'"]))
 
 ########################################################################
@@ -115,8 +117,8 @@ sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
 sequence.append(utils.AssertPresentationAction(
     "Down Arrow in tree",
-    ["BRAILLE LINE:  '" + utils.firefoxAppNames + " Application Library Frame Tree Recently Bookmarked ListItem'",
-     "     VISIBLE:  'Recently Bookmarked ListItem', cursor=1",
+    ["BRAILLE LINE:  '" + utils.firefoxAppNames + " Application Library Frame Tree Recently Bookmarked ListItem TREE LEVEL 3'",
+     "     VISIBLE:  'Recently Bookmarked ListItem TRE', cursor=1",
      "SPEECH OUTPUT: 'Recently Bookmarked tree level 3'"]))
 
 ########################################################################
@@ -127,8 +129,8 @@ sequence.append(KeyComboAction("KP_Enter"))
 sequence.append(PauseAction(3000))
 sequence.append(utils.AssertPresentationAction(
     "Basic Where Am I", 
-    ["BRAILLE LINE:  '" + utils.firefoxAppNames + " Application Library Frame Tree Recently Bookmarked ListItem'",
-     "     VISIBLE:  'Recently Bookmarked ListItem', cursor=1",
+    ["BRAILLE LINE:  '" + utils.firefoxAppNames + " Application Library Frame Tree Recently Bookmarked ListItem TREE LEVEL 3'",
+     "     VISIBLE:  'Recently Bookmarked ListItem TRE', cursor=1",
      "SPEECH OUTPUT: 'list item Recently Bookmarked item 1 of 4 tree level 3'"]))
 
 ########################################################################
@@ -138,8 +140,8 @@ sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
 sequence.append(utils.AssertPresentationAction(
     "Up Arrow in tree",
-    ["BRAILLE LINE:  '" + utils.firefoxAppNames + " Application Library Frame Tree Bookmarks Menu ListItem'",
-     "     VISIBLE:  'Bookmarks Menu ListItem', cursor=1",
+    ["BRAILLE LINE:  '" + utils.firefoxAppNames + " Application Library Frame Tree Bookmarks Menu expanded ListItem TREE LEVEL 2'",
+     "     VISIBLE:  'Bookmarks Menu expanded ListItem', cursor=1",
      "SPEECH OUTPUT: 'Bookmarks Menu expanded tree level 2'"]))
 
 ########################################################################
@@ -149,8 +151,8 @@ sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Left"))
 sequence.append(utils.AssertPresentationAction(
     "Left Arrow to collapse folder", 
-    ["BRAILLE LINE:  '" + utils.firefoxAppNames + " Application Library Frame Tree Bookmarks Menu ListItem'",
-     "     VISIBLE:  'Bookmarks Menu ListItem', cursor=1",
+    ["BRAILLE LINE:  '" + utils.firefoxAppNames + " Application Library Frame Tree Bookmarks Menu collapsed ListItem TREE LEVEL 2'",
+     "     VISIBLE:  'Bookmarks Menu collapsed ListIte', cursor=1",
      "SPEECH OUTPUT: 'collapsed'"]))
 
 ########################################################################
@@ -160,16 +162,16 @@ sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
 sequence.append(utils.AssertPresentationAction(
     "Up Arrow in tree",
-    ["BRAILLE LINE:  '" + utils.firefoxAppNames + " Application Library Frame Tree Bookmarks Toolbar ListItem'",
-     "     VISIBLE:  'Bookmarks Toolbar ListItem', cursor=1",
+    ["BRAILLE LINE:  '" + utils.firefoxAppNames + " Application Library Frame Tree Bookmarks Toolbar collapsed ListItem TREE LEVEL 2'",
+     "     VISIBLE:  'Bookmarks Toolbar collapsed List', cursor=1",
      "SPEECH OUTPUT: 'Bookmarks Toolbar collapsed'"]))
 
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
 sequence.append(utils.AssertPresentationAction(
     "Up Arrow in tree",
-    ["BRAILLE LINE:  '" + utils.firefoxAppNames + " Application Library Frame Tree All Bookmarks ListItem'",
-     "     VISIBLE:  'All Bookmarks ListItem', cursor=1",
+    ["BRAILLE LINE:  '" + utils.firefoxAppNames + " Application Library Frame Tree All Bookmarks expanded ListItem TREE LEVEL 1'",
+     "     VISIBLE:  'All Bookmarks expanded ListItem ', cursor=1",
      "SPEECH OUTPUT: 'All Bookmarks expanded tree level 1'"]))
 
 ########################################################################
diff --git a/test/keystrokes/firefox/xul_role_tree_table.py b/test/keystrokes/firefox/xul_role_tree_table.py
index dfb592e..ca3d775 100644
--- a/test/keystrokes/firefox/xul_role_tree_table.py
+++ b/test/keystrokes/firefox/xul_role_tree_table.py
@@ -30,15 +30,17 @@ sequence.append(utils.AssertPresentationAction(
      "SPEECH OUTPUT: 'Bookmarks menu'",
      "SPEECH OUTPUT: 'Bookmark This Page Control D'"]))
 
+# Firefox 3.5 introduces a shortcut (Control Shift O) that was not present
+# in earlier versions.
+#
 sequence.append(PauseAction(3000))
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
 sequence.append(utils.AssertPresentationAction(
     "Down Arrow in Bookmarks menu",
-    ["BRAILLE LINE:  '" + utils.firefoxAppNames + " Application " + utils.firefoxFrameNames + " Frame ToolBar Application MenuBar Organize Bookmarks...'",
-     "     VISIBLE:  'Organize Bookmarks...', cursor=1",
-     "SPEECH OUTPUT: 'Organize Bookmarksâ?¦'"]))
-
+    ["BRAILLE LINE:  '" + utils.firefoxAppNames + " Application " + utils.firefoxFrameNames + " Frame ToolBar Application MenuBar Organize Bookmarks...(\(Control Shift O\)|)'",
+     "     VISIBLE:  'Organize Bookmarks...(\(Control Sh|)', cursor=1",
+     "SPEECH OUTPUT: 'Organize Bookmarksâ?¦( Control Shift O|)'"]))
 sequence.append(KeyComboAction("Return"))
 sequence.append(PauseAction(3000))
 
@@ -61,8 +63,8 @@ sequence.append(KeyComboAction("KP_Enter"))
 sequence.append(PauseAction(3000))
 sequence.append(utils.AssertPresentationAction(
     "Basic Where Am I", 
-    ["BRAILLE LINE:  '" + utils.firefoxAppNames + " Application Library Frame ScrollPane TreeTable Name ColumnHeader Bookmarks Menu TREE LEVEL 1'",
-     "     VISIBLE:  'Bookmarks Menu TREE LEVEL 1', cursor=1",
+    ["BRAILLE LINE:  '" + utils.firefoxAppNames + " Application Library Frame ScrollPane TreeTable Name ColumnHeader Bookmarks Menu   TREE LEVEL 1'",
+     "     VISIBLE:  'Bookmarks Menu   TREE LEVEL 1', cursor=1",
      "SPEECH OUTPUT: 'tree table Name cell Bookmarks Menu column 1 of 3 row 2 of 3 tree level 1'"]))
 
 ########################################################################
diff --git a/test/keystrokes/gtk-demo/role_column_header.py b/test/keystrokes/gtk-demo/role_column_header.py
index 168a3b9..e66ab95 100644
--- a/test/keystrokes/gtk-demo/role_column_header.py
+++ b/test/keystrokes/gtk-demo/role_column_header.py
@@ -91,8 +91,8 @@ sequence.append(WaitAction("object:active-descendant-changed",
                            5000))
 sequence.append(utils.AssertPresentationAction(
     "Normal cell",
-    ["BRAILLE LINE:  'gtk-demo Application GtkListStore demo Frame ScrollPane Table Severity ColumnHeader Normal'",
-     "     VISIBLE:  'Normal', cursor=1",
+    ["BRAILLE LINE:  'gtk-demo Application GtkListStore demo Frame ScrollPane Table Severity ColumnHeader < > Fixed? 60482 Normal scrollable notebooks and hidden tabs'",
+     "     VISIBLE:  'Normal scrollable notebooks and ', cursor=1",
      "SPEECH OUTPUT: 'Severity column header Normal'"]))
 
 ########################################################################
@@ -148,8 +148,8 @@ sequence.append(WaitAction("object:active-descendant-changed",
                            5000))
 sequence.append(utils.AssertPresentationAction(
     "60482 cell",
-    ["BRAILLE LINE:  'gtk-demo Application GtkListStore demo Frame ScrollPane Table Bug number ColumnHeader 60482'",
-     "     VISIBLE:  '60482', cursor=1",
+    ["BRAILLE LINE:  'gtk-demo Application GtkListStore demo Frame ScrollPane Table Bug number ColumnHeader < > Fixed? 60482 Normal scrollable notebooks and hidden tabs'",
+     "     VISIBLE:  '60482 Normal scrollable notebook', cursor=1",
      "SPEECH OUTPUT: 'Bug number column header 60482'"]))
 
 ########################################################################
@@ -164,8 +164,8 @@ sequence.append(WaitAction("object:active-descendant-changed",
                            5000))
 sequence.append(utils.AssertPresentationAction(
     "Checkbox cell",
-    ["BRAILLE LINE:  'gtk-demo Application GtkListStore demo Frame ScrollPane Table Fixed? ColumnHeader < > Fixed?'",
-     "     VISIBLE:  '< > Fixed?', cursor=1",
+    ["BRAILLE LINE:  'gtk-demo Application GtkListStore demo Frame ScrollPane Table Fixed? ColumnHeader < > Fixed? 60482 Normal scrollable notebooks and hidden tabs'",
+     "     VISIBLE:  '< > Fixed? 60482 Normal scrollab', cursor=1",
      "SPEECH OUTPUT: 'Fixed? column header check box not checked'"]))
 
 ########################################################################
diff --git a/test/keystrokes/gtk-demo/role_combo_box.py b/test/keystrokes/gtk-demo/role_combo_box.py
index dfc1a04..d7a7348 100644
--- a/test/keystrokes/gtk-demo/role_combo_box.py
+++ b/test/keystrokes/gtk-demo/role_combo_box.py
@@ -265,7 +265,7 @@ sequence.append(utils.AssertPresentationAction(
      "     VISIBLE:  'Combo boxes Frame', cursor=1",
      "BRAILLE LINE:  'gtk-demo Application Combo boxes Frame Editable Panel Two Combo'",
      "     VISIBLE:  'Two Combo', cursor=1",
-     "SPEECH OUTPUT: 'Combo boxes frame",
+     "SPEECH OUTPUT: 'Combo boxes frame'",
      "SPEECH OUTPUT: 'Editable panel Two combo box'"]))
 
 sequence.append(KeyComboAction("<Shift>ISO_Left_Tab"))
diff --git a/test/keystrokes/gtk-demo/role_combo_box2.py b/test/keystrokes/gtk-demo/role_combo_box2.py
index 2e09b96..c789627 100644
--- a/test/keystrokes/gtk-demo/role_combo_box2.py
+++ b/test/keystrokes/gtk-demo/role_combo_box2.py
@@ -39,7 +39,7 @@ sequence.append(WaitForFocus("All sheets", acc_role=pyatspi.ROLE_COMBO_BOX))
 sequence.append(utils.AssertPresentationAction(
     "All sheets combo box item",
     ["BRAILLE LINE:  'gtk-demo Application Print Dialog TabList Page Setup Page Layout Filler Only print: All sheets Combo'",
-     "     VISIBLE:  'All sheets Combo', cursor=1",
+     "     VISIBLE:  'Only print: All sheets Combo', cursor=13",
      "SPEECH OUTPUT: 'Layout Only print: All sheets combo box'"]))
 
 ########################################################################
@@ -51,8 +51,8 @@ sequence.append(PauseAction(3000))
 sequence.append(utils.AssertPresentationAction(
     "All sheets combo box item Where Am I",
     ["BRAILLE LINE:  'gtk-demo Application Print Dialog TabList Page Setup Page Layout Filler Only print: All sheets Combo'",
-     "     VISIBLE:  'All sheets Combo', cursor=1",
-     "SPEECH OUTPUT: 'Only print: combo box All sheets item 1 of 3.",
+     "     VISIBLE:  'Only print: All sheets Combo', cursor=13",
+     "SPEECH OUTPUT: 'Only print: combo box All sheets item 1 of 3.'",
      "SPEECH OUTPUT: 'Alt o'"]))
 
 ########################################################################
@@ -68,7 +68,7 @@ sequence.append(WaitAction("object:selection-changed",
 sequence.append(utils.AssertPresentationAction(
     "Event sheets combo box item",
     ["BRAILLE LINE:  'gtk-demo Application Print Dialog TabList Page Setup Page Layout Filler Only print: Even sheets Combo'",
-     "     VISIBLE:  'Even sheets Combo', cursor=1",
+     "     VISIBLE:  'Only print: Even sheets Combo', cursor=13",
      "SPEECH OUTPUT: 'Even sheets'"]))
 
 ########################################################################
@@ -80,8 +80,8 @@ sequence.append(PauseAction(3000))
 sequence.append(utils.AssertPresentationAction(
     "Even sheets combo box item Where Am I",
     ["BRAILLE LINE:  'gtk-demo Application Print Dialog TabList Page Setup Page Layout Filler Only print: Even sheets Combo'",
-     "     VISIBLE:  'Even sheets Combo', cursor=1",
-     "SPEECH OUTPUT: 'Only print: combo box Even sheets item 2 of 3.",
+     "     VISIBLE:  'Only print: Even sheets Combo', cursor=13",
+     "SPEECH OUTPUT: 'Only print: combo box Even sheets item 2 of 3.'",
      "SPEECH OUTPUT: 'Alt o'"]))
 
 ########################################################################
diff --git a/test/keystrokes/gtk-demo/role_radio_button.py b/test/keystrokes/gtk-demo/role_radio_button.py
index 2b5d929..5fadb14 100644
--- a/test/keystrokes/gtk-demo/role_radio_button.py
+++ b/test/keystrokes/gtk-demo/role_radio_button.py
@@ -33,7 +33,7 @@ sequence.append(KeyComboAction("<Alt>a", 500))
 sequence.append(WaitForFocus("All Pages", acc_role=pyatspi.ROLE_RADIO_BUTTON))
 sequence.append(utils.AssertPresentationAction(
     "All Pages radio button",
-    ["BRAILLE LINE:  'gtk-demo Application Print Dialog TabList General Page Range Filler &=y All Pages RadioButton'",
+    ["BRAILLE LINE:  'gtk-demo Application Print Dialog TabList General Page Range &=y All Pages RadioButton'",
      "     VISIBLE:  '&=y All Pages RadioButton', cursor=1",
      "SPEECH OUTPUT: 'Range All Pages selected radio button'"]))
 
@@ -45,9 +45,9 @@ sequence.append(KeyComboAction("KP_Enter"))
 sequence.append(PauseAction(3000))
 sequence.append(utils.AssertPresentationAction(
     "All Pages radio button Where Am I",
-    ["BRAILLE LINE:  'gtk-demo Application Print Dialog TabList General Page Range Filler &=y All Pages RadioButton'",
+    ["BRAILLE LINE:  'gtk-demo Application Print Dialog TabList General Page Range &=y All Pages RadioButton'",
      "     VISIBLE:  '&=y All Pages RadioButton', cursor=1",
-     "SPEECH OUTPUT: 'Range All Pages radio button selected item 1 of 3.",
+     "SPEECH OUTPUT: 'Range All Pages radio button selected item 1 of 3.'",
      "SPEECH OUTPUT: 'Alt a'"]))
 
 ########################################################################
@@ -67,7 +67,7 @@ sequence.append(WaitForFocus("Pages:", acc_role=pyatspi.ROLE_RADIO_BUTTON))
 sequence.append(utils.AssertPresentationAction(
     "Range radio button",
     ["KNOWN ISSUE - the radio button should be presented as selected.",
-     "BRAILLE LINE:  'gtk-demo Application Print Dialog TabList General Page Range Filler & y Pages: RadioButton'",
+     "BRAILLE LINE:  'gtk-demo Application Print Dialog TabList General Page Range & y Pages: RadioButton'",
      "     VISIBLE:  '& y Pages: RadioButton', cursor=1",
      "SPEECH OUTPUT: 'Pages: not selected radio button'"]))
 
@@ -79,9 +79,9 @@ sequence.append(KeyComboAction("KP_Enter"))
 sequence.append(PauseAction(3000))
 sequence.append(utils.AssertPresentationAction(
     "Range radio button Where Am I",
-    ["BRAILLE LINE:  'gtk-demo Application Print Dialog TabList General Page Range Filler &=y Pages: RadioButton'",
+    ["BRAILLE LINE:  'gtk-demo Application Print Dialog TabList General Page Range &=y Pages: RadioButton'",
      "     VISIBLE:  '&=y Pages: RadioButton', cursor=1",
-     "SPEECH OUTPUT: 'Range Pages: radio button selected item 3 of 3.",
+     "SPEECH OUTPUT: 'Range Pages: radio button selected item 3 of 3.'",
      "SPEECH OUTPUT: 'Alt e'"]))
 
 ########################################################################
@@ -93,7 +93,7 @@ sequence.append(WaitForFocus("All Pages", acc_role=pyatspi.ROLE_RADIO_BUTTON))
 sequence.append(utils.AssertPresentationAction(
     "All Pages radio button",
     ["KNOWN ISSUE - the radio button should be presented as selected.",
-     "BRAILLE LINE:  'gtk-demo Application Print Dialog TabList General Page Range Filler & y All Pages RadioButton'",
+     "BRAILLE LINE:  'gtk-demo Application Print Dialog TabList General Page Range & y All Pages RadioButton'",
      "     VISIBLE:  '& y All Pages RadioButton', cursor=1",
      "SPEECH OUTPUT: 'All Pages not selected radio button'"]))
 
diff --git a/test/keystrokes/gtk-demo/role_spin_button.py b/test/keystrokes/gtk-demo/role_spin_button.py
index 6245e04..122f227 100644
--- a/test/keystrokes/gtk-demo/role_spin_button.py
+++ b/test/keystrokes/gtk-demo/role_spin_button.py
@@ -62,7 +62,7 @@ sequence.append(utils.AssertPresentationAction(
     "Hue spin button Where Am I",
     ["BRAILLE LINE:  'gtk-demo Application Changing color ColorChooser ColorChooser Hue: 240 $l'",
      "     VISIBLE:  'Hue: 240 $l', cursor=9",
-     "SPEECH OUTPUT: 'Hue: spin button 240 selected.",
+     "SPEECH OUTPUT: 'Hue: spin button 240 selected.'",
      "SPEECH OUTPUT: 'Alt h'"]))
 
 ########################################################################
@@ -133,7 +133,7 @@ sequence.append(utils.AssertPresentationAction(
     "Hue spin button caret navigation",
     ["BRAILLE LINE:  'gtk-demo Application Changing color ColorChooser ColorChooser Hue: 240 $l'",
      "     VISIBLE:  'Hue: 240 $l', cursor=7",
-     "SPEECH OUTPUT: 'Hue: spin button 240.",
+     "SPEECH OUTPUT: 'Hue: spin button 240.'",
      "SPEECH OUTPUT: 'Alt h'"]))
 
 ########################################################################
diff --git a/test/keystrokes/gtk-demo/role_table.py b/test/keystrokes/gtk-demo/role_table.py
index f91c999..4849bf2 100644
--- a/test/keystrokes/gtk-demo/role_table.py
+++ b/test/keystrokes/gtk-demo/role_table.py
@@ -107,8 +107,8 @@ sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("KP_Enter"))
 sequence.append(utils.AssertPresentationAction(
     "Table Where Am I (again)",
-    ["BRAILLE LINE:  'gtk-demo Application Shopping list Frame ScrollPane Table Number ColumnHeader 5'",
-     "     VISIBLE:  '5', cursor=1",
+    ["BRAILLE LINE:  'gtk-demo Application Shopping list Frame ScrollPane Table Number ColumnHeader 5 packages of noodles[ ]*'",
+     "     VISIBLE:  '5 packages of noodles[ ]*', cursor=1",
      "SPEECH OUTPUT: 'table Number cell 5 column 1 of 3 row 2 of 5'"]))
 
 ########################################################################
diff --git a/test/keystrokes/gtk-demo/role_tree_table.py b/test/keystrokes/gtk-demo/role_tree_table.py
index 9893218..86c23b1 100644
--- a/test/keystrokes/gtk-demo/role_tree_table.py
+++ b/test/keystrokes/gtk-demo/role_tree_table.py
@@ -220,8 +220,8 @@ sequence.append(KeyComboAction("KP_Enter"))
 sequence.append(PauseAction(3000))
 sequence.append(utils.AssertPresentationAction(
     "Alex checkbox cell basic Where Am I",
-    ["BRAILLE LINE:  'gtk-demo Application Card planning sheet Frame ScrollPane TreeTable Alex ColumnHeader <x> Alex'",
-     "     VISIBLE:  '<x> Alex', cursor=1",
+    ["BRAILLE LINE:  'gtk-demo Application Card planning sheet Frame ScrollPane TreeTable Alex ColumnHeader New Years Day <x> Alex <x> Havoc <x> Tim <x> Owen < > Dave'",
+     "     VISIBLE:  '<x> Alex <x> Havoc <x> Tim <x> O', cursor=1",
      "SPEECH OUTPUT: 'tree table Alex cell check box checked column 2 of 6 row 2 of 53'"]))
 
 ########################################################################
@@ -233,10 +233,10 @@ sequence.append(KeyComboAction("KP_Enter"))
 sequence.append(PauseAction(3000))
 sequence.append(utils.AssertPresentationAction(
     "Alex checkbox cell detailed Where Am I",
-    ["BRAILLE LINE:  'gtk-demo Application Card planning sheet Frame ScrollPane TreeTable Alex ColumnHeader <x> Alex'",
-     "     VISIBLE:  '<x> Alex', cursor=1",
-     "BRAILLE LINE:  'gtk-demo Application Card planning sheet Frame ScrollPane TreeTable Alex ColumnHeader <x> Alex'",
-     "     VISIBLE:  '<x> Alex', cursor=1",
+    ["BRAILLE LINE:  'gtk-demo Application Card planning sheet Frame ScrollPane TreeTable Alex ColumnHeader New Years Day <x> Alex <x> Havoc <x> Tim <x> Owen < > Dave'",
+     "     VISIBLE:  '<x> Alex <x> Havoc <x> Tim <x> O', cursor=1",
+     "BRAILLE LINE:  'gtk-demo Application Card planning sheet Frame ScrollPane TreeTable Alex ColumnHeader New Years Day <x> Alex <x> Havoc <x> Tim <x> Owen < > Dave'",
+     "     VISIBLE:  '<x> Alex <x> Havoc <x> Tim <x> O', cursor=1",
      "SPEECH OUTPUT: 'tree table Alex cell check box checked column 2 of 6 row 2 of 53'",
      "SPEECH OUTPUT: 'tree table Alex cell check box checked column 2 of 6 row 2 of 53 New Years Day Alex check box checked Havoc check box checked Tim check box checked Owen check box checked Dave check box not checked'"]))
 
@@ -252,8 +252,8 @@ sequence.append(WaitAction("object:state-changed:checked",
                            5000))
 sequence.append(utils.AssertPresentationAction(
     "Alex checkbox cell unchecked",
-    ["BRAILLE LINE:  'gtk-demo Application Card planning sheet Frame ScrollPane TreeTable Alex ColumnHeader < > Alex'",
-     "     VISIBLE:  '< > Alex', cursor=1",
+    ["BRAILLE LINE:  'gtk-demo Application Card planning sheet Frame ScrollPane TreeTable Alex ColumnHeader New Years Day < > Alex <x> Havoc <x> Tim <x> Owen < > Dave'",
+     "     VISIBLE:  '< > Alex <x> Havoc <x> Tim <x> O', cursor=1",
      "SPEECH OUTPUT: 'not checked'"]))
 
 ########################################################################
@@ -268,8 +268,8 @@ sequence.append(WaitAction("object:state-changed:checked",
                            5000))
 sequence.append(utils.AssertPresentationAction(
     "Alex checkbox cell checked",
-    ["BRAILLE LINE:  'gtk-demo Application Card planning sheet Frame ScrollPane TreeTable Alex ColumnHeader <x> Alex'",
-     "     VISIBLE:  '<x> Alex', cursor=1",
+    ["BRAILLE LINE:  'gtk-demo Application Card planning sheet Frame ScrollPane TreeTable Alex ColumnHeader New Years Day <x> Alex <x> Havoc <x> Tim <x> Owen < > Dave'",
+     "     VISIBLE:  '<x> Alex <x> Havoc <x> Tim <x> O', cursor=1",
      "SPEECH OUTPUT: 'checked'"]))
 
 ########################################################################
diff --git a/test/keystrokes/oocalc/bug_361167.py b/test/keystrokes/oocalc/bug_361167.py
index 497df1c..3611a87 100644
--- a/test/keystrokes/oocalc/bug_361167.py
+++ b/test/keystrokes/oocalc/bug_361167.py
@@ -66,7 +66,7 @@ sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
 sequence.append(utils.AssertPresentationAction(
     "Down Arrow to cell A2",
-    ["BRAILLE LINE:  'soffice Application fruit(.ods|) - " + utils.getOOoName("Calc") + " Frame fruit(.ods|) - " + utils.getOOoName("Calc") + " RootPane ScrollPane Document view3 Sheet Sheet1 Table  Good in Pies Good in Pies Cell A2 '",
+    ["BRAILLE LINE:  'soffice Application fruit(.ods|) - " + utils.getOOoName("Calc") + " Frame fruit(.ods|) - " + utils.getOOoName("Calc") + " RootPane ScrollPane Document view3 Sheet Sheet1 Table Good in Pies Good in Pies Cell A2 '",
      "     VISIBLE:  'Good in Pies Cell A2 ', cursor=1",
      "SPEECH OUTPUT: 'Good in Pies Good in Pies A2'"]))
 
@@ -77,7 +77,7 @@ sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Right"))
 sequence.append(utils.AssertPresentationAction(
     "Right Arrow to cell B2",
-    ["BRAILLE LINE:  'soffice Application fruit(.ods|) - " + utils.getOOoName("Calc") + " Frame fruit(.ods|) - " + utils.getOOoName("Calc") + " RootPane ScrollPane Document view3 Sheet Sheet1 Table  Apples Yes Cell B2 '",
+    ["BRAILLE LINE:  'soffice Application fruit(.ods|) - " + utils.getOOoName("Calc") + " Frame fruit(.ods|) - " + utils.getOOoName("Calc") + " RootPane ScrollPane Document view3 Sheet Sheet1 Table Good in Pies Apples Yes Cell B2 '",
      "     VISIBLE:  'Yes Cell B2 ', cursor=1",
      "SPEECH OUTPUT: 'Apples Yes B2'"]))
 
@@ -89,7 +89,7 @@ sequence.append(KeyComboAction("KP_Enter"))
 sequence.append(PauseAction(3000))
 sequence.append(utils.AssertPresentationAction(
     "Basic where am I with dynamic headers set B2", 
-    ["BRAILLE LINE:  'soffice Application fruit(.ods|) - " + utils.getOOoName("Calc") + " Frame fruit(.ods|) - " + utils.getOOoName("Calc") + " RootPane ScrollPane Document view3 Sheet Sheet1 Table Yes Cell B2 '",
+    ["BRAILLE LINE:  'soffice Application fruit(.ods|) - " + utils.getOOoName("Calc") + " Frame fruit(.ods|) - " + utils.getOOoName("Calc") + " RootPane ScrollPane Document view3 Sheet Sheet1 Table Good in Pies Apples Yes Cell B2 '",
      "     VISIBLE:  'Yes Cell B2 ', cursor=1",
      "SPEECH OUTPUT: 'cell column 2 Apples row 2 Good in Pies Yes'"]))
 
@@ -100,7 +100,7 @@ sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
 sequence.append(utils.AssertPresentationAction(
     "Down Arrow to cell B3",
-    ["BRAILLE LINE:  'soffice Application fruit(.ods|) - " + utils.getOOoName("Calc") + " Frame fruit(.ods|) - " + utils.getOOoName("Calc") + " RootPane ScrollPane Document view3 Sheet Sheet1 Table  Juiceable Yes Cell B3 '",
+    ["BRAILLE LINE:  'soffice Application fruit(.ods|) - " + utils.getOOoName("Calc") + " Frame fruit(.ods|) - " + utils.getOOoName("Calc") + " RootPane ScrollPane Document view3 Sheet Sheet1 Table Juiceable Apples Yes Cell B3 '",
      "     VISIBLE:  'Yes Cell B3 ', cursor=1",
      "SPEECH OUTPUT: 'Juiceable Yes B3'"]))
 
@@ -111,7 +111,7 @@ sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Right"))
 sequence.append(utils.AssertPresentationAction(
     "Right Arrow to cell C3",
-    ["BRAILLE LINE:  'soffice Application fruit(.ods|) - " + utils.getOOoName("Calc") + " Frame fruit(.ods|) - " + utils.getOOoName("Calc") + " RootPane ScrollPane Document view3 Sheet Sheet1 Table  Pears Yes Cell C3 '",
+    ["BRAILLE LINE:  'soffice Application fruit(.ods|) - " + utils.getOOoName("Calc") + " Frame fruit(.ods|) - " + utils.getOOoName("Calc") + " RootPane ScrollPane Document view3 Sheet Sheet1 Table Juiceable Pears Yes Cell C3 '",
      "     VISIBLE:  'Yes Cell C3 ', cursor=1",
      "SPEECH OUTPUT: 'Pears Yes C3'"]))
 
@@ -123,7 +123,7 @@ sequence.append(KeyComboAction("KP_Enter"))
 sequence.append(PauseAction(3000))
 sequence.append(utils.AssertPresentationAction(
     "Basic where am I with dynamic headers set C3",
-    ["BRAILLE LINE:  'soffice Application fruit(.ods|) - " + utils.getOOoName("Calc") + " Frame fruit(.ods|) - " + utils.getOOoName("Calc") + " RootPane ScrollPane Document view3 Sheet Sheet1 Table Yes Cell C3 '",
+    ["BRAILLE LINE:  'soffice Application fruit(.ods|) - " + utils.getOOoName("Calc") + " Frame fruit(.ods|) - " + utils.getOOoName("Calc") + " RootPane ScrollPane Document view3 Sheet Sheet1 Table Juiceable Pears Yes Cell C3 '",
      "     VISIBLE:  'Yes Cell C3 ', cursor=1",
      "SPEECH OUTPUT: 'cell column 3 Pears row 3 Juiceable Yes'"]))
 
@@ -134,7 +134,7 @@ sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Up"))
 sequence.append(utils.AssertPresentationAction(
     "Up Arrow to cell C2",
-    ["BRAILLE LINE:  'soffice Application fruit(.ods|) - " + utils.getOOoName("Calc") + " Frame fruit(.ods|) - " + utils.getOOoName("Calc") + " RootPane ScrollPane Document view3 Sheet Sheet1 Table  Good in Pies No Cell C2 '",
+    ["BRAILLE LINE:  'soffice Application fruit(.ods|) - " + utils.getOOoName("Calc") + " Frame fruit(.ods|) - " + utils.getOOoName("Calc") + " RootPane ScrollPane Document view3 Sheet Sheet1 Table Good in Pies Pears No Cell C2 '",
      "     VISIBLE:  'No Cell C2 ', cursor=1",
      "SPEECH OUTPUT: 'Good in Pies No C2'"]))
 
diff --git a/test/keystrokes/oocalc/bug_364407.py b/test/keystrokes/oocalc/bug_364407.py
index 7e96633..16d5d78 100644
--- a/test/keystrokes/oocalc/bug_364407.py
+++ b/test/keystrokes/oocalc/bug_364407.py
@@ -78,12 +78,9 @@ sequence.append(KeyComboAction("Return"))
 sequence.append(WaitForFocus("Sheet Sheet1", acc_role=pyatspi.ROLE_TABLE))
 sequence.append(utils.AssertPresentationAction(
     "Type 'c3' followed by Return to jump to cell C3 in the spreadsheet",
-    ["BRAILLE LINE:  'soffice Application Untitled[ ]*2 - " + utils.getOOoName("Calc") + " Frame Untitled[ ]*2 - " + utils.getOOoName("Calc") + " RootPane ScrollPane Document view3 Sheet Sheet1 Table'",
-     "     VISIBLE:  'Sheet Sheet1 Table', cursor=1",
-     "BRAILLE LINE:  'soffice Application Untitled[ ]*2 - " + utils.getOOoName("Calc") + " Frame Untitled[ ]*2 - " + utils.getOOoName("Calc") + " RootPane ScrollPane Document view3 Sheet Sheet1 Table Cell C3 '",
+    ["BRAILLE LINE:  'soffice Application Untitled[ ]*2 - " + utils.getOOoName("Calc") + " Frame Untitled[ ]*2 - " + utils.getOOoName("Calc") + " RootPane ScrollPane Document view3 Sheet Sheet1 Table Cell C3 '",
      "     VISIBLE:  'Cell C3 ', cursor=1",
-     "SPEECH OUTPUT: 'Sheet Sheet1 table grayed'",
-     "SPEECH OUTPUT: ' C3'"]))
+     "SPEECH OUTPUT: 'C3'"]))
 
 ######################################################################
 # 6. Enter Alt-f, Alt-c to close the Calc spreadsheet window.
diff --git a/test/keystrokes/oowriter/bug_350219.py b/test/keystrokes/oowriter/bug_350219.py
index 8c4ae6d..894458a 100644
--- a/test/keystrokes/oowriter/bug_350219.py
+++ b/test/keystrokes/oowriter/bug_350219.py
@@ -30,8 +30,7 @@ sequence.append(WaitForWindowActivate("Untitled[ ]*2 - " + utils.getOOoName("Wri
 sequence.append(WaitForFocus("", acc_role=pyatspi.ROLE_PARAGRAPH))
 sequence.append(utils.AssertPresentationAction(
     "New text document",
-    ["BUG? - The braille context doesn't include the Frame",
-     "BRAILLE LINE:  'soffice Application Untitled[ ]*2 - " + utils.getOOoName("Writer") + " Frame'",
+    ["BRAILLE LINE:  'soffice Application Untitled[ ]*2 - " + utils.getOOoName("Writer") + " Frame'",
      "     VISIBLE:  'Untitled[ ]*2 - *",
      "BRAILLE LINE:  'soffice Application Untitled[ ]*2 - " + utils.getOOoName("Writer") + " Frame Untitled[ ]*2 - " + utils.getOOoName("Writer") + " RootPane ScrollPane Document view  \$l'",
      "     VISIBLE:  ' $l', cursor=1",
diff --git a/test/keystrokes/oowriter/bug_353268.py b/test/keystrokes/oowriter/bug_353268.py
index 81d4f8c..76482e8 100644
--- a/test/keystrokes/oowriter/bug_353268.py
+++ b/test/keystrokes/oowriter/bug_353268.py
@@ -61,10 +61,10 @@ sequence.append(KeyComboAction("Down"))
 sequence.append(WaitForFocus("", acc_role=pyatspi.ROLE_PARAGRAPH))
 sequence.append(utils.AssertPresentationAction(
     "Arrow down over first line of text",
-    ["BRAILLE LINE:  'soffice Application Untitled[ ]*2 - " + utils.getOOoName("Writer") + " Frame Untitled[ ]*2 - " + utils.getOOoName("Writer") + " RootPane ScrollPane Document view Line 2 \$l'",
-     "     VISIBLE:  'Line 2 $l', cursor=1",
-     "BRAILLE LINE:  'soffice Application Untitled[ ]*2 - " + utils.getOOoName("Writer") + " Frame Untitled[ ]*2 - " + utils.getOOoName("Writer") + " RootPane ScrollPane Document view Line 2 \$l'",
-     "     VISIBLE:  'Line 2 $l', cursor=1",
+    ["BRAILLE LINE:  'Line 2 \$l'",
+     "     VISIBLE:  'Line 2 \$l', cursor=1",
+     "BRAILLE LINE:  'Line 2 \$l'",
+     "     VISIBLE:  'Line 2 \$l', cursor=1",
      "SPEECH OUTPUT: 'Line 2'"]))
 
 ######################################################################
@@ -75,10 +75,10 @@ sequence.append(KeyComboAction("Down"))
 sequence.append(WaitForFocus("", acc_role=pyatspi.ROLE_PARAGRAPH))
 sequence.append(utils.AssertPresentationAction(
     "Arrow down over second line of text",
-    ["BRAILLE LINE:  'soffice Application Untitled[ ]*2 - " + utils.getOOoName("Writer") + " Frame Untitled[ ]*2 - " + utils.getOOoName("Writer") + " RootPane ScrollPane Document view  \$l'",
-     "     VISIBLE:  ' $l', cursor=1",
-     "BRAILLE LINE:  'soffice Application Untitled[ ]*2 - " + utils.getOOoName("Writer") + " Frame Untitled[ ]*2 - " + utils.getOOoName("Writer") + " RootPane ScrollPane Document view  \$l'",
-     "     VISIBLE:  ' $l', cursor=1",
+    ["BRAILLE LINE:  ' \$l'",
+     "     VISIBLE:  ' \$l', cursor=1",
+     "BRAILLE LINE:  ' \$l'",
+     "     VISIBLE:  ' \$l', cursor=1",
      "SPEECH OUTPUT: 'blank'"]))
 
 ######################################################################
diff --git a/test/keystrokes/oowriter/bug_362979.py b/test/keystrokes/oowriter/bug_362979.py
index fbc4a82..0a4d26f 100644
--- a/test/keystrokes/oowriter/bug_362979.py
+++ b/test/keystrokes/oowriter/bug_362979.py
@@ -89,9 +89,9 @@ sequence.append(KeyComboAction("Down"))
 sequence.append(WaitForFocus("", acc_role=pyatspi.ROLE_PARAGRAPH))
 sequence.append(utils.AssertPresentationAction(
     "Move to second bulleted line",
-    ["BRAILLE LINE:  'soffice Application Untitled[ ]*2 - " + utils.getOOoName("Writer") + " Frame Untitled[ ]*2 - " + utils.getOOoName("Writer") + " RootPane ScrollPane Document view â?¢Line 2 \$l'",
+    ["BRAILLE LINE:  'â?¢Line 2 \$l'",
      "     VISIBLE:  'â?¢Line 2 \$l', cursor=2",
-     "BRAILLE LINE:  'soffice Application Untitled[ ]*2 - " + utils.getOOoName("Writer") + " Frame Untitled[ ]*2 - " + utils.getOOoName("Writer") + " RootPane ScrollPane Document view â?¢Line 2 \$l'",
+     "BRAILLE LINE:  'â?¢Line 2 \$l'",
      "     VISIBLE:  'â?¢Line 2 \$l', cursor=2",
      "SPEECH OUTPUT: 'â?¢Line 2'"]))
 
diff --git a/test/keystrokes/oowriter/bug_382408.py b/test/keystrokes/oowriter/bug_382408.py
index 40aad1e..b765cc5 100644
--- a/test/keystrokes/oowriter/bug_382408.py
+++ b/test/keystrokes/oowriter/bug_382408.py
@@ -35,10 +35,10 @@ sequence.append(KeyComboAction("Down"))
 sequence.append(WaitForFocus("", acc_role=pyatspi.ROLE_PARAGRAPH))
 sequence.append(utils.AssertPresentationAction(
     "Type a down arrow to move to the next line",
-    ["BRAILLE LINE:  '" + utils.getOOoBrailleLine("Writer", "table-sample(.odt|)", "This is a test. \$l") + "'",
-     "     VISIBLE:  'This is a test. $l', cursor=16",
-     "BRAILLE LINE:  '" + utils.getOOoBrailleLine("Writer", "table-sample(.odt|)", "This is a test. \$l") + "'",
-     "     VISIBLE:  'This is a test. $l', cursor=16",
+    ["BRAILLE LINE:  'This is a test. \$l'",
+     "     VISIBLE:  'This is a test. \$l', cursor=16",
+     "BRAILLE LINE:  'This is a test. \$l'",
+     "     VISIBLE:  'This is a test. \$l', cursor=16",
      "SPEECH OUTPUT: 'This is a test.'"]))
 
 ######################################################################
diff --git a/test/keystrokes/oowriter/bug_382415.py b/test/keystrokes/oowriter/bug_382415.py
index 2033198..0dbccf3 100644
--- a/test/keystrokes/oowriter/bug_382415.py
+++ b/test/keystrokes/oowriter/bug_382415.py
@@ -28,10 +28,10 @@ sequence.append(KeyComboAction("Down"))
 sequence.append(WaitForFocus("", acc_role=pyatspi.ROLE_PARAGRAPH))
 sequence.append(utils.AssertPresentationAction(
     "Down arrow to next line",
-    ["BRAILLE LINE:  '" + utils.getOOoBrailleLine("Writer", "table-sample(.odt|)", "This is a test. \$l") + "'",
-     "     VISIBLE:  'This is a test. $l', cursor=16",
-     "BRAILLE LINE:  '" + utils.getOOoBrailleLine("Writer", "table-sample(.odt|)", "This is a test. \$l") + "'",
-     "     VISIBLE:  'This is a test. $l', cursor=16",
+    ["BRAILLE LINE:  'This is a test. \$l'",
+     "     VISIBLE:  'This is a test. \$l', cursor=16",
+     "BRAILLE LINE:  'This is a test. \$l'",
+     "     VISIBLE:  'This is a test. \$l', cursor=16",
      "SPEECH OUTPUT: 'This is a test.'"]))
 
 ######################################################################
diff --git a/test/keystrokes/oowriter/bug_382880.py b/test/keystrokes/oowriter/bug_382880.py
index c244368..075955b 100644
--- a/test/keystrokes/oowriter/bug_382880.py
+++ b/test/keystrokes/oowriter/bug_382880.py
@@ -28,10 +28,10 @@ sequence.append(KeyComboAction("Down"))
 sequence.append(WaitForFocus("", acc_role=pyatspi.ROLE_PARAGRAPH))
 sequence.append(utils.AssertPresentationAction(
     "Type a down arrow to move to the next line",
-    ["BRAILLE LINE:  '" + utils.getOOoBrailleLine("Writer", "table-sample(.odt|)", "This is a test. \$l") + "'",
-     "     VISIBLE:  'This is a test. $l', cursor=16",
-     "BRAILLE LINE:  '" + utils.getOOoBrailleLine("Writer", "table-sample(.odt|)", "This is a test. \$l") + "'",
-     "     VISIBLE:  'This is a test. $l', cursor=16",
+    ["BRAILLE LINE:  'This is a test. \$l'",
+     "     VISIBLE:  'This is a test. \$l', cursor=16",
+     "BRAILLE LINE:  'This is a test. \$l'",
+     "     VISIBLE:  'This is a test. \$l', cursor=16",
      "SPEECH OUTPUT: 'This is a test.'"]))
 
 ######################################################################
diff --git a/test/keystrokes/oowriter/bug_382888.py b/test/keystrokes/oowriter/bug_382888.py
index f755185..768b695 100644
--- a/test/keystrokes/oowriter/bug_382888.py
+++ b/test/keystrokes/oowriter/bug_382888.py
@@ -28,10 +28,10 @@ sequence.append(KeyComboAction("Down"))
 sequence.append(WaitForFocus("", acc_role=pyatspi.ROLE_PARAGRAPH))
 sequence.append(utils.AssertPresentationAction(
     "Type a down arrow to move to the next line",
-    ["BRAILLE LINE:  '" + utils.getOOoBrailleLine("Writer", "table-sample(.odt|)", "This is a test. \$l") + "'",
-     "     VISIBLE:  'This is a test. $l', cursor=16",
-     "BRAILLE LINE:  '" + utils.getOOoBrailleLine("Writer", "table-sample(.odt|)", "This is a test. \$l") + "'",
-     "     VISIBLE:  'This is a test. $l', cursor=16",
+    ["BRAILLE LINE:  'This is a test. \$l'",
+     "     VISIBLE:  'This is a test. \$l', cursor=16",
+     "BRAILLE LINE:  'This is a test. \$l'",
+     "     VISIBLE:  'This is a test. \$l', cursor=16",
      "SPEECH OUTPUT: 'This is a test.'"]))
 
 ######################################################################
diff --git a/test/keystrokes/oowriter/bug_385828.py b/test/keystrokes/oowriter/bug_385828.py
index f7c068d..a928be9 100644
--- a/test/keystrokes/oowriter/bug_385828.py
+++ b/test/keystrokes/oowriter/bug_385828.py
@@ -38,10 +38,10 @@ sequence.append(utils.AssertPresentationAction(
     "Press 'a' to bring up the Agenda... wizard",
     ["BRAILLE LINE:  " + utils.getOOoName("Writer") + " Frame (1 dialog)'",
      "     VISIBLE:  'Frame (1 dialog)', cursor=1",
-     "BRAILLE LINE:  " + utils.getOOoName("Writer") + "'Agenda Wizard Dialog'",
+     "BRAILLE LINE:  " + utils.getOOoName("Writer") + " Agenda Wizard Dialog'",
      "     VISIBLE:  'Agenda Wizard Dialog', cursor=1",
-     "BRAILLE LINE:  " + utils.getOOoName("Writer") + "'Agenda Wizard Dialog Agenda Wizard OptionPane Steps Panel  $l'",
-     "     VISIBLE:  '  $l', cursor=1",
+     "BRAILLE LINE:  " + utils.getOOoName("Writer") + " Agenda Wizard Dialog Agenda Wizard OptionPane Steps Panel  \$l'",
+     "     VISIBLE:  ' \$l', cursor=1",
      "SPEECH OUTPUT: 'frame 1 unfocused dialog'",
      "SPEECH OUTPUT: 'Agenda Wizard Please choose the page design for the agenda 1. Page design 2. General information 3. Headings to include 4. Names 5. Agenda items 6. Name and location'",
      "SPEECH OUTPUT: 'Page design label'"]))
diff --git a/test/keystrokes/oowriter/bug_435201.py b/test/keystrokes/oowriter/bug_435201.py
index 72dc740..d5a3d4f 100644
--- a/test/keystrokes/oowriter/bug_435201.py
+++ b/test/keystrokes/oowriter/bug_435201.py
@@ -32,7 +32,7 @@ sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("<Control>Down"))
 sequence.append(utils.AssertPresentationAction(
     "Type Control-down to move to the next paragraph [1]",
-    ["BRAILLE LINE:  '" + utils.getOOoBrailleLine("Writer", "spanish(.odt|)", "NOBODY expects the Spanish Inquisition! Amongst our weaponry are such diverse  \$l") + "'",
+    ["BRAILLE LINE:  'NOBODY expects the Spanish Inquisition! Amongst our weaponry are such diverse  \$l'",
      "     VISIBLE:  'NOBODY expects the Spanish Inqui', cursor=1",
      "BRAILLE LINE:  'NOBODY expects the Spanish Inquisition! Amongst our weaponry are such diverse  \$l",
      "     VISIBLE:  'NOBODY expects the Spanish Inqui', cursor=1",
@@ -45,7 +45,7 @@ sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("<Control>Down"))
 sequence.append(utils.AssertPresentationAction(
     "Type Control-down to move to the next paragraph [2]",
-    ["BRAILLE LINE:  '" + utils.getOOoBrailleLine("Writer", "spanish(.odt|)", " \$l") + "'",
+    ["BRAILLE LINE:  ' \$l'",
      "     VISIBLE:  ' \$l', cursor=1",
      "BRAILLE LINE:  ' \$l'",
      "     VISIBLE:  ' \$l', cursor=1",
@@ -58,11 +58,11 @@ sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("<Control>Down"))
 sequence.append(utils.AssertPresentationAction(
     "Type Control-down to move to the next paragraph [3]",
-    ["BRAILLE LINE:  '" + utils.getOOoBrailleLine("Writer", "spanish(.odt|)", "Now old lady, you have one last chance. Confess the heinous sin of heresy, reject  \$l") + "'",
+    ["BRAILLE LINE:  'Now old lady, you have one last chance. Confess the heinous sin of heresy, reject  \$l'",
      "     VISIBLE:  'Now old lady, you have one last ', cursor=1",
      "BRAILLE LINE:  'Now old lady, you have one last chance. Confess the heinous sin of heresy, reject  \$l'",
      "     VISIBLE:  'Now old lady, you have one last ', cursor=1",
-     "BRAILLE LINE:  '" + utils.getOOoBrailleLine("Writer", "spanish(.odt|)", " \$l") + "'",
+     "BRAILLE LINE:  ' \$l'",
      "     VISIBLE:  ' \$l', cursor=1",
      "SPEECH OUTPUT: 'Now old lady, you have one last chance. Confess the heinous sin of heresy, reject the works of the ungodly. Two last chances. And you shall be free. Three last chances. You have three last chances, the nature of which I have divulged in my previous utterance.'"]))
 
@@ -73,7 +73,7 @@ sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("<Control>Down"))
 sequence.append(utils.AssertPresentationAction(
     "Type Control-down to move to the next paragraph [4]",
-    ["BRAILLE LINE:  '" + utils.getOOoBrailleLine("Writer", "spanish(.odt|)", " \$l") + "'",
+    ["BRAILLE LINE:  ' \$l'",
      "     VISIBLE:  ' \$l', cursor=1",
      "BRAILLE LINE:  ' \$l'",
      "     VISIBLE:  ' \$l', cursor=1",
@@ -86,11 +86,11 @@ sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("<Control>Down"))
 sequence.append(utils.AssertPresentationAction(
     "Type Control-down to move to the next paragraph [5]",
-    ["BRAILLE LINE:  '" + utils.getOOoBrailleLine("Writer", "spanish(.odt|)", "Hm! She is made of harder stuff! Cardinal Fang! Fetch the COMFY CHAIR! \$l") + "'",
+    ["BRAILLE LINE:  'Hm! She is made of harder stuff! Cardinal Fang! Fetch the COMFY CHAIR! \$l'",
      "     VISIBLE:  'Hm! She is made of harder stuff!', cursor=1",
      "BRAILLE LINE:  'Hm! She is made of harder stuff! Cardinal Fang! Fetch the COMFY CHAIR! \$l'",
      "     VISIBLE:  'Hm! She is made of harder stuff!', cursor=1",
-     "BRAILLE LINE:  '" + utils.getOOoBrailleLine("Writer", "spanish(.odt|)", " \$l") + "'",
+     "BRAILLE LINE:  ' \$l'",
      "     VISIBLE:  ' \$l', cursor=1",
      "SPEECH OUTPUT: 'Hm! She is made of harder stuff! Cardinal Fang! Fetch the COMFY CHAIR!'"]))
 
diff --git a/test/keystrokes/oowriter/bug_435226.py b/test/keystrokes/oowriter/bug_435226.py
index a96658b..66fce78 100644
--- a/test/keystrokes/oowriter/bug_435226.py
+++ b/test/keystrokes/oowriter/bug_435226.py
@@ -72,7 +72,7 @@ sequence.append(KeyComboAction("KP_Enter"))
 sequence.append(PauseAction(3000))
 sequence.append(utils.AssertPresentationAction(
     "Type KP-Enter once to do a 'single-click' where-am-I operation",
-    ["BRAILLE LINE:  '" + utils.getOOoBrailleLine("Writer", "spanish(.odt|)", "Hm! She is made of harder stuff! Cardinal Fang! Fetch the COMFY CHAIR! \$l") + "'",
+    ["BRAILLE LINE:  'Hm! She is made of harder stuff! Cardinal Fang! Fetch the COMFY CHAIR! \$l'",
      "     VISIBLE:  'Hm! She is made of harder stuff!', cursor=17",
      "SPEECH OUTPUT: 'Spanish Inquisition! Our chief weapon is surprise. Surprise and fear. Fear and surprise. Our two weapons are fear and surprise. And ruthless efficiency. Our three weapons are fear, surprise, and ruthless efficiency. And an almost fanatical devotion to the Pope. Our four. No. Amongst our weapons. Amongst our weaponry, are such elements as fear, surprise. I'll come in again. NOBODY expects the Spanish Inquisition! 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! Now old lady, you have one last chance. Confess the heinous sin of heresy, reject the works of the ungodly. Two last chances. And you shall be free. Three last chances. You have three last chances, the nature of which I have divulged in my previous utterance. Hm! She is made  selected'"]))
 
@@ -85,9 +85,9 @@ sequence.append(KeyComboAction("KP_Enter"))
 sequence.append(PauseAction(3000))
 sequence.append(utils.AssertPresentationAction(
     "Type KP-Enter twice to do a 'double-click' where-am-I operation",
-    ["BRAILLE LINE:  '" + utils.getOOoBrailleLine("Writer", "spanish(.odt|)", "Hm! She is made of harder stuff! Cardinal Fang! Fetch the COMFY CHAIR! \$l") + "'",
+    ["BRAILLE LINE:  'Hm! She is made of harder stuff! Cardinal Fang! Fetch the COMFY CHAIR! \$l'",
      "     VISIBLE:  'Hm! She is made of harder stuff!', cursor=17",
-     "BRAILLE LINE:  '" + utils.getOOoBrailleLine("Writer", "spanish(.odt|)", "Hm! She is made of harder stuff! Cardinal Fang! Fetch the COMFY CHAIR! \$l") + "'",
+     "BRAILLE LINE:  'Hm! She is made of harder stuff! Cardinal Fang! Fetch the COMFY CHAIR! \$l'",
      "     VISIBLE:  'Hm! She is made of harder stuff!', cursor=17",
      "SPEECH OUTPUT: 'Spanish Inquisition! Our chief weapon is surprise. Surprise and fear. Fear and surprise. Our two weapons are fear and surprise. And ruthless efficiency. Our three weapons are fear, surprise, and ruthless efficiency. And an almost fanatical devotion to the Pope. Our four. No. Amongst our weapons. Amongst our weaponry, are such elements as fear, surprise. I'll come in again. NOBODY expects the Spanish Inquisition! 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! Now old lady, you have one last chance. Confess the heinous sin of heresy, reject the works of the ungodly. Two last chances. And you shall be free. Three last chances. You have three last chances, the nature of which I have divulged in my previous utterance. Hm! She is made  selected'",
      "SPEECH OUTPUT: 'Spanish Inquisition! Our chief weapon is surprise. Surprise and fear. Fear and surprise. Our two weapons are fear and surprise. And ruthless efficiency. Our three weapons are fear, surprise, and ruthless efficiency. And an almost fanatical devotion to the Pope. Our four. No. Amongst our weapons. Amongst our weaponry, are such elements as fear, surprise. I'll come in again. NOBODY expects the Spanish Inquisition! 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! Now old lady, you have one last chance. Confess the heinous sin of heresy, reject the works of the ungodly. Two last chances. And you shall be free. Three last chances. You have three last chances, the nature of which I have divulged in my previous utterance. Hm! She is made  ;  paragraph style Preformatted Text selected'"]))
diff --git a/test/keystrokes/oowriter/table_cells.py b/test/keystrokes/oowriter/table_cells.py
index f60a058..8fac645 100644
--- a/test/keystrokes/oowriter/table_cells.py
+++ b/test/keystrokes/oowriter/table_cells.py
@@ -26,10 +26,10 @@ sequence.append(KeyComboAction("Down"))
 sequence.append(WaitForFocus("", acc_role=pyatspi.ROLE_PARAGRAPH))
 sequence.append(utils.AssertPresentationAction(
     "Type a down arrow to move to the next line",
-    ["BRAILLE LINE:  '" + utils.getOOoBrailleLine("Writer", "table-sample(.odt|)", "This is a test. \$l") + "'",
-     "     VISIBLE:  'This is a test. $l', cursor=16",
-     "BRAILLE LINE:  '" + utils.getOOoBrailleLine("Writer", "table-sample(.odt|)", "This is a test. \$l") + "'",
-     "     VISIBLE:  'This is a test. $l', cursor=16",
+    ["BRAILLE LINE:  'This is a test. \$l'",
+     "     VISIBLE:  'This is a test. \$l', cursor=16",
+     "BRAILLE LINE:  'This is a test. \$l'",
+     "     VISIBLE:  'This is a test. \$l', cursor=16",
      "SPEECH OUTPUT: 'This is a test.'"]))
 
 ######################################################################
@@ -285,7 +285,7 @@ sequence.append(KeyComboAction("Down"))
 sequence.append(WaitForFocus("", acc_role=pyatspi.ROLE_PARAGRAPH))
 sequence.append(utils.AssertPresentationAction(
     "Down - Speak Row",
-    ["BRAILLE LINE:  '" + utils.getOOoBrailleLine("Writer", "table-sample(.odt|)", "Calendar-1 Table 31      ") + "'",
+    ["BRAILLE LINE:  '" + utils.getOOoBrailleLine("Writer", "table-sample(.odt|)", "Calendar-1 Table 31") + "      '",
      "     VISIBLE:  '', cursor=1",
      "SPEECH OUTPUT: 'End of table 31'"]))
 
diff --git a/test/keystrokes/oowriter/table_cells_structural_navigation1.py b/test/keystrokes/oowriter/table_cells_structural_navigation1.py
index a255210..50d52c4 100644
--- a/test/keystrokes/oowriter/table_cells_structural_navigation1.py
+++ b/test/keystrokes/oowriter/table_cells_structural_navigation1.py
@@ -26,10 +26,10 @@ sequence.append(KeyComboAction("Down"))
 sequence.append(WaitForFocus("", acc_role=pyatspi.ROLE_PARAGRAPH))
 sequence.append(utils.AssertPresentationAction(
     "Type a down arrow to move to the next line",
-    ["BRAILLE LINE:  '" + utils.getOOoBrailleLine("Writer", "table-sample2(.odt|)", "This is a test. \$l") + "'",
-     "     VISIBLE:  'This is a test. $l', cursor=16",
-     "BRAILLE LINE:  '" + utils.getOOoBrailleLine("Writer", "table-sample2(.odt|)", "This is a test. \$l") + "'",
-     "     VISIBLE:  'This is a test. $l', cursor=16",
+    ["BRAILLE LINE:  'This is a test. \$l'",
+     "     VISIBLE:  'This is a test. \$l', cursor=16",
+     "BRAILLE LINE:  'This is a test. \$l'",
+     "     VISIBLE:  'This is a test. \$l', cursor=16",
      "SPEECH OUTPUT: 'This is a test.'"]))
 
 ######################################################################
@@ -118,8 +118,8 @@ sequence.append(KeyComboAction("<Alt><Shift>Right"))
 sequence.append(WaitForFocus("", acc_role=pyatspi.ROLE_PARAGRAPH))
 sequence.append(utils.AssertPresentationAction(
     "5. Alt Shift Right.",
-    ["BRAILLE LINE:  '" + utils.getOOoBrailleLine("Writer", "table-sample2(.odt|)", "Calendar-1 Table 6 Paragraph7 Paragraph") + "'",
-     "     VISIBLE:  '7 Paragraph', cursor=1",
+    ["BRAILLE LINE:  '" + utils.getOOoBrailleLine("Writer", "table-sample2(.odt|)", "Calendar-1 Table 6 Paragraph 7 Paragraph") + "'",
+     "     VISIBLE:  '6 Paragraph 7 Paragraph', cursor=1",
      "SPEECH OUTPUT: '6'",
      "SPEECH OUTPUT: '7'",
      "SPEECH OUTPUT: 'Row 3, column 4.'",



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