Index: src/orca/orca_prefs.py
===================================================================
--- src/orca/orca_prefs.py	(revision 3203)
+++ src/orca/orca_prefs.py	(working copy)
@@ -31,7 +31,8 @@
 import settings
 
 # The same fields than in orca_gui_prefs.py:
-(HANDLER, DESCRIP, MOD_MASK1, MOD_USED1, KEY1, TEXT1, MOD_MASK2, MOD_USED2, KEY2, TEXT2, MODIF, EDITABLE) = range(12)
+(HANDLER, DESCRIP, MOD_MASK1, MOD_USED1, KEY1, OLDTEXT1, TEXT1, \
+ MOD_MASK2, MOD_USED2, KEY2, OLDTEXT2, TEXT2, MODIF, EDITABLE) = range(14)
 
 (ACTUAL, REPLACEMENT) = range(2)
 
@@ -388,6 +389,13 @@
 
         prefs.writelines("   keyB.removeByHandler(script.inputEventHandlers['" \
                          + str(tupl[HANDLER])+"'])\n")
+        if not (tupl[TEXT1] or tupl[TEXT2]):
+            prefs.writelines("   keyB.add(orca.keybindings.KeyBinding(\n")
+            prefs.writelines("      None,\n")
+            prefs.writelines("      0,\n")
+            prefs.writelines("      0,\n")
+            prefs.writelines('      script.inputEventHandlers["' + \
+                             str(tupl[HANDLER]) +'"]))\n\n')
 
         if (tupl[TEXT1]):
             prefs.writelines("   keyB.add(orca.keybindings.KeyBinding(\n")
@@ -431,7 +439,8 @@
         while thisIter != None:
             iterChild = treeModel.iter_children(thisIter)
             while iterChild != None:
-                values = treeModel.get(iterChild, 0,1,2,3,4,5,6,7,8,9,10,11)
+                values = treeModel.get(iterChild,
+                                       0,1,2,3,4,5,6,7,8,9,10,11,12,13)
                 if values[MODIF]:
                     self._writeKeyBinding(prefs, values)
                 iterChild = treeModel.iter_next(iterChild)
Index: src/orca/app_gui_prefs.py
===================================================================
--- src/orca/app_gui_prefs.py	(revision 3203)
+++ src/orca/app_gui_prefs.py	(working copy)
@@ -152,6 +152,9 @@
         - clearModel: if True, initially clear out the key bindings model. 
         """
 
+        if clearModel:
+            self.keyBindingsModel.clear()
+
         global applicationName, appScript
 
         # Get the key bindings for the application script.
@@ -165,25 +168,37 @@
         defScript = default.Script(None)
         self.defKeyBindings = defScript.getKeyBindings()
 
-        nodeCreated = False
+        iterApp = self._createNode(applicationName)
+        iterOrca = self._createNode(_("Orca"))
 
+        # Translators: this refers to commands that do not currently have
+        # an associated key binding.
+        #
+        iterUnbound = self._createNode(_("Unbound"))
+
         # Find the key bindings that are in the application script but 
         # not in the default script.
         #
         for kb in self.appKeyBindings.keyBindings:
-            if not self.defKeyBindings.hasKeyBinding(kb, "strict"):
-                if not self._addAlternateKeyBinding(kb):
-                    handl = appScript.getInputEventHandlerKey(kb.handler)
-                    if not nodeCreated:
-                        iterOrca = self._createNode(applicationName)
-                        nodeCreated = True
-                    self._insertRow(handl, kb, iterOrca)
+            if not self.defKeyBindings.hasKeyBinding(kb, "description"):
+                node = iterApp
+            elif kb.keysymstring:
+                node = iterOrca
+            else:
+                node = iterUnbound
+            if not self._addAlternateKeyBinding(kb):
+                handl = appScript.getInputEventHandlerKey(kb.handler)
+                self._insertRow(handl, kb, node)
 
-        # Call the parent class to add in the default key bindings.
+        if not self.keyBindingsModel.iter_has_child(iterApp):
+            self.keyBindingsModel.remove(iterApp)
+
+        # Call the parent class to add braille bindings and finish
+        # setting up the tree view.
         #
+        self.kbindings = self.appKeyBindings
         orca_gui_prefs.orcaSetupGUI._populateKeyBindings(self, False)
 
-
     def okButtonClicked(self, widget):
         """Signal handler for the "clicked" signal for the okButton
            GtkButton widget. The user has clicked the OK button.
Index: src/orca/orca.py
===================================================================
--- src/orca/orca.py	(revision 3203)
+++ src/orca/orca.py	(working copy)
@@ -530,12 +530,20 @@
         elif event.event_string == "Escape":
             orca_state.capturingKeys = False
         else:
-            # Translators: this is a spoken prompt letting the user know
-            # Orca has recorded a new key combination (e.g., Alt+Ctrl+g)
-            # based upon their input.
-            #
-            speech.speak(_("Key captured: %s. Press enter to confirm.") \
-                         % str(event.event_string))
+            if event.event_string in ["Delete", "BackSpace"]:
+                # Translators: this is a spoken prompt letting the user know
+                # Orca has deleted an existing key combination based upon
+                # their input.
+                #
+                speech.speak(_("Key binding deleted. Press enter to confirm."))
+            else:
+                # Translators: this is a spoken prompt letting the user know
+                # Orca has recorded a new key combination (e.g., Alt+Ctrl+g)
+                # based upon their input.
+                #
+                mods = keybindings.getModifierNames(event.modifiers)
+                speech.speak(_("Key captured: %s. Press enter to confirm.") \
+                             % (mods + event.event_string))
             orca_state.lastCapturedKey = event
     else:
         pass
Index: src/orca/default.py
===================================================================
--- src/orca/default.py	(revision 3203)
+++ src/orca/default.py	(working copy)
@@ -1246,6 +1246,8 @@
         """
 
         orcaModMask         = 1 << settings.MODIFIER_ORCA
+        orcaShiftModMask = (1 << settings.MODIFIER_ORCA |
+                            1 << pyatspi.MODIFIER_SHIFT)
         orcaControlModMask  = (1 << settings.MODIFIER_ORCA |
                                1 << pyatspi.MODIFIER_CONTROL)
         orcaAltModMask      = (1 << settings.MODIFIER_ORCA |
@@ -1394,7 +1396,7 @@
             keybindings.KeyBinding(
                 "b",
                 orcaShiftAltModMask,
-                orcaAltModMask,
+                orcaShiftModMask,
                 self.inputEventHandlers["goToPrevBookmark"])) 
         # key binding to move to the next bookmark             
         keyBindings.add(
@@ -1429,7 +1431,41 @@
                     orcaShiftAltModMask,
                     shiftAltModMask,
                     self.inputEventHandlers["bookmarkCurrentWhereAmI"]))
-                    
+
+        #####################################################################
+        #                                                                   #
+        #  Unbound handlers                                                 #
+        #                                                                   #
+        #####################################################################
+
+        keyBindings.add(
+            keybindings.KeyBinding(
+                None,
+                0,
+                0,
+                self.inputEventHandlers["decreaseSpeechRateHandler"]))
+
+        keyBindings.add(
+            keybindings.KeyBinding(
+                None,
+                0,
+                0,
+                self.inputEventHandlers["increaseSpeechRateHandler"]))
+
+        keyBindings.add(
+            keybindings.KeyBinding(
+                None,
+                0,
+                0,
+                self.inputEventHandlers["decreaseSpeechPitchHandler"]))
+
+        keyBindings.add(
+            keybindings.KeyBinding(
+                None,
+                0,
+                0,
+                self.inputEventHandlers["increaseSpeechPitchHandler"]))
+
         keyBindings = settings.overrideKeyBindings(self, keyBindings)
 
         return keyBindings
Index: src/orca/keybindings.py
===================================================================
--- src/orca/keybindings.py	(revision 3203)
+++ src/orca/keybindings.py	(working copy)
@@ -114,6 +114,10 @@
     Returns an integer representing a key code that should match the
     event.hw_code for key events.
     """
+
+    if not keysym:
+        return 0
+
     if not _keycodeCache.has_key(keysym):
         keymap = gtk.gdk.keymap_get_default()
 
Index: src/orca/orca_gui_prefs.py
===================================================================
--- src/orca/orca_gui_prefs.py	(revision 3203)
+++ src/orca/orca_gui_prefs.py	(working copy)
@@ -52,8 +52,8 @@
 
 OS = None
 
-(HANDLER, DESCRIP, MOD_MASK1, MOD_USED1, KEY1, TEXT1, \
- MOD_MASK2, MOD_USED2, KEY2, TEXT2, MODIF, EDITABLE) = range(12)
+(HANDLER, DESCRIP, MOD_MASK1, MOD_USED1, KEY1, OLDTEXT1, TEXT1, \
+ MOD_MASK2, MOD_USED2, KEY2, OLDTEXT2, TEXT2, MODIF, EDITABLE) = range(14)
 
 (NAME, IS_SPOKEN, IS_BRAILLED, VALUE) = range(4)
 
@@ -79,10 +79,12 @@
             gobject.TYPE_STRING,  # Modifier mask 1
             gobject.TYPE_STRING,  # Used Modifiers 1
             gobject.TYPE_STRING,  # Modifier key name 1
+            gobject.TYPE_STRING,  # Original Text of the Key Binding Shown 1
             gobject.TYPE_STRING,  # Text of the Key Binding Shown 1
             gobject.TYPE_STRING,  # Modifier mask 2
             gobject.TYPE_STRING,  # Used Modifiers 2
             gobject.TYPE_STRING,  # Modifier key name 2
+            gobject.TYPE_STRING,  # Original Text of the Key Binding Shown 2
             gobject.TYPE_STRING,  # Text of the Key Binding Shown 2
             gobject.TYPE_BOOLEAN, # Key Modified by User
             gobject.TYPE_BOOLEAN) # Row with fields editable or not
@@ -145,6 +147,19 @@
         column.set_sort_column_id(KEY1)
         self.keyBindView.append_column(column)
 
+        # OLDTEXT1 - invisble column which will store a copy of the
+        # original keybinding in TEXT1 prior to the Apply or OK
+        # buttons being pressed.  This will prevent automatic
+        # resorting each time a cell is edited.
+        #
+        column = gtk.TreeViewColumn("OldText1",
+                                    gtk.CellRendererText(),
+                                    text=OLDTEXT1)
+        column.set_resizable(True)
+        column.set_visible(False)
+        column.set_sort_column_id(OLDTEXT1)
+        self.keyBindView.append_column(column)
+
         # TEXT1
         #
         rendererText = gtk.CellRendererText()
@@ -165,7 +180,7 @@
                                     text=TEXT1,
                                     editable=EDITABLE)
         column.set_resizable(True)
-        column.set_sort_column_id(TEXT1)
+        column.set_sort_column_id(OLDTEXT1)
         self.keyBindView.append_column(column)
 
         # MOD_MASK2 - invisble column
@@ -196,6 +211,19 @@
         column.set_sort_column_id(KEY2)
         self.keyBindView.append_column(column)
 
+        # OLDTEXT2 - invisble column which will store a copy of the
+        # original keybinding in TEXT1 prior to the Apply or OK
+        # buttons being pressed.  This will prevent automatic
+        # resorting each time a cell is edited.
+        #
+        column = gtk.TreeViewColumn("OldText2",
+                                    gtk.CellRendererText(),
+                                    text=OLDTEXT2)
+        column.set_resizable(True)
+        column.set_visible(False)
+        column.set_sort_column_id(OLDTEXT2)
+        self.keyBindView.append_column(column)
+
         # TEXT2
         #
         rendererText = gtk.CellRendererText()
@@ -219,7 +247,7 @@
                                     text=TEXT2,
                                     editable=EDITABLE)
         column.set_resizable(True)
-        column.set_sort_column_id(TEXT2)
+        column.set_sort_column_id(OLDTEXT2)
         self.keyBindView.append_column(column)
 
         # MODIF
@@ -1675,12 +1703,17 @@
             while iterChild != None:
                 if model.get(iterChild,DESCRIP)[0] == kb.handler._description:
                     exist = True
+                    if not kb.keysymstring:
+                        text = None
+                    else:
+                        text = keybindings.getModifierNames(kb.modifiers) \
+                               + kb.keysymstring
                     model.set(iterChild,
                               MOD_MASK2, kb.modifier_mask,
                               MOD_USED2, kb.modifiers,
                               KEY2, kb.keysymstring,
-                              TEXT2,keybindings.getModifierNames(kb.modifiers)\
-                                  + kb.keysymstring)
+                              OLDTEXT2, text,
+                              TEXT2, text)
                 iterChild = model.iter_next(iterChild)
             myiter = model.iter_next(myiter)
 
@@ -1705,14 +1738,19 @@
 
         if parent != None:
             myiter = model.append(parent)
+            if not kb.keysymstring:
+                text = None
+            else:
+                text = keybindings.getModifierNames(kb.modifiers) \
+                       + kb.keysymstring
             model.set (myiter,
                        HANDLER,   handl,
                        DESCRIP,   kb.handler._description,
                        MOD_MASK1, kb.modifier_mask,
                        MOD_USED1, kb.modifiers,
                        KEY1,      kb.keysymstring,
-                       TEXT1,     keybindings.getModifierNames(kb.modifiers) \
-                                  + kb.keysymstring,
+                       OLDTEXT1,  text,
+                       TEXT1,     text,
                        MODIF,     modif,
                        EDITABLE,  True)
             return myiter
@@ -1792,22 +1830,38 @@
 
         if clearModel:
             self.keyBindingsModel.clear()
+            self.kbindings = None
 
-        self.kbindings = keybindings.KeyBindings()
+        iterOrca = self._getIterOf("Orca") or self._createNode(_("Orca"))
 
-        iterOrca = self._createNode(_("Orca"))
+        # Translators: this refers to commands that do not currently have
+        # an associated key binding.
+        #
+        iterUnbound = self._getIterOf("Unbound") \
+                      or self._createNode(_("Unbound"))
 
-        # KeyBindings from the default script, in default.py (Orca's default)
-        #
         defScript = default.Script(None)
-        self.kbindingsDef = defScript.getKeyBindings()
 
-        for kb in self.kbindingsDef.keyBindings:
-            if not self.kbindings.hasKeyBinding(kb, typeOfSearch="strict"):
-                if not self._addAlternateKeyBinding(kb):
-                    handl = defScript.getInputEventHandlerKey(kb.handler)
-                    self._insertRow(handl, kb, iterOrca)
+        # If we are in the app-specific preferences, we already have
+        # populated our tree with bindings.  Otherwise, we need to
+        # start from scratch.
+        #
+        if not self.kbindings:
+            self.kbindings = keybindings.KeyBindings()
+            self.defKeyBindings = defScript.getKeyBindings()
+            for kb in self.defKeyBindings.keyBindings:
+                if not self.kbindings.hasKeyBinding(kb, "strict"):
+                    if not self._addAlternateKeyBinding(kb):
+                        handl = defScript.getInputEventHandlerKey(kb.handler)
+                        if kb.keysymstring:
+                            self._insertRow(handl, kb, iterOrca)
+                        else:
+                            self._insertRow(handl, kb, iterUnbound)
+                self.kbindings.add(kb)
 
+        if not self.keyBindingsModel.iter_has_child(iterUnbound):
+            self.keyBindingsModel.remove(iterUnbound)
+
         self.orcaModKeyEntry = self.widgets.get_widget("orcaModKeyEntry")
         self.orcaModKeyEntry.set_text(
             str(settings.orcaModifierKeys)[1:-1].replace("'",""))
@@ -1820,14 +1874,13 @@
         # take when the user presses these buttons.
         #
         iterBB = self._createNode(_("Braille Bindings"))
-
         self.bbindings = defScript.getBrailleBindings()
         for com, inputEvHand in self.bbindings.iteritems():
             handl = defScript.getInputEventHandlerKey(inputEvHand)
             self._insertRowBraille(handl, com, inputEvHand, iterBB)
 
         self.keyBindView.expand_all()
-        self.keyBindingsModel.set_sort_column_id(TEXT1, gtk.SORT_ASCENDING)
+        self.keyBindingsModel.set_sort_column_id(OLDTEXT1, gtk.SORT_ASCENDING)
 
     def _cleanupSpeechServers(self):
         """Remove unwanted factories and gnome-speech drivers for the current
@@ -2661,28 +2714,48 @@
         """
 
         newKeyEvent = orca_state.lastCapturedKey
-        newKey = str(orca_state.lastCapturedKey.event_string)
+        newKey = str(newKeyEvent.event_string)
         mods = keybindings.getModifierNames(newKeyEvent.modifiers)
+        if newKey in ["Delete", "BackSpace"]:
+            newKey = newText = None
+        else:
+            newText = mods + newKey
 
         orca_state.capturingKeys = False
+        speech.stop()
 
-        if (newKey != treeModel[path][key]) \
-           or (newKeyEvent.modifiers != int(treeModel[path][modUsed])):
+        handler = self.defKeyBindings.getInputHandler(newKeyEvent)
+        if handler:
+            # Translators: this is a spoken prompt letting the user know
+            # that the key combination (e.g., Ctrl+Alt+f) they just
+            # entered has already been bound to another command.
+            #
+            speech.speak(_("The key entered is already bound to %s") % \
+                         handler._description)
+
+        elif (newKey != treeModel[path][key]) \
+             or (newKeyEvent.modifiers != int(treeModel[path][modUsed])):
             myiter = treeModel.get_iter_from_string(path)
             treeModel.set(myiter,
                           modMask, newKeyEvent.modifiers,
                           modUsed, newKeyEvent.modifiers,
                           key, newKey,
-                          text, mods + newKey,
+                          text, newText,
                           MODIF, True)
-            speech.stop()
-            # Translators: this is a spoken prompt confirming the key
-            # combination (e.g., Ctrl+Alt+f) the user just typed when
-            # creating a new key binding.
-            #
-            speech.speak(_("The new key is: %s") % newKey)
+            if newKey:
+                # Translators: this is a spoken prompt confirming the key
+                # combination (e.g., Ctrl+Alt+f) the user just typed when
+                # creating a new key binding.
+                #
+                speech.speak(_("The new key is: %s") % newText)
+            else:
+                # Translators: this is a spoken prompt confirming that an
+                # existing key combination (e.g., Ctrl+Alt+f) that was
+                # associated with a command has been deleted.
+                #
+                speech.speak(_("The keybinding has been removed."))
+
         else:
-            speech.stop()
             # Translators: this is a spoken prompt letting the user
             # know that the key combination (e.g., Ctrl+Alt+f) they
             # just entered for defining a new key binding was already
