diff --git a/po/POTFILES.in b/po/POTFILES.in
index a96dd12..6de4f8b 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -20,6 +20,7 @@ src/orca/keynames.py
 src/orca/liveregions.py
 src/orca/mag.py
 src/orca/notification_messages.py
+src/orca/object_navigator.py
 [type: gettext/glade]src/orca/orca-advanced-magnification.ui
 src/orca/orca_console_prefs.py
 [type: gettext/glade]src/orca/orca-find.ui
@@ -29,6 +30,7 @@ src/orca/orca_gui_prefs.py
 src/orca/orca.in
 [type: gettext/glade]src/orca/orca-mainwin.ui
 src/orca/orca.py
+[type: gettext/glade]src/orca/orca-object-navigator.ui
 [type: gettext/glade]src/orca/orca-preferences-warning.ui
 [type: gettext/glade]src/orca/orca-profile.ui
 [type: gettext/glade]src/orca/orca-quit.ui
diff --git a/src/orca/Makefile.am b/src/orca/Makefile.am
index 891ecac..2ec9aaf 100644
--- a/src/orca/Makefile.am
+++ b/src/orca/Makefile.am
@@ -41,6 +41,7 @@ orca_python_PYTHON = \
 	mag.py \
 	mouse_review.py \
 	notification_messages.py \
+	object_navigator.py \
 	orca.py \
 	orca_console_prefs.py \
 	orca_gtkbuilder.py \
@@ -85,6 +86,7 @@ ui_DATA = \
 	orca-advanced-magnification.ui \
 	orca-find.ui \
 	orca-mainwin.ui \
+	orca-object-navigator.ui \
 	orca-preferences-warning.ui \
 	orca-quit.ui \
 	orca-setup.ui \
diff --git a/src/orca/object_navigator.py b/src/orca/object_navigator.py
new file mode 100644
index 0000000..460a745
--- /dev/null
+++ b/src/orca/object_navigator.py
@@ -0,0 +1,449 @@
+# Orca
+#
+# Copyright 2011 Marcus Habermehl
+#
+# 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.
+
+"""Displays a list of structural navigation objects."""
+
+__id__ = "$Id$"
+__version__ = "$Revision$"
+__date__ = "$Date$"
+__copyright__ = "Copyright (c) 2011 Marcus Habermehl"
+__license__ = "LGPL"
+
+import gtk
+import os
+import pyatspi
+import re
+
+import debug
+import orca
+import orca_gtkbuilder
+import orca_platform
+import orca_state
+import rolenames
+
+from orca_i18n import _
+
+class ObjectNavigator(orca_gtkbuilder.GtkBuilderWrapper):
+    def __init__(self, uiFile, script):
+        """Initialize the Object Navigator window.
+
+        Arguments:
+        - uiFile: path to the GtkBuilder file.
+        - script: the application script.
+        """
+
+        orca_gtkbuilder.GtkBuilderWrapper.__init__(
+            self, uiFile, "objectNavigator")
+
+        self._script = script
+
+        self._arg = None
+
+        self._predicate = None
+
+        self._unnamedIndex = 1
+
+        self._objectStore = gtk.ListStore(str, object, object, object)
+
+        self.get_widget("objectView").set_model(self._objectStore)
+
+        entryRenderer = gtk.CellRendererText()
+
+        entryColumn = gtk.TreeViewColumn("", entryRenderer)
+        entryColumn.add_attribute(entryRenderer, "text", 0)
+        self.get_widget("objectView").append_column(entryColumn)
+
+        objectRenderer = gtk.CellRendererText()
+
+        objectColumn = gtk.TreeViewColumn("", objectRenderer)
+        objectColumn.set_visible(False)
+        self.get_widget("objectView").append_column(objectColumn)
+
+        presentRenderer = gtk.CellRendererText()
+
+        presentColumn = gtk.TreeViewColumn("", presentRenderer)
+        presentColumn.set_visible(False)
+        self.get_widget("objectView").append_column(presentColumn)
+
+        argRenderer = gtk.CellRendererText()
+
+        argColumn = gtk.TreeViewColumn("", argRenderer)
+        argColumn.set_visible(False)
+        self.get_widget("objectView").append_column(argColumn)
+
+    def init(self, objectType, document, predicate, presentation, arg):
+        """Set the window title, find objects in the document and fill the
+        object list.
+
+        Arguments:
+        - objectType: human readable name of the object type to present.
+        - document: the document to search objects in.
+        - predicate: a function to test if an object is of the searched type.
+        - presentation: a function used to present an object into the document.
+        - arg: an argument passed to the predicate function.
+        """
+
+        self.get_widget("objectNavigator").set_title(
+            # Translators: this is the window title for the list of a given
+            # structural navigation object. %s is replaced by a human readable
+            # name of the object type. (e.g. Anchors)
+            #
+            _("List of %s") % objectType)
+
+        while gtk.events_pending():
+            gtk.main_iteration()
+
+        self._predicate = predicate
+
+        self._arg = arg
+
+        objects = pyatspi.findAllDescendants(document, self._executePredicate)
+
+        if not objects:
+            return False
+
+        for obj in objects:
+            self._objectStore.append(
+                [self._generateLabel(obj), obj, presentation, arg])
+
+        return True
+
+    def _executePredicate(self, obj):
+        """Executes predicate with arg.
+
+        Argument:
+        - obj: an accessible object.
+        """
+
+        return self._predicate(obj, self._arg)
+
+    def _generateLabel(self, obj):
+        """Generate the label for an object to show in the object list.
+
+        Arguments:
+        - obj: the accessible object.
+        """
+
+        haveName = False
+        haveRole = False
+        labelList = []
+
+        # Translators: This is a prefix for objects for that we can't find a
+        # name or label. %d is replaced by a serial number.
+        #
+        unnamed = _("Unnamed %d") % self._unnamedIndex
+
+        while gtk.events_pending():
+            gtk.main_iteration()
+
+        format = self._script.formatting.getFormat(mode = "speech",
+                                                   role = obj.getRole(),
+                                                   formatType = "unfocused")
+
+        for i in format.split("+"):
+            part = i.strip().rstrip()
+            part = part[0].upper() + part[1:]
+
+            # Those parts of speech aren't needed for the labels.
+            if part in ["LineBreak", "Pause"]:
+                continue
+
+            # Since we want to sometimes complete the RoleName we use the
+            # methode of this class.
+            if part == "RoleName":
+                generateMethode = "self._generateRoleName(obj)"
+            # For all other parts we use the methods of the SpeechGenerator
+            # class.
+            else:
+                generateMethode = \
+                    "self._script.speechGenerator._generate%s(obj)" % part
+
+            try:
+                speech = eval(generateMethode)
+            except:
+                pass
+            else:
+                # Check if an usable name for the object was found.
+                if part in ["LabelAndName", "LabelOrName", "Name"]:
+                    if len(speech) > 0 and self._removeSpam(speech[0]):
+                        haveName = True
+                # Check if an usable role for the object was found.
+                elif part in ["NumberOfChildren", "RoleName", "TextRole"]:
+                    if len(speech) > 0:
+                        haveRole = True
+
+                if len(speech) > 0:
+                    labelList.append(self._removeSpam(speech[0]))
+
+        # If orca doesn't insert a role by itself, we will append the role.
+        if not haveRole:
+            labelList.append(self._generateRoleName(obj)[0])
+
+        while gtk.events_pending():
+            gtk.main_iteration()
+
+        if not haveName:
+            # If we haven't found a name for form fields use the guessTheLabel
+            # method of Gecko's Script class.
+            if self._script.structuralNavigation._formFieldPredicate(obj):
+                if obj.getRole() != pyatspi.ROLE_PUSH_BUTTON:
+                    guess = self._removeSpam(
+                        self._script.guessTheLabel(obj, False))
+
+                    if guess:
+                        haveName = True
+                        labelList.insert(0, guess)
+            # If we haven't found a name for lists get the text of the list
+            # items, contained in the list.
+            elif self._script.structuralNavigation._listPredicate(obj):
+                name = self._removeSpam(self._getText(obj))
+
+                if name:
+                    haveName = True
+                    labelList = [name, labelList[-1]]
+            # If we haven't found a name for tables get the text of the rows,
+            # contained in the table.
+            elif self._script.structuralNavigation._tablePredicate(obj):
+                name = ""
+
+                for i in range(obj.childCount):
+                    if "tag:TR" in obj.getChildAtIndex(i).getAttributes():
+                        name = "%s %s" % (name, obj.getChildAtIndex(i).name)
+
+                name = self._removeSpam(name)
+
+                if name:
+                    haveName = True
+                    labelList = [name, labelList[-1]]
+            # If we haven't found a name for headings get the text of the
+            # objects, contained in the table.
+            elif self._script.structuralNavigation._headingPredicate(obj):
+                name = self._removeSpam(self._getText(obj))
+
+                if name:
+                    haveName = True
+                    labelList.insert(0, name)
+
+        # Paragraphs and sections should present their content as name.
+        if obj.getRole() in [pyatspi.ROLE_PARAGRAPH, pyatspi.ROLE_SECTION]:
+            name = self._removeSpam(self._getText(obj))
+
+            if name:
+                haveName = True
+                labelList = [name, labelList[-1]]
+
+        # If not already a name was found, the object is unnamed.
+        if not haveName:
+            labelList.insert(0, unnamed)
+            self._unnamedIndex += 1
+
+        labelString = " ".join(labelList)
+
+        return labelString
+
+    def _generateRoleName(self, obj):
+        """Generate the role name for obj.
+
+        Arguments:
+        - obj: the accessible object.
+        """
+
+        role = rolenames.getSpeechForRoleName(obj)
+
+        # Add the heading level to the role name of headings.
+        if obj.getRole() == pyatspi.ROLE_HEADING:
+            level = self._script.getHeadingLevel(obj)
+
+            if level:
+                # Translators: this is the role name for headings.
+                # (e.g. Heading level 2)
+                #
+                role = _("%(role)s level %(level)d") % {
+                    "role": role, "level": self._script.getHeadingLevel(obj)}
+
+        # Add the visited state to the role name of links.
+        if obj.getRole() == pyatspi.ROLE_LINK:
+            if obj.getState().contains(pyatspi.STATE_VISITED):
+                # Translators: this is the role name for visited links.
+                # (e.g. visited Link)
+                #
+                role = _("visited %s") % role
+            else:
+                # Translators: this is the role name for unvisited links.
+                # (e.g. unvisited Link)
+                #
+                role = _("unvisited %s") % role
+
+        return [role]
+
+    def _getText(self, obj):
+        """Get the text contained in obj.
+
+        Arguments:
+        - obj: the accessible object.
+        """
+
+        try:
+            text = obj.queryText()
+        except:
+            string = ""
+        else:
+            string = text.getText(0, -1)
+
+        idx = 0
+
+        # If an object is part of the text, replace the object placeholder with
+        # its content.
+        for i in re.findall("\xef\xbf\xbc", string):
+            text = self._getText(obj.getChildAtIndex(idx))
+            string = string.replace("\xef\xbf\xbc", text + " ", 1)
+            idx += 1
+
+        return string
+
+    def onFocusOutEvent(self, widget, event):
+        """The object navigator window has lost the focus. Close the window.
+
+        Arguments:
+        - widget: the widget that has received the event.
+        - event: the event that was received.
+        """
+
+        widget.destroy()
+
+    def onRowActivated(self, treeView, treePath, treeViewColumn):
+        """The user has pressed Enter on a selected row. Close the window and
+        present the selected object in the window, using the presentation
+        method of the StructuralNavigation class.
+
+        Arguments:
+        - treeView: the treeview that has received the signal.
+        - treePath: the selected path in the treeview.
+        - treeViewColumn: the selected treeview column in the treeview.
+        """
+
+        treeModel, treeIter = treeView.get_selection().get_selected()
+
+        obj = treeModel.get_value(treeIter, 1)
+        present = treeModel.get_value(treeIter, 2)
+        arg = treeModel.get_value(treeIter, 3)
+
+        self.get_widget("objectNavigator").destroy()
+
+        while gtk.events_pending():
+            gtk.main_iteration()
+
+        present(obj, arg)
+
+    def _removeSpam(self, string):
+        """Remove protected, duplicated, prefixed or suffixed whitespaces and
+        object placeholders from string.
+
+        Arguments:
+        - string: the string the remove whitespaces from.
+        """
+
+        if not string:
+            return string
+
+        string = string.replace("\xc2\xa0", " ")
+
+        string = string.replace("\xef\xbf\xbc", " ")
+
+        while "  " in string:
+            string = string.replace("  ", " ")
+
+        string = string.strip()
+        string = string.rstrip()
+
+        return string
+
+    def showGUI(self):
+        """Show the object list window. This assumes that the GUI has already
+        been created.
+        """
+
+        objectNavigator = self.get_widget("objectNavigator")
+
+        # Set the current time on the object navigator GUI dialog so that it'll
+        # get focus. set_user_time is a new call in pygtk 2.9.2 or later.
+        # It's surronded by a try/except block here so that if it's not found,
+        # then we can fail gracefully.
+        #
+        try:
+            objectNavigator.realize()
+            ts = orca_state.lastInputEventTimestamp
+            if ts == 0:
+                ts = gtk.get_current_event_time()
+            objectNavigator.window.set_user_time(ts)
+        except AttributeError:
+            debug.printException(debug.LEVEL_FINEST)
+
+        objectNavigator.show()
+
+def showObjectNavigator(
+    script, objectType, document, predicate, presentation, arg):
+    """Initialize, build and show the object list window.
+
+    Arguments:
+    - script: the application script.
+    - objectType: human readable name of the object type to present.
+    - document: the document to search objects in.
+    - predicate: a function to test if an object is of the searched type.
+    - presentation: a function used to present an object into the document.
+    - arg: an argument passed to the predicate function.
+    """
+
+    # If the cursor isn't inside a document
+    # orca.scripts.toolkits.Gecko.script.guessTheLabel will return empty
+    # labels.
+    #
+    if orca_state.locusOfFocus.getRole() == pyatspi.ROLE_FRAME:
+        orca.speech.speak(
+            # Translators: This message is spoken if an object list is
+            # requrested, but the cursor isn't inside a document.
+            #
+            _("The cursor is not inside a document."),
+            orca.settings.voices.get(orca.settings.SYSTEM_VOICE))
+        return False
+
+    orca.speech.speak(
+        # Translators: This message is spoken before an object list is builded.
+        #
+        _("Please wait while %s are collected.") % objectType,
+        orca.settings.voices.get(orca.settings.SYSTEM_VOICE))
+
+    objectNavigator = ObjectNavigator(
+        os.path.join(orca_platform.prefix,
+                     orca_platform.datadirname,
+                     orca_platform.package,
+                     "ui",
+                     "orca-object-navigator.ui"),
+        script)
+
+    if objectNavigator.init(objectType, document, predicate, presentation, arg):
+        objectNavigator.showGUI()
+    else:
+        orca.speech.speak(
+            # Translators: This message is spoken if the user requested an
+            # object list, but the document doesn't contains objects of the
+            # given type.
+            #
+            _("There was no %s found in the document..") % objectType,
+            orca.settings.voices.get(orca.settings.SYSTEM_VOICE))
diff --git a/src/orca/orca-object-navigator.ui b/src/orca/orca-object-navigator.ui
new file mode 100644
index 0000000..8bb7e01
--- /dev/null
+++ b/src/orca/orca-object-navigator.ui
@@ -0,0 +1,68 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<interface>
+  <requires lib="gtk+" version="2.16"/>
+  <!-- interface-naming-policy project-wide -->
+  <object class="GtkDialog" id="objectNavigator">
+    <property name="border_width">5</property>
+    <property name="type_hint">normal</property>
+    <signal name="focus_out_event" handler="onFocusOutEvent"/>
+    <child internal-child="vbox">
+      <object class="GtkVBox" id="dialog-vbox1">
+        <property name="visible">True</property>
+        <property name="spacing">2</property>
+        <child>
+          <object class="GtkLabel" id="label1">
+            <property name="visible">True</property>
+            <property name="label" translatable="yes">Select an item from the list and press Enter to go to the selected object in the document.</property>
+            <property name="wrap">True</property>
+          </object>
+          <packing>
+            <property name="expand">False</property>
+            <property name="fill">False</property>
+            <property name="position">1</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkScrolledWindow" id="scrolledwindow1">
+            <property name="visible">True</property>
+            <property name="can_focus">True</property>
+            <property name="hscrollbar_policy">automatic</property>
+            <property name="vscrollbar_policy">automatic</property>
+            <child>
+              <object class="GtkTreeView" id="objectView">
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="headers_visible">False</property>
+                <property name="rules_hint">True</property>
+                <accessibility>
+                  <relation type="labelled-by" target="label1"/>
+                </accessibility>
+                <signal name="row_activated" handler="onRowActivated"/>
+              </object>
+            </child>
+          </object>
+          <packing>
+            <property name="position">2</property>
+          </packing>
+        </child>
+        <child internal-child="action_area">
+          <object class="GtkHButtonBox" id="dialog-action_area1">
+            <property name="visible">True</property>
+            <property name="layout_style">end</property>
+            <child>
+              <placeholder/>
+            </child>
+            <child>
+              <placeholder/>
+            </child>
+          </object>
+          <packing>
+            <property name="expand">False</property>
+            <property name="pack_type">end</property>
+            <property name="position">0</property>
+          </packing>
+        </child>
+      </object>
+    </child>
+  </object>
+</interface>
diff --git a/src/orca/scripts/apps/epiphany/script.py b/src/orca/scripts/apps/epiphany/script.py
index 38acc16..c8f48f8 100644
--- a/src/orca/scripts/apps/epiphany/script.py
+++ b/src/orca/scripts/apps/epiphany/script.py
@@ -56,6 +56,7 @@ class Script(WebKitGtk.Script):
                         StructuralNavigation.FORM_FIELD,
                         StructuralNavigation.HEADING,
                         StructuralNavigation.LANDMARK,
+                        StructuralNavigation.LINK,
                         StructuralNavigation.LIST,
                         StructuralNavigation.LIST_ITEM,
                         StructuralNavigation.LIVE_REGION,
diff --git a/src/orca/scripts/apps/soffice/script.py b/src/orca/scripts/apps/soffice/script.py
index 76bcd1c..2f6ce1a 100644
--- a/src/orca/scripts/apps/soffice/script.py
+++ b/src/orca/scripts/apps/soffice/script.py
@@ -203,7 +203,7 @@ class Script(default.Script):
         """Returns the 'structural navigation' class for this script.
         """
         types = self.getEnabledStructuralNavigationTypes()
-        return StructuralNavigation(self, types, enabled=False)
+        return StructuralNavigation(self, types, False, False)
 
     def getEnabledStructuralNavigationTypes(self):
         """Returns a list of the structural navigation object types
diff --git a/src/orca/scripts/apps/soffice/structural_navigation.py b/src/orca/scripts/apps/soffice/structural_navigation.py
index 48b0297..fbd2a09 100644
--- a/src/orca/scripts/apps/soffice/structural_navigation.py
+++ b/src/orca/scripts/apps/soffice/structural_navigation.py
@@ -41,12 +41,13 @@ from orca.orca_i18n import _
 
 class StructuralNavigation(structural_navigation.StructuralNavigation):
 
-    def __init__(self, script, enabledTypes, enabled):
+    def __init__(self, script, enabledTypes, enabled, listsEnabled):
         """StarOffice/OpenOffice specific Structural Navigation."""
         structural_navigation.StructuralNavigation.__init__(self,
                                                             script,
                                                             enabledTypes,
-                                                            enabled)
+                                                            enabled,
+                                                            listsEnabled)
 
     def _isHeader(self, obj):
         """Returns True if the table cell is a header.
diff --git a/src/orca/scripts/apps/yelp/yelp_v3/script.py b/src/orca/scripts/apps/yelp/yelp_v3/script.py
index c7064b0..fba6baa 100644
--- a/src/orca/scripts/apps/yelp/yelp_v3/script.py
+++ b/src/orca/scripts/apps/yelp/yelp_v3/script.py
@@ -50,6 +50,7 @@ class Script(WebKitGtk.Script):
                         StructuralNavigation.FORM_FIELD,
                         StructuralNavigation.HEADING,
                         StructuralNavigation.LANDMARK,
+                        StructuralNavigation.LINK,
                         StructuralNavigation.LIST,
                         StructuralNavigation.LIST_ITEM,
                         StructuralNavigation.LIVE_REGION,
diff --git a/src/orca/scripts/toolkits/Gecko/script.py b/src/orca/scripts/toolkits/Gecko/script.py
index 17f3548..8fe7598 100644
--- a/src/orca/scripts/toolkits/Gecko/script.py
+++ b/src/orca/scripts/toolkits/Gecko/script.py
@@ -113,6 +113,7 @@ class Script(default.Script):
         self.speakCellSpanCheckButton = None
         self.speakResultsDuringFindCheckButton = None
         self.structuralNavigationCheckButton = None
+        self.listOfCheckButton = None
         self.grabFocusOnAncestorCheckButton = None
 
         # _caretNavigationFunctions are functions that represent fundamental
@@ -355,6 +356,7 @@ class Script(default.Script):
                         GeckoStructuralNavigation.FORM_FIELD,
                         GeckoStructuralNavigation.HEADING,
                         GeckoStructuralNavigation.LANDMARK,
+                        GeckoStructuralNavigation.LINK,
                         GeckoStructuralNavigation.LIST,
                         GeckoStructuralNavigation.LIST_ITEM,
                         GeckoStructuralNavigation.LIVE_REGION,
@@ -373,7 +375,8 @@ class Script(default.Script):
         """
         types = self.getEnabledStructuralNavigationTypes()
         enable = script_settings.structuralNavigationEnabled
-        return GeckoStructuralNavigation(self, types, enable)
+        lists = script_settings.listOfEnabled
+        return GeckoStructuralNavigation(self, types, enable, lists)
 
     def setupInputEventHandlers(self):
         """Defines InputEventHandler fields for this script that can be
@@ -711,6 +714,21 @@ class Script(default.Script):
         gtk.ToggleButton.set_active(self.structuralNavigationCheckButton,
                                     self.structuralNavigation.enabled)
 
+        # Translators: Orca provides keystrokes to present HTML content
+        # via 'List of ...' dialogs.
+        #
+        label = _("Use Orca '_List of ...' Dialogs")
+        self.listOfCheckButton = gtk.CheckButton(label)
+        gtk.Widget.show(self.listOfCheckButton)
+        gtk.Box.pack_start(generalVBox, self.listOfCheckButton, False, False, 0)
+        gtk.ToggleButton.set_active(self.listOfCheckButton,
+                                    self.structuralNavigation.listOfEnabled)
+        self.structuralNavigationCheckButton.connect(
+            "toggled",
+            lambda x: gtk.Widget.set_sensitive(
+                self.listOfCheckButton,
+                self.structuralNavigationCheckButton.get_active()))
+
         # Translators: Orca has had to implement its own caret navigation
         # model to work around issues in Gecko/Firefox. In certain versions
         # of Firefox, we must perform a focus grab on each object being
@@ -938,6 +956,11 @@ class Script(default.Script):
                          % (prefix, value))
         script_settings.structuralNavigationEnabled = value
 
+        value = self.listOfCheckButton.get_active()
+        prefs.writelines("%s.listOfEnabled = %s\n" \
+                         % (prefix, value))
+        script_settings.listOfEnabled = value
+
         value = self.grabFocusOnAncestorCheckButton.get_active()
         prefs.writelines("%s.grabFocusOnAncestor = %s\n" % (prefix, value))
         script_settings.grabFocusOnAncestor = value
@@ -1047,6 +1070,9 @@ class Script(default.Script):
                  and (handler.function in self.structuralNavigation.functions \
                       or handler.function in self._liveRegionFunctions):
                 return self.useStructuralNavigationModel()
+            elif handler and handler.function in \
+                self.structuralNavigation.listOfFunctions:
+                return self.structuralNavigation.listOfEnabled
             else:
                 consumes = handler != None
         if not consumes:
@@ -1057,6 +1083,9 @@ class Script(default.Script):
                  and (handler.function in self.structuralNavigation.functions \
                       or handler.function in self._liveRegionFunctions):
                 return self.useStructuralNavigationModel()
+            elif handler and handler.function in \
+                self.structuralNavigation.listOfFunctions:
+                return self.structuralNavigation.listOfEnabled
             else:
                 consumes = handler != None
         return consumes
diff --git a/src/orca/scripts/toolkits/Gecko/script_settings.py b/src/orca/scripts/toolkits/Gecko/script_settings.py
index 11d2a02..6c6099d 100644
--- a/src/orca/scripts/toolkits/Gecko/script_settings.py
+++ b/src/orca/scripts/toolkits/Gecko/script_settings.py
@@ -47,6 +47,10 @@ sayAllOnLoad = True
 #
 structuralNavigationEnabled = True
 
+# Whether or not to use the 'List of ...' dialogs.
+#
+listOfEnabled = False
+
 # Whether or not Orca should speak the changing location within the
 # document frame *during* a find (i.e. while focus is still in the
 # Find toolbar).
diff --git a/src/orca/scripts/toolkits/Gecko/structural_navigation.py b/src/orca/scripts/toolkits/Gecko/structural_navigation.py
index 341b71c..5123e9b 100644
--- a/src/orca/scripts/toolkits/Gecko/structural_navigation.py
+++ b/src/orca/scripts/toolkits/Gecko/structural_navigation.py
@@ -38,13 +38,14 @@ import orca.settings as settings
 
 class GeckoStructuralNavigation(structural_navigation.StructuralNavigation):
 
-    def __init__(self, script, enabledTypes, enabled):
+    def __init__(self, script, enabledTypes, enabled, listsEnabled):
         """Gecko specific Structural Navigation."""
 
         structural_navigation.StructuralNavigation.__init__(self,
                                                             script,
                                                             enabledTypes,
-                                                            enabled)
+                                                            enabled,
+                                                            listsEnabled)
 
     #####################################################################
     #                                                                   #
diff --git a/src/orca/scripts/toolkits/WebKitGtk/script.py b/src/orca/scripts/toolkits/WebKitGtk/script.py
index a3c2033..fe0487b 100644
--- a/src/orca/scripts/toolkits/WebKitGtk/script.py
+++ b/src/orca/scripts/toolkits/WebKitGtk/script.py
@@ -92,7 +92,7 @@ class Script(default.Script):
         """Returns the 'structural navigation' class for this script."""
 
         types = self.getEnabledStructuralNavigationTypes()
-        return StructuralNavigation(self, types, True)
+        return StructuralNavigation(self, types, True, True)
 
     def getUtilities(self):
         """Returns the utilites for this script."""
diff --git a/src/orca/scripts/toolkits/WebKitGtk/structural_navigation.py b/src/orca/scripts/toolkits/WebKitGtk/structural_navigation.py
index f3849ff..8de1160 100644
--- a/src/orca/scripts/toolkits/WebKitGtk/structural_navigation.py
+++ b/src/orca/scripts/toolkits/WebKitGtk/structural_navigation.py
@@ -37,13 +37,14 @@ import orca.structural_navigation as structural_navigation
 
 class StructuralNavigation(structural_navigation.StructuralNavigation):
 
-    def __init__(self, script, enabledTypes, enabled):
+    def __init__(self, script, enabledTypes, enabled, listsEnabled):
         """WebKitGtk specific Structural Navigation."""
 
         structural_navigation.StructuralNavigation.__init__(self,
                                                             script,
                                                             enabledTypes,
-                                                            enabled)
+                                                            enabled,
+                                                            listsEnabled)
         self.collectionEnabled = False
 
     def _getCaretPosition(self, obj):
diff --git a/src/orca/structural_navigation.py b/src/orca/structural_navigation.py
index 15f2a85..009e8f7 100644
--- a/src/orca/structural_navigation.py
+++ b/src/orca/structural_navigation.py
@@ -32,6 +32,7 @@ import pyatspi
 import debug
 import input_event
 import keybindings
+import object_navigator
 import orca
 import orca_state
 import settings
@@ -128,7 +129,7 @@ class StructuralNavigationObject:
     """
 
     def __init__(self, structuralNavigation, objType, bindings, predicate,
-                 criteria, presentation):
+                 criteria, presentation, navigator):
 
         """Creates a new structural navigation object.
 
@@ -149,6 +150,8 @@ class StructuralNavigationObject:
           via collection.
         - presentation: the method which should be called after performing
           the search for the structural navigation object.
+        - navigator: the method which should be called to show a list of the
+          structural navigation objects of the associated type.
         """
 
         self.structuralNavigation = structuralNavigation
@@ -157,10 +160,12 @@ class StructuralNavigationObject:
         self.predicate = predicate
         self.criteria = criteria
         self.present = presentation
+        self.navigator = navigator
 
         self.inputEventHandlers = {}
         self.keyBindings = keybindings.KeyBindings()
         self.functions = []
+        self.listOfFunctions = []
         self._setUpHandlersAndBindings()
 
     def _setUpHandlersAndBindings(self):
@@ -201,6 +206,22 @@ class StructuralNavigationObject:
 
             self.functions.append(self.goNext)
 
+        navigatorBinding = self.bindings.get("navigator")
+        if navigatorBinding and self.navigator:
+            [keysymstring, modifiers, description] = navigatorBinding
+            handlerName = "show%sNavigator" % self.objType
+            self.inputEventHandlers[handlerName] = \
+                input_event.InputEventHandler(self.navigator, description)
+
+            self.keyBindings.add(
+                keybindings.KeyBinding(
+                    keysymstring,
+                    settings.defaultModifierMask,
+                    modifiers,
+                    self.inputEventHandlers[handlerName]))
+
+            self.listOfFunctions.append(self.navigator)
+
         # Set up the "at level" handlers (e.g. to navigate among headings
         # at the specified level).
         #
@@ -242,6 +263,25 @@ class StructuralNavigationObject:
 
             self.functions.append(handler)
 
+        navigatorAtLevel = self.bindings.get("navigatorAtLevel") or []
+        for i, binding in enumerate(navigatorAtLevel):
+            level = i + 1
+            handler = self.showNavigatorAtLevelFactory(level)
+            handlerName = "show%sNavigatorAtLevel%d" % (self.objType, level)
+            keysymstring, modifiers, description = binding
+
+            self.inputEventHandlers[handlerName] = \
+                input_event.InputEventHandler(handler, description)
+
+            self.keyBindings.add(
+                keybindings.KeyBinding(
+                    keysymstring,
+                    settings.defaultModifierMask,
+                    modifiers,
+                    self.inputEventHandlers[handlerName]))
+
+            self.listOfFunctions.append(handler)
+
         # Set up the "directional" handlers (e.g. for table cells. Live
         # region support has a handler to go to the last live region,
         # so we'll handle that here as well).
@@ -401,6 +441,21 @@ class StructuralNavigationObject:
              and direction == "Last":
             return goLastLiveRegion
 
+    def showNavigatorAtLevelFactory(self, level):
+        """Generates a showObjectNavigator method for the specified level.
+        Right now, this is just for headings, but it may have applicability
+        for other objects such as list items (i.e. for level-based
+        navigation in an outline or other multi-tiered list.
+
+        Arguments:
+        - level: the desired level of the object as an int.
+        """
+
+        def showObjectNavigatorAtLevel(script, inputEvent):
+            self.navigator(script, inputEvent, arg=level)
+
+        return showObjectNavigatorAtLevel
+
 #############################################################################
 #                                                                           #
 # StructuralNavigation                                                      #
@@ -440,6 +495,7 @@ class StructuralNavigation:
     FORM_FIELD      = "formField"
     HEADING         = "heading"
     LANDMARK        = "landmark"
+    LINK            = "link"
     LIST            = "list"        # Bulleted/numbered lists
     LIST_ITEM       = "listItem"    # Bulleted/numbered list items
     LIVE_REGION     = "liveRegion"
@@ -485,7 +541,7 @@ class StructuralNavigation:
                     pyatspi.ROLE_SECTION,
                     pyatspi.ROLE_DOCUMENT_FRAME]
 
-    def __init__(self, script, enabledTypes, enabled=False):
+    def __init__(self, script, enabledTypes, enabled=False, listsEnabled=False):
         """Creates an instance of the StructuralNavigation class.
 
         Arguments:
@@ -497,10 +553,13 @@ class StructuralNavigation:
           enabled; in soffice, we would want to start out with it
           disabled and have the user enable it via a keystroke when
           desired.
+        - listsEnabled: Whether the 'List of ...' dialogs should start
+          out enabled.
         """
 
         self._script = script
         self.enabled = enabled
+        self.listOfEnabled = enabled and listsEnabled
 
         # Create all of the StructuralNavigationObject's in which the
         # script is interested, using the convenience method
@@ -511,6 +570,7 @@ class StructuralNavigation:
                 self.structuralNavigationObjectCreator(objType)
 
         self.functions = []
+        self.listOfFunctions = []
         self.inputEventHandlers = {}
         self.setupInputEventHandlers()
         self.keyBindings = self.getKeyBindings()
@@ -557,8 +617,13 @@ class StructuralNavigation:
         except:
             criteria = None
 
+        try:
+            navigator = eval("self._%sNavigator" % name)
+        except:
+            navigator = None
+
         return StructuralNavigationObject(self, name, bindings, predicate,
-                                          criteria, presentation)
+                                          criteria, presentation, navigator)
 
     def addObject(self, objType, structuralNavigationObject):
         """Adds structuralNavigationObject to the dictionary of enabled
@@ -594,6 +659,8 @@ class StructuralNavigation:
             self.inputEventHandlers.update(\
                 structuralNavigationObject.inputEventHandlers)
             self.functions.extend(structuralNavigationObject.functions)
+            self.listOfFunctions.extend(
+                structuralNavigationObject.listOfFunctions)
 
     def getKeyBindings(self):
         """Defines the structural navigation key bindings for a script.
@@ -1862,6 +1929,11 @@ class StructuralNavigation:
         #
         nextDesc = _("Goes to next anchor.")
         bindings["next"] = ["a", settings.NO_MODIFIER_MASK, nextDesc]
+        # Translators: this is for showing a list of anchors contained in a
+        # document. An anchor is a named spot that one can jump to.
+        #
+        naviDesc = _("Show a list of anchors.")
+        bindings["navigator"] = ["a", settings.ORCA_MODIFIER_MASK, naviDesc]
         return bindings
 
     def _anchorCriteria(self, collection, arg=None):
@@ -1882,6 +1954,27 @@ class StructuralNavigation:
                              matchStates=stateMatch,
                              roles=role)
 
+    def _anchorNavigator(self, script, inputEvent, arg=None):
+        """Show the Object Navigator with a list of anchors.
+
+        Arguments:
+        - script: the script with which this instance is associated.
+        - inputEvent: the inputEvent that was triggered.
+        - arg: an optional argument which may need to be included in
+          the predicate (e.g. the level of a heading).
+        """
+
+        object_navigator.showObjectNavigator(
+            script,
+            # Translators: this is the objectType, used to set the window title
+            # and speak messages for the Object Navigator.
+            #
+            _("anchors"),
+            self._getDocument(),
+            self._anchorPredicate,
+            self._anchorPresentation,
+            arg)
+
     def _anchorPredicate(self, obj, arg=None):
         """The predicate to be used for verifying that the object
         obj is an anchor.
@@ -1952,6 +2045,11 @@ class StructuralNavigation:
         #
         nextDesc = _("Goes to next blockquote.")
         bindings["next"] = ["q", settings.NO_MODIFIER_MASK, nextDesc]
+        # Translators: this is for showing a list of blockquotes contained in
+        # a document.
+        #
+        naviDesc = _("Show a list of blockquotes.")
+        bindings["navigator"] = ["F1", settings.ORCA_MODIFIER_MASK, naviDesc]
         return bindings
 
     def _blockquoteCriteria(self, collection, arg=None):
@@ -1967,6 +2065,27 @@ class StructuralNavigation:
         attrs = ['tag:BLOCKQUOTE']
         return MatchCriteria(collection, objAttrs=attrs)
 
+    def _blockquoteNavigator(self, script, inputEvent, arg=None):
+        """Show the Object Navigator with a list of blockquotes.
+
+        Arguments:
+        - script: the script with which this instance is associated.
+        - inputEvent: the inputEvent that was triggered.
+        - arg: an optional argument which may need to be included in
+          the predicate (e.g. the level of a heading).
+        """
+
+        object_navigator.showObjectNavigator(
+            script,
+            # Translators: this is the objectType, used to set the window title
+            # and speak messages for the Object Navigator.
+            #
+            _("blockquotes"),
+            self._getDocument(),
+            self._blockquotePredicate,
+            self._blockquotePresentation,
+            arg)
+
     def _blockquotePredicate(self, obj, arg=None):
         """The predicate to be used for verifying that the object
         obj is a blockquote.
@@ -2046,6 +2165,11 @@ class StructuralNavigation:
         #
         nextDesc = _("Goes to next button.")
         bindings["next"] = ["b", settings.NO_MODIFIER_MASK, nextDesc]
+        # Translators: this is for showing a list of buttons contained in a
+        # document.
+        #
+        naviDesc = _("Show a list of buttons.")
+        bindings["navigator"] = ["F2", settings.ORCA_MODIFIER_MASK, naviDesc]
         return bindings
 
     def _buttonCriteria(self, collection, arg=None):
@@ -2066,6 +2190,27 @@ class StructuralNavigation:
                              matchStates=stateMatch,
                              roles=role)
 
+    def _buttonNavigator(self, script, inputEvent, arg=None):
+        """Show the Object Navigator with a list of buttons.
+
+        Arguments:
+        - script: the script with which this instance is associated.
+        - inputEvent: the inputEvent that was triggered.
+        - arg: an optional argument which may need to be included in
+          the predicate (e.g. the level of a heading).
+        """
+
+        object_navigator.showObjectNavigator(
+            script,
+            # Translators: this is the objectType, used to set the window title
+            # and speak messages for the Object Navigator.
+            #
+            _("buttons"),
+            self._getDocument(),
+            self._buttonPredicate,
+            self._buttonPresentation,
+            arg)
+
     def _buttonPredicate(self, obj, arg=None):
         """The predicate to be used for verifying that the object
         obj is a button.
@@ -2136,6 +2281,11 @@ class StructuralNavigation:
         #
         nextDesc = _("Goes to next check box.")
         bindings["next"] = ["x", settings.NO_MODIFIER_MASK, nextDesc]
+        # Translators: this is for showing a list of check boxes contained in
+        # a document.
+        #
+        naviDesc = _("Show a list of check boxes.")
+        bindings["navigator"] = ["x", settings.ORCA_MODIFIER_MASK, naviDesc]
         return bindings
 
     def _checkBoxCriteria(self, collection, arg=None):
@@ -2156,6 +2306,27 @@ class StructuralNavigation:
                              matchStates=stateMatch,
                              roles=role)
 
+    def _checkBoxNavigator(self, script, inputEvent, arg=None):
+        """Show the Object Navigator with a list of check boxes.
+
+        Arguments:
+        - script: the script with which this instance is associated.
+        - inputEvent: the inputEvent that was triggered.
+        - arg: an optional argument which may need to be included in
+          the predicate (e.g. the level of a heading).
+        """
+
+        object_navigator.showObjectNavigator(
+            script,
+            # Translators: this is the objectType, used to set the window title
+            # and speak messages for the Object Navigator.
+            #
+            _("check boxes"),
+            self._getDocument(),
+            self._checkBoxPredicate,
+            self._checkBoxPresentation,
+            arg)
+
     def _checkBoxPredicate(self, obj, arg=None):
         """The predicate to be used for verifying that the object
         obj is a check box.
@@ -2228,9 +2399,12 @@ class StructuralNavigation:
         #
         nextDesc = _("Goes to next large object.")
         bindings["next"] = ["o", settings.NO_MODIFIER_MASK, nextDesc]
-        # I don't think it makes sense to add support for a list
-        # of chunks.  But one could always change that here.
+        # Translators: this is for showing a list of 'large objects' contained
+        # in a document. A 'large object' is a logical chunk of text, such as
+        # a paragraph, a list, a table, etc.
         #
+        naviDesc = _("Show a list of large objects.")
+        bindings["navigator"] = ["o", settings.ORCA_MODIFIER_MASK, naviDesc]
         return bindings
 
     def _chunkCriteria(self, collection, arg=None):
@@ -2250,6 +2424,27 @@ class StructuralNavigation:
                              matchRoles=roleMatch,
                              applyPredicate=True)
 
+    def _chunkNavigator(self, script, inputEvent, arg=None):
+        """Show the Object Navigator with a list of large objects.
+
+        Arguments:
+        - script: the script with which this instance is associated.
+        - inputEvent: the inputEvent that was triggered.
+        - arg: an optional argument which may need to be included in
+          the predicate (e.g. the level of a heading).
+        """
+
+        object_navigator.showObjectNavigator(
+            script,
+            # Translators: this is the objectType, used to set the window title
+            # and speak messages for the Object Navigator.
+            #
+            _("large objects"),
+            self._getDocument(),
+            self._chunkPredicate,
+            self._chunkPresentation,
+            arg)
+
     def _chunkPredicate(self, obj, arg=None):
         """The predicate to be used for verifying that the object
         obj is a chunk.
@@ -2331,6 +2526,11 @@ class StructuralNavigation:
         #
         nextDesc = _("Goes to next combo box.")
         bindings["next"] = ["c", settings.NO_MODIFIER_MASK, nextDesc]
+        # Translators: this is for showing a list of combo boxes contained
+        # in a document.
+        #
+        naviDesc = _("Show a list of combo boxes.")
+        bindings["navigator"] = ["c", settings.ORCA_MODIFIER_MASK, naviDesc]
         return bindings
 
     def _comboBoxCriteria(self, collection, arg=None):
@@ -2351,6 +2551,27 @@ class StructuralNavigation:
                              matchStates=stateMatch,
                              roles=role)
 
+    def _comboBoxNavigator(self, script, inputEvent, arg=None):
+        """Show the Object Navigator with a list of combo boxes.
+
+        Arguments:
+        - script: the script with which this instance is associated.
+        - inputEvent: the inputEvent that was triggered.
+        - arg: an optional argument which may need to be included in
+          the predicate (e.g. the level of a heading).
+        """
+
+        object_navigator.showObjectNavigator(
+            script,
+            # Translators: this is the objectType, used to set the window title
+            # and speak messages for the Object Navigator.
+            #
+            _("combo boxes"),
+            self._getDocument(),
+            self._comboBoxPredicate,
+            self._comboBoxPresentation,
+            arg)
+
     def _comboBoxPredicate(self, obj, arg=None):
         """The predicate to be used for verifying that the object
         obj is a combo box.
@@ -2421,6 +2642,11 @@ class StructuralNavigation:
         #
         nextDesc = _("Goes to next entry.")
         bindings["next"] = ["e", settings.NO_MODIFIER_MASK, nextDesc]
+        # Translators: this is for showing a list of entries in a form
+        # contained in a document.
+        #
+        naviDesc = _("Show a list of entries.")
+        bindings["navigator"] = ["e", settings.ORCA_MODIFIER_MASK, naviDesc]
         return bindings
 
     def _entryCriteria(self, collection, arg=None):
@@ -2449,6 +2675,27 @@ class StructuralNavigation:
                              matchRoles=roleMatch,
                              applyPredicate=True)
 
+    def _entryNavigator(self, script, inputEvent, arg=None):
+        """Show the Object Navigator with a list of entries.
+
+        Arguments:
+        - script: the script with which this instance is associated.
+        - inputEvent: the inputEvent that was triggered.
+        - arg: an optional argument which may need to be included in
+          the predicate (e.g. the level of a heading).
+        """
+
+        object_navigator.showObjectNavigator(
+            script,
+            # Translators: this is the objectType, used to set the window title
+            # and speak messages for the Object Navigator.
+            #
+            _("entries"),
+            self._getDocument(),
+            self._entryPredicate,
+            self._entryPresentation,
+            arg)
+
     def _entryPredicate(self, obj, arg=None):
         """The predicate to be used for verifying that the object
         obj is an entry.
@@ -2525,6 +2772,11 @@ class StructuralNavigation:
         #
         nextDesc = _("Goes to next form field.")
         bindings["next"] = ["Tab", settings.ORCA_MODIFIER_MASK, nextDesc]
+        # Translators: this is for showing a list of fields in a form
+        # contained in a document.
+        #
+        naviDesc = _("Show a list of form fields.")
+        bindings["navigator"] = ["F5", settings.ORCA_MODIFIER_MASK, naviDesc]
         return bindings
 
     def _formFieldCriteria(self, collection, arg=None):
@@ -2548,6 +2800,27 @@ class StructuralNavigation:
                              matchRoles=roleMatch,
                              applyPredicate=True)
 
+    def _formFieldNavigator(self, script, inputEvent, arg=None):
+        """Show the Object Navigator with a list of form fields.
+
+        Arguments:
+        - script: the script with which this instance is associated.
+        - inputEvent: the inputEvent that was triggered.
+        - arg: an optional argument which may need to be included in
+          the predicate (e.g. the level of a heading).
+        """
+
+        object_navigator.showObjectNavigator(
+            script,
+            # Translators: this is the objectType, used to set the window title
+            # and speak messages for the Object Navigator.
+            #
+            _("form fields"),
+            self._getDocument(),
+            self._formFieldPredicate,
+            self._formFieldPresentation,
+            arg)
+
     def _formFieldPredicate(self, obj, arg=None):
         """The predicate to be used for verifying that the object
         obj is a form field.
@@ -2630,9 +2903,15 @@ class StructuralNavigation:
         #
         nextDesc = _("Goes to next heading.")
         bindings["next"] = ["h", settings.NO_MODIFIER_MASK, nextDesc]
+        # Translators: this is for showing a list of headings contained in a
+        # document. (e.g. <h1>)
+        #
+        naviDesc = _("Show a list of headings.")
+        bindings["navigator"] = ["F6", settings.ORCA_MODIFIER_MASK, naviDesc]
 
         prevAtLevelBindings = []
         nextAtLevelBindings = []
+        naviAtLevelBindings = []
         minLevel, maxLevel = self._headingLevels()
         for i in range(minLevel, maxLevel + 1):
             # Translators: this is for navigating in a document by heading.
@@ -2649,8 +2928,16 @@ class StructuralNavigation:
             nextAtLevelBindings.append([str(i),
                                         settings.NO_MODIFIER_MASK,
                                         nextDesc])
+            # Translators: this for showing a list of headings contained in a
+            # document. (e.h. <h1> is a heading at level 1).
+            #
+            naviDesc = _("Show a list of headings at level %d.") % i
+            naviAtLevelBindings.append([str(i),
+                                        settings.ORCA_MODIFIER_MASK,
+                                        naviDesc])
         bindings["previousAtLevel"] = prevAtLevelBindings
         bindings["nextAtLevel"] = nextAtLevelBindings
+        bindings["navigatorAtLevel"] = naviAtLevelBindings
         return bindings
 
     def _headingLevels(self):
@@ -2679,6 +2966,35 @@ class StructuralNavigation:
                              roles=role,
                              objAttrs=attrs)
 
+    def _headingNavigator(self, script, inputEvent, arg=None):
+        """Show the Object Navigator with a list of headings.
+
+        Arguments:
+        - script: the script with which this instance is associated.
+        - inputEvent: the inputEvent that was triggered.
+        - arg: an optional argument which may need to be included in
+          the predicate (e.g. the level of a heading).
+        """
+
+        if arg:
+            # Translators: this is the objectType, used to set the window title
+            # and speak messages for the Object Navigator.
+            #
+            objectName = _("headings of level %d") % arg
+        else:
+            # Translators: this is the objectType, used to set the window title
+            # and speak messages for the Object Navigator.
+            #
+            objectName = _("headings")
+
+        object_navigator.showObjectNavigator(
+            script,
+            objectName,
+            self._getDocument(),
+            self._headingPredicate,
+            self._headingPresentation,
+            arg)
+
     def _headingPredicate(self, obj, arg=None):
         """The predicate to be used for verifying that the object
         obj is a heading.
@@ -2774,6 +3090,13 @@ class StructuralNavigation:
         #
         nextDesc = _("Goes to next landmark.")
         bindings["next"] = ["m", settings.NO_MODIFIER_MASK, nextDesc]
+        # Translators: this is for showing a list of ARIA role landmarks
+        # contained in a document. ARIA role landmarks are the W3C defined
+        # HTML tag attribute 'role' used to identify important part of
+        # webpage like banners, main context, search etc.
+        #
+        naviDesc = _("Show a list of landmarks.")
+        bindings["navigator"] = ["m", settings.ORCA_MODIFIER_MASK, naviDesc]
         return bindings
 
     def _landmarkCriteria(self, collection, arg=None):
@@ -2802,6 +3125,27 @@ class StructuralNavigation:
 
         return MatchCriteria(collection, objAttrs=attrs)
 
+    def _landmarkNavigator(self, script, inputEvent, arg=None):
+        """Show the Object Navigator with a list of landmarks.
+
+        Arguments:
+        - script: the script with which this instance is associated.
+        - inputEvent: the inputEvent that was triggered.
+        - arg: an optional argument which may need to be included in
+          the predicate (e.g. the level of a heading).
+        """
+
+        object_navigator.showObjectNavigator(
+            script,
+            # Translators: this is the objectType, used to set the window title
+            # and speak messages for the Object Navigator.
+            #
+            _("landmarks"),
+            self._getDocument(),
+            self._landmarkPredicate,
+            self._landmarkPresentation,
+            arg)
+
     def _landmarkPredicate(self, obj, arg=None):
         """The predicate to be used for verifying that the object
         obj is a landmark.
@@ -2860,6 +3204,124 @@ class StructuralNavigation:
 
     ########################
     #                      #
+    # Links                #
+    #                      #
+    ########################
+
+    def _linkBindings(self):
+        """Returns a dictionary of [keysymstring, modifiers, description]
+        lists for navigating amongst links.
+        """
+
+        bindings = {}
+        # Navigating to the next previous or next link is internal implemented
+        # by browsers.
+
+        # Translators: this is for showing a list of links contained in a
+        # document.
+        #
+        naviDesc = _("Show a list of links.")
+        bindings["navigator"] = ["F7", settings.ORCA_MODIFIER_MASK, naviDesc]
+        return bindings
+
+    def _linkCriteria(self, collection, arg=None):
+        """Returns the MatchCriteria to be used for locating links by
+        collection.
+
+        Arguments:
+        - collection: the collection interface for the document
+        - arg: an optional argument which may need to be included in
+          the criteria (e.g. the level of a heading).
+        """
+
+        role = [pyatspi.ROLE_LINK]
+        return MatchCriteria(collection, roles=role)
+
+    def _linkNavigator(self, script, inputEvent, arg=None):
+        """Show the Object Navigator with a list of links.
+
+        Arguments:
+        - script: the script with which this instance is associated.
+        - inputEvent: the inputEvent that was triggered.
+        - arg: an optional argument which may need to be included in
+          the predicate (e.g. the level of a heading).
+        """
+
+        object_navigator.showObjectNavigator(
+            script,
+            # Translators: this is the objectType, used to set the window title
+            # and speak messages for the Object Navigator.
+            #
+            _("links"),
+            self._getDocument(),
+            self._linkPredicate,
+            self._linkNavigatorPresentation,
+            arg)
+
+    def _linkNavigatorPresentation(self, obj, arg=None):
+        """Presents the link or indicates that one was not
+        found (Object Navigator version).
+
+        Arguments:
+        - obj: the accessible object under consideration.
+        - arg: an optional argument which may need to be included in
+          the criteria (e.g. the level of a heading).
+        """
+
+        try:
+            action = obj.queryAction()
+        except NotImplementedError:
+            pass
+        else:
+            for i in range(action.nActions):
+                if action.getName(i) == "jump":
+                    action.doAction(i)
+                    break
+
+    def _linkPredicate(self, obj, arg=None):
+        """The predicate to be used for verifying that the object obj
+        is a link.
+
+        Arguments:
+        - obj: the accessible object under consideration.
+        - arg: an optional argument which may need to be included in
+          the criteria (e.g. the level of a heading).
+        """
+
+        return obj and obj.getRole() == pyatspi.ROLE_LINK
+
+    def _linkPresentation(self, obj, arg=None):
+        """Presents the link or indicates that one was not
+        found.
+
+        Arguments:
+        - obj: the accessible object under consideration.
+        - arg: an optional argument which may need to be included in
+          the criteria (e.g. the level of a heading).
+        """
+
+        if obj:
+            obj.queryComponent().grabFocus()
+        else:
+            # Translators: this is for navigating document content by moving
+            # from link to link. This string is the detailed message which
+            # Orca will present if there are no more links found.
+            #
+            full = _("No more links.")
+            # Translators: Orca has a command that allows the user to move
+            # to the next structural navigation object. In Orca, "structural
+            # navigation" refers to quickly moving through a document by
+            # jumping amongst objects of a given type, such as from link to
+            # link, or from heading to heading, or from form field to form
+            # field. This is a brief message which will be presented to the
+            # user if the desired structural navigation object could not be
+            # found.
+            #
+            brief = C_("structural navigation", "Not found")
+            self._script.presentMessage(full, brief)
+
+    ########################
+    #                      #
     # Lists                #
     #                      #
     ########################
@@ -2880,6 +3342,11 @@ class StructuralNavigation:
         #
         nextDesc = _("Goes to next list.")
         bindings["next"] = ["l", settings.NO_MODIFIER_MASK, nextDesc]
+        # Translators: this is for showing a list of bulleted/numbered lists
+        # contained in a document.
+        #
+        naviDesc = _("Show a list of lists.")
+        bindings["navigator"] = ["l", settings.ORCA_MODIFIER_MASK, naviDesc]
         return bindings
 
     def _listCriteria(self, collection, arg=None):
@@ -2900,6 +3367,27 @@ class StructuralNavigation:
                              matchStates=stateMatch,
                              roles=role)
 
+    def _listNavigator(self, script, inputEvent, arg=None):
+        """Show the Object Navigator with a list of lists.
+
+        Arguments:
+        - script: the script with which this instance is associated.
+        - inputEvent: the inputEvent that was triggered.
+        - arg: an optional argument which may need to be included in
+          the predicate (e.g. the level of a heading).
+        """
+
+        object_navigator.showObjectNavigator(
+            script,
+            # Translators: this is the objectType, used to set the window title
+            # and speak messages for the Object Navigator.
+            #
+            _("lists"),
+            self._getDocument(),
+            self._listPredicate,
+            self._listPresentation,
+            arg)
+
     def _listPredicate(self, obj, arg=None):
         """The predicate to be used for verifying that the object
         obj is an (un)ordered list.
@@ -2998,6 +3486,11 @@ class StructuralNavigation:
         #
         nextDesc = _("Goes to next list item.")
         bindings["next"] = ["i", settings.NO_MODIFIER_MASK, nextDesc]
+        # Translators: this is for showing a list of bulleted/numbered list
+        # items contained in a document.
+        #
+        naviDesc = _("Show a list of list items.")
+        bindings["navigator"] = ["i", settings.ORCA_MODIFIER_MASK, naviDesc]
         return bindings
 
     def _listItemCriteria(self, collection, arg=None):
@@ -3018,6 +3511,27 @@ class StructuralNavigation:
                              matchStates=stateMatch,
                              roles=role)
 
+    def _listItemNavigator(self, script, inputEvent, arg=None):
+        """Show the Object Navigator with a list of list items.
+
+        Arguments:
+        - script: the script with which this instance is associated.
+        - inputEvent: the inputEvent that was triggered.
+        - arg: an optional argument which may need to be included in
+          the predicate (e.g. the level of a heading).
+        """
+
+        object_navigator.showObjectNavigator(
+            script,
+            # Translators: this is the objectType, used to set the window title
+            # and speak messages for the Object Navigator.
+            #
+            _("list items"),
+            self._getDocument(),
+            self._listItemPredicate,
+            self._listItemPresentation,
+            arg)
+
     def _listItemPredicate(self, obj, arg=None):
         """The predicate to be used for verifying that the object
         obj is an item in an (un)ordered list.
@@ -3092,6 +3606,11 @@ class StructuralNavigation:
         #
         nextDesc = _("Goes to next live region.")
         bindings["next"] = ["d", settings.NO_MODIFIER_MASK, nextDesc]
+        # Translators: this is for showing a list of live regions contained
+        # in a document.
+        #
+        naviDesc = _("Show a list of live regions.")
+        bindings["navigator"] = ["y", settings.ORCA_MODIFIER_MASK, naviDesc]
         # Translators: this is for navigating to the last live region
         # which made an announcement.
         #
@@ -3099,6 +3618,27 @@ class StructuralNavigation:
         bindings["last"] = ["y", settings.NO_MODIFIER_MASK, desc]
         return bindings
 
+    def _liveRegionNavigator(self, script, inputEvent, arg=None):
+        """Show the Object Navigator with a list of live regions.
+
+        Arguments:
+        - script: the script with which this instance is associated.
+        - inputEvent: the inputEvent that was triggered.
+        - arg: an optional argument which may need to be included in
+          the predicate (e.g. the level of a heading).
+        """
+
+        object_navigator.showObjectNavigator(
+            script,
+            # Translators: this is the objectType, used to set the window title
+            # and speak messages for the Object Navigator.
+            #
+            _("live regions"),
+            self._getDocument(),
+            self._liveRegionPredicate,
+            self._liveRegionPresentation,
+            arg)
+
     def _liveRegionPredicate(self, obj, arg=None):
         """The predicate to be used for verifying that the object
         obj is a live region.
@@ -3177,6 +3717,11 @@ class StructuralNavigation:
         #
         nextDesc = _("Goes to next paragraph.")
         bindings["next"] = ["p", settings.NO_MODIFIER_MASK, nextDesc]
+        # Translators: this is for showing a list of paragraphs contained
+        # in a document.
+        #
+        naviDesc = _("Show a list of paragraphs.")
+        bindings["navigator"] = ["p", settings.ORCA_MODIFIER_MASK, naviDesc]
         return bindings
 
     def _paragraphCriteria(self, collection, arg=None):
@@ -3192,6 +3737,27 @@ class StructuralNavigation:
         role = [pyatspi.ROLE_PARAGRAPH]
         return MatchCriteria(collection, roles=role, applyPredicate=True)
 
+    def _paragraphNavigator(self, script, inputEvent, arg=None):
+        """Show the Object Navigator with a list of paragraphs.
+
+        Arguments:
+        - script: the script with which this instance is associated.
+        - inputEvent: the inputEvent that was triggered.
+        - arg: an optional argument which may need to be included in
+          the predicate (e.g. the level of a heading).
+        """
+
+        object_navigator.showObjectNavigator(
+            script,
+            # Translators: this is the objectType, used to set the window title
+            # and speak messages for the Object Navigator.
+            #
+            _("paragraphs"),
+            self._getDocument(),
+            self._paragraphPredicate,
+            self._paragraphPresentation,
+            arg)
+
     def _paragraphPredicate(self, obj, arg=None):
         """The predicate to be used for verifying that the object
         obj is a paragraph.
@@ -3270,6 +3836,11 @@ class StructuralNavigation:
         #
         nextDesc = _("Goes to next radio button.")
         bindings["next"] = ["r", settings.NO_MODIFIER_MASK, nextDesc]
+        # Translators: this is for showing a list of radio buttons in a form
+        # contained in a document.
+        #
+        naviDesc = _("Show a list of radio buttons.")
+        bindings["navigator"] = ["r", settings.ORCA_MODIFIER_MASK, naviDesc]
         return bindings
 
     def _radioButtonCriteria(self, collection, arg=None):
@@ -3290,6 +3861,27 @@ class StructuralNavigation:
                              matchStates=stateMatch,
                              roles=role)
 
+    def _radioButtonNavigator(self, script, inputEvent, arg=None):
+        """Show the Object Navigator with a list of radio buttons.
+
+        Arguments:
+        - script: the script with which this instance is associated.
+        - inputEvent: the inputEvent that was triggered.
+        - arg: an optional argument which may need to be included in
+          the predicate (e.g. the level of a heading).
+        """
+
+        object_navigator.showObjectNavigator(
+            script,
+            # Translators: this is the objectType, used to set the window title
+            # and speak messages for the Object Navigator.
+            #
+            _("radio buttons"),
+            self._getDocument(),
+            self._radioButtonPredicate,
+            self._radioButtonPresentation,
+            arg)
+
     def _radioButtonPredicate(self, obj, arg=None):
         """The predicate to be used for verifying that the object
         obj is a radio button.
@@ -3360,6 +3952,11 @@ class StructuralNavigation:
         #
         nextDesc = _("Goes to next separator.")
         bindings["next"] = ["s", settings.NO_MODIFIER_MASK, nextDesc]
+        # Translators: this is for showing a list of separators contained
+        # in a document.
+        #
+        naviDesc = _("Show a list of separators.")
+        bindings["navigator"] = ["F3", settings.ORCA_MODIFIER_MASK, naviDesc]
         return bindings
 
     def _separatorCriteria(self, collection, arg=None):
@@ -3375,6 +3972,27 @@ class StructuralNavigation:
         role = [pyatspi.ROLE_SEPARATOR]
         return MatchCriteria(collection, roles=role, applyPredicate=False)
 
+    def _separatorNavigator(self, script, inputEvent, arg=None):
+        """Show the Object Navigator with a list of separators.
+
+        Arguments:
+        - script: the script with which this instance is associated.
+        - inputEvent: the inputEvent that was triggered.
+        - arg: an optional argument which may need to be included in
+          the predicate (e.g. the level of a heading).
+        """
+
+        object_navigator.showObjectNavigator(
+            script,
+            # Translators: this is the objectType, used to set the window title
+            # and speak messages for the Object Navigator.
+            #
+            _("separators"),
+            self._getDocument(),
+            self._separatorPredicate,
+            self._separatorPresentation,
+            arg)
+
     def _separatorPredicate(self, obj, arg=None):
         """The predicate to be used for verifying that the object
         obj is a separator.
@@ -3439,6 +4057,11 @@ class StructuralNavigation:
         #
         nextDesc = _("Goes to next table.")
         bindings["next"] = ["t", settings.NO_MODIFIER_MASK, nextDesc]
+        # Translators: this is for showing a list of tables contained in
+        # a document.
+        #
+        naviDesc = _("Show a list of tables.")
+        bindings["navigator"] = ["F4", settings.ORCA_MODIFIER_MASK, naviDesc]
         return bindings
 
     def _tableCriteria(self, collection, arg=None):
@@ -3454,6 +4077,27 @@ class StructuralNavigation:
         role = [pyatspi.ROLE_TABLE]
         return MatchCriteria(collection, roles=role, applyPredicate=True)
 
+    def _tableNavigator(self, script, inputEvent, arg=None):
+        """Show the Object Navigator with a list of tables.
+
+        Arguments:
+        - script: the script with which this instance is associated.
+        - inputEvent: the inputEvent that was triggered.
+        - arg: an optional argument which may need to be included in
+          the predicate (e.g. the level of a heading).
+        """
+
+        object_navigator.showObjectNavigator(
+            script,
+            # Translators: this is the objectType, used to set the window title
+            # and speak messages for the Object Navigator.
+            #
+            _("tables"),
+            self._getDocument(),
+            self._tablePredicate,
+            self._tablePresentation,
+            arg)
+
     def _tablePredicate(self, obj, arg=None):
         """The predicate to be used for verifying that the object
         obj is a table.
@@ -3635,6 +4279,11 @@ class StructuralNavigation:
         #
         nextDesc = _("Goes to next unvisited link.")
         bindings["next"] = ["u", settings.NO_MODIFIER_MASK, nextDesc]
+        # Translators: this is for showing a list of unvisited links
+        # contained in a document.
+        #
+        naviDesc = _("Show a list of unvisited links.")
+        bindings["navigator"] = ["u", settings.ORCA_MODIFIER_MASK, naviDesc]
         return bindings
 
     def _unvisitedLinkCriteria(self, collection, arg=None):
@@ -3655,6 +4304,47 @@ class StructuralNavigation:
                              matchStates=stateMatch,
                              roles=role)
 
+    def _unvisitedLinkNavigator(self, script, inputEvent, arg=None):
+        """Show the Object Navigator with a list of unvisited links.
+
+        Arguments:
+        - script: the script with which this instance is associated.
+        - inputEvent: the inputEvent that was triggered.
+        - arg: an optional argument which may need to be included in
+          the predicate (e.g. the level of a heading).
+        """
+
+        object_navigator.showObjectNavigator(
+            script,
+            # Translators: this is the objectType, used to set the window title
+            # and speak messages for the Object Navigator.
+            #
+            _("unvisited links"),
+            self._getDocument(),
+            self._unvisitedLinkPredicate,
+            self._unvisitedLinkNavigatorPresentation,
+            arg)
+
+    def _unvisitedLinkNavigatorPresentation(self, obj, arg=None):
+        """Presents the link or indicates that one was not
+        found (Object Navigator version).
+
+        Arguments:
+        - obj: the accessible object under consideration.
+        - arg: an optional argument which may need to be included in
+          the criteria (e.g. the level of a heading).
+        """
+
+        try:
+            action = obj.queryAction()
+        except NotImplementedError:
+            pass
+        else:
+            for i in range(action.nActions):
+                if action.getName(i) == "jump":
+                    action.doAction(i)
+                    break
+
     def _unvisitedLinkPredicate(self, obj, arg=None):
         """The predicate to be used for verifying that the object
         obj is an unvisited link.
@@ -3731,6 +4421,11 @@ class StructuralNavigation:
         #
         nextDesc = _("Goes to next visited link.")
         bindings["next"] = ["v", settings.NO_MODIFIER_MASK, nextDesc]
+        # Translators: this is for showing a list of visited links
+        # contained in a document.
+        #
+        naviDesc = _("Show a list of visited links.")
+        bindings["navigator"] = ["v", settings.ORCA_MODIFIER_MASK, naviDesc]
         return bindings
 
     def _visitedLinkCriteria(self, collection, arg=None):
@@ -3751,6 +4446,47 @@ class StructuralNavigation:
                              matchStates=stateMatch,
                              roles=role)
 
+    def _visitedLinkNavigator(self, script, inputEvent, arg=None):
+        """Show the Object Navigator with a list of visited links.
+
+        Arguments:
+        - script: the script with which this instance is associated.
+        - inputEvent: the inputEvent that was triggered.
+        - arg: an optional argument which may need to be included in
+          the predicate (e.g. the level of a heading).
+        """
+
+        object_navigator.showObjectNavigator(
+            script,
+            # Translators: this is the objectType, used to set the window title
+            # and speak messages for the Object Navigator.
+            #
+            _("visited links"),
+            self._getDocument(),
+            self._visitedLinkPredicate,
+            self._visitedLinkNavigatorPresentation,
+            arg)
+
+    def _visitedLinkNavigatorPresentation(self, obj, arg=None):
+        """Presents the link or indicates that one was not
+        found (Object Navigator version).
+
+        Arguments:
+        - obj: the accessible object under consideration.
+        - arg: an optional argument which may need to be included in
+          the criteria (e.g. the level of a heading).
+        """
+
+        try:
+            action = obj.queryAction()
+        except NotImplementedError:
+            pass
+        else:
+            for i in range(action.nActions):
+                if action.getName(i) == "jump":
+                    action.doAction(i)
+                    break
+
     def _visitedLinkPredicate(self, obj, arg=None):
         """The predicate to be used for verifying that the object
         obj is a visited link.
