diff --git a/src/louis/__init__.py b/src/louis/__init__.py
index 0833038..95193fc 100644
--- a/src/louis/__init__.py
+++ b/src/louis/__init__.py
@@ -133,6 +133,52 @@ def _mushPosArrays(prefixPos, uncontractedLen, suffixPos):
 
    return pos
 
+def _partition(myStr, mySep):
+   """Provides an implementation of partition for compatibility with
+   Python 2.4.
+
+   Arguments:
+   - myStr: the string
+   - mySep: the separator to look for, starting at the beginning of the string
+
+   Returns:
+   (stringBeforeSep, mySep, stringAfterSep)
+   """
+
+   try:
+     return myStr.partition(mySep)
+   except AttributeError:
+     index = myStr.find(mySep)
+     if index < 0:
+        return (myStr, u'', u'')
+     else:
+        return (myStr[0:index], 
+                myStr[index:index+len(mySep)], 
+                myStr[index+len(mySep):])
+
+def _rpartition(myStr, mySep):
+   """Provides an implementation of rpartition for compatibility with
+   Python 2.4.
+
+   Arguments:
+   - myStr: the string
+   - mySep: the separator to look for, starting at the end of the string
+
+   Returns:
+   (stringBeforeSep, mySep, stringAfterSep)
+   """
+
+   try:
+     return myStr.rpartition(mySep)
+   except AttributeError:
+     index = myStr.rfind(mySep)
+     if index < 0:
+        return (u'', u'', myStr)
+     else:
+        return (myStr[0:index], 
+                myStr[index:index+len(mySep)], 
+                myStr[index+len(mySep):])
+
 def _divideLine(line, offset):
    """Isolates a word the cursor is on and returns the prefix,
    the cursored word, and the suffix. This is a temporary method
@@ -144,8 +190,9 @@ def _divideLine(line, offset):
    """
    if len(line) <= offset:
       return line, '', ''
-   firstHalf = line[:offset].rpartition(' ')
-   secondHalf = line[offset:].partition(' ')
+   
+   firstHalf = _rpartition(line[:offset], ' ')
+   secondHalf = _partition(line[offset:], ' ')
    return firstHalf[0] + firstHalf[1], \
           firstHalf[2] + secondHalf[0], \
           secondHalf[1] + secondHalf[2]
diff --git a/src/orca/Gecko.py b/src/orca/Gecko.py
index 8b5d53b..d0534d2 100644
--- a/src/orca/Gecko.py
+++ b/src/orca/Gecko.py
@@ -261,6 +261,8 @@ class BrailleGenerator(braillegenerator.BrailleGenerator):
             if not isLabelled and obj.name and len(obj.name):
                 text = self._script.appendString(text, obj.name)
 
+        text = self._script.appendString(text, self._getTextForRole(obj))
+
         # get the Braille indicator
         state = obj.getState()
         if state.contains(pyatspi.STATE_INDETERMINATE):
@@ -269,14 +271,12 @@ class BrailleGenerator(braillegenerator.BrailleGenerator):
             indicatorIndex = 1
         else:
             indicatorIndex = 0
-        text = self._script.appendString(
-            settings.brailleCheckBoxIndicators[indicatorIndex],
-            text)
-
-        text = self._script.appendString(text, self._getTextForRole(obj))
 
         regions = []
-        componentRegion = braille.Component(obj, text)
+
+        componentRegion = braille.Component(
+            obj, text,
+            indicator=settings.brailleCheckBoxIndicators[indicatorIndex])
         regions.append(componentRegion)
 
         return [regions, componentRegion]
@@ -325,15 +325,14 @@ class BrailleGenerator(braillegenerator.BrailleGenerator):
             if not isLabelled and obj.name and len(obj.name):
                 text = self._script.appendString(text, obj.name)
 
-        indicatorIndex = 0 + obj.getState().contains(pyatspi.STATE_CHECKED)
-        text = self._script.appendString(
-            settings.brailleRadioButtonIndicators[indicatorIndex],
-            text)
-
         text = self._script.appendString(text, self._getTextForRole(obj))
 
+        indicatorIndex = int(obj.getState().contains(pyatspi.STATE_CHECKED))
+
         regions = []
-        componentRegion = braille.Component(obj, text)
+        componentRegion = braille.Component(
+            obj, text,
+            indicator=settings.brailleRadioButtonIndicators[indicatorIndex])
         regions.append(componentRegion)
 
         return [regions, componentRegion]
@@ -4599,7 +4598,8 @@ class Script(default.Script):
                 string = text.getText(startOffset, endOffset)
                 regions = [braille.Region(
                     string,
-                    focusedCharacterOffset - startOffset)]
+                    focusedCharacterOffset - startOffset,
+                    expandOnCursor=True)]
                 if obj.getRole() == pyatspi.ROLE_LINK:
                     link = obj
                 else:
diff --git a/src/orca/braille.py b/src/orca/braille.py
index 56b517b..189af83 100644
--- a/src/orca/braille.py
+++ b/src/orca/braille.py
@@ -38,6 +38,14 @@ import signal
 
 import pyatspi
 
+try:
+    import louis
+except ImportError:
+    louis = None
+    _defaultContractionTable = None
+else:
+    _defaultContractionTable = louis.getDefaultTable()
+
 # We'll use the official BrlAPI pythons (as of BrlTTY 3.8) if they
 # are available.  Otherwise, we'll fall back to our own bindings.
 #
@@ -264,7 +272,7 @@ class Region:
     each region is determined by its string.
     """
 
-    def __init__(self, string, cursorOffset=0):
+    def __init__(self, string, cursorOffset=0, expandOnCursor=False):
         """Creates a new Region containing the given string.
 
         Arguments:
@@ -276,13 +284,27 @@ class Region:
         if not string:
             string = ""
 
+        # If louis is None, then we don't go into contracted mode.
+        self.contracted = settings.enableContractedBraille and \
+                          louis is not None
+        
+        self.expandOnCursor = expandOnCursor
+        
         string = string.decode("UTF-8")
-        if string[-1:] == "\n":
-            string = string[:-1]
-        self.string = string.encode("UTF-8")
+        string.strip('\n')
+        self.rawLine = string.encode("UTF-8")
 
-        self.cursorOffset = cursorOffset
+        if self.contracted:
+            self.contractionTable = settings.brailleContractionTable or \
+                                    _defaultContractionTable
 
+            self.string, self.inPos, self.outPos, self.cursorOffset = \
+                         self.contractLine(self.rawLine,
+                                           cursorOffset, expandOnCursor)
+        else:
+            self.string = self.rawLine
+            self.cursorOffset = cursorOffset
+            
     def processRoutingKey(self, offset):
         """Processes a cursor routing key press on this Component.  The offset
         is 0-based, where 0 represents the leftmost character of string
@@ -299,14 +321,89 @@ class Region:
         #
         mask = ['\x00'] * len(self.string)
         return "".join(mask)
+    
+    def repositionCursor(self):
+        """Reposition the cursor offset for contracted mode.
+        """
+        if self.contracted:
+            self.string, self.inPos, self.outPos, self.cursorOffset = \
+                       self.contractLine(self.rawLine,
+                                         self.cursorOffset,
+                                         self.expandOnCursor)
+
+    def contractLine(self, line, cursorOffset=0, expandOnCursor=False):
+        """Contract the given line. Returns the contracted line, and the
+        cursor position in the contracted line.
+
+        Arguments:
+        - line: Line to contract.
+        - cursorOffset: Offset of cursor,defaults to 0.
+        - expandOnCursor: Expand word under cursor, False by default.
+        """
 
+        try:
+            cursorOnSpace = line[cursorOffset] == ' '
+        except IndexError:
+            cursorOnSpace = False
+            
+        if not expandOnCursor or cursorOnSpace:
+            contracted, inPos, outPos, cursorPos = \
+                             louis.translate([self.contractionTable],
+                                             line.decode(),
+                                             cursorPos=cursorOffset)
+        else:
+            contracted, inPos, outPos, cursorPos = \
+                             louis.translate([self.contractionTable],
+                                             line.decode(),
+                                             cursorPos=cursorOffset,
+                                             mode=louis.MODE.compbrlAtCursor)
+
+        return contracted, inPos, outPos, cursorPos
+    
+    def displayToBufferOffset(self, display_offset):
+        try:
+            offset = self.inPos[display_offset]
+        except IndexError:
+            # Off the chart, we just place the cursor at the end of the line.
+            offset = len(self.rawLine)
+        except AttributeError:
+            # Not in contracted mode.
+            offset = display_offset
+
+        return offset
+
+    def setContractedBraille(self, contracted):
+        if self.contracted == contracted:
+            return
+        self.contracted = contracted
+        if contracted:
+            self.contractionTable = settings.brailleContractionTable or \
+                                    _defaultContractionTable
+            self.contractRegion()
+        else:
+            self.expandRegion()
+
+    def contractRegion(self):
+        self.string, self.inPos, self.outPos, self.cursorOffset = \
+                     self.contractLine(self.rawLine,
+                                       self.cursorOffset,
+                                       self.expandOnCursor)
+        
+    def expandRegion(self):
+        self.string = self.rawLine
+        try:
+            self.cursorOffset = self.inPos[self.cursorOffset]
+        except IndexError:
+            self.cursorOffset = len(self.string)
+        
 class Component(Region):
     """A subclass of Region backed by an accessible.  This Region will react
     to any cursor routing key events and perform the default action on the
     accessible, if a default action exists.
     """
 
-    def __init__(self, accessible, string, cursorOffset=0):
+    def __init__(self, accessible, string, cursorOffset=0,
+                 indicator='', expandOnCursor=False):
         """Creates a new Component.
 
         Arguments:
@@ -316,7 +413,9 @@ class Component(Region):
                         for this Region if it gets focus.
         """
 
-        Region.__init__(self, string, cursorOffset)
+        Region.__init__(self, string, cursorOffset, expandOnCursor)
+        if indicator:
+            self.string = indicator + ' ' + self.string
         self.accessible = accessible
 
     def processRoutingKey(self, offset):
@@ -349,7 +448,7 @@ class Text(Region):
     [[[TODO: WDW - need to add in text selection capabilities.  Logged
     as bugzilla bug 319754.]]]"""
 
-    def __init__(self, accessible, label=None, eol=""):
+    def __init__(self, accessible, label="", eol=""):
         """Creates a new Text region.
 
         Arguments:
@@ -381,14 +480,20 @@ class Text(Region):
         self._maxCaretOffset = self.lineOffset + len(string.decode("UTF-8"))
 
         self.eol = eol
-        string = string + self.eol
 
-        self.label = label
-        if self.label:
-            string = self.label + " " + string
-            cursorOffset += len(self.label.decode("UTF-8")) + 1
+        if label:
+            self.label = label + ' '
+        else:
+            self.label = ''
+
+        string = self.label + string
 
-        Region.__init__(self, string, cursorOffset)
+        cursorOffset += len(self.label)
+        
+        Region.__init__(self, string, cursorOffset, True)
+
+        if not self.contracted:
+            self.string += self.eol
 
     def repositionCursor(self):
         """Attempts to reposition the cursor in response to a new
@@ -400,15 +505,20 @@ class Text(Region):
         [string, caretOffset, lineOffset] = \
                  orca_state.activeScript.getTextLineAtCaret(self.accessible)
         cursorOffset = min(caretOffset - lineOffset, len(string))
-        if self.label:
-            cursorOffset += len(self.label.decode("UTF-8")) + 1
-
+        
         if lineOffset != self.lineOffset:
             return False
-        else:
-            self.caretOffset = caretOffset
-            self.lineOffset = lineOffset
-            self.cursorOffset = cursorOffset
+
+        self.caretOffset = caretOffset
+        self.lineOffset = lineOffset
+
+        cursorOffset += len(self.label)
+
+        if self.contracted:
+            self.string, self.inPos, self.outPos, cursorOffset = \
+                       self.contractLine(self.rawLine, cursorOffset, True)
+
+        self.cursorOffset = cursorOffset
 
         return True
 
@@ -417,11 +527,11 @@ class Text(Region):
         is 0-based, where 0 represents the leftmost character of text
         associated with this region.  Note that the zeroeth character may have
         been scrolled off the display."""
+        
+        offset = self.displayToBufferOffset(offset)
 
-        if self.label:
-            offset = offset - len(self.label.decode("UTF-8")) - 1
-            if offset < 0:
-                return
+        if offset < 0:
+            return
 
         newCaretOffset = min(self.lineOffset + offset, self._maxCaretOffset)
         self.accessible.queryText().setCaretOffset(newCaretOffset)
@@ -517,17 +627,48 @@ class Text(Region):
 
         mask = "".join(attrMask)
 
+        if self.contracted:
+            contractedMask = [0] * len(self.rawLine)
+            outPos = self.outPos[len(self.label):]
+            if self.label:
+                # Transform the offsets.
+                outPos = \
+                       [offset - len(self.label) - 1 for offset in outPos]
+            for i, m in enumerate(mask):
+                try:
+                    contractedMask[outPos[i]] |= ord(m)
+                except IndexError:
+                    continue
+            mask = ''.join(map(chr, contractedMask))
+
         # Add empty mask characters for the EOL character as well as for
         # any label that might be present.
         #
         for i in range (0, len(self.eol)):
             mask += '\x00'
+
         if self.label:
             for i in range (0, len(self.label) + 1):
                 mask = '\x00' + mask
 
         return mask
 
+    def contractLine(self, line, cursorOffset=0, expandOnCursor=True):
+        contracted, inPos, outPos, cursorPos = Region.contractLine(
+            self, line, cursorOffset, expandOnCursor)
+        
+        return contracted + self.eol, inPos, outPos, cursorPos
+
+    def displayToBufferOffset(self, display_offset):
+        offset = Region.displayToBufferOffset(self, display_offset)
+        offset -= len(self.label)
+        return offset
+
+    def setContractedBraille(self, contracted):
+        Region.setContractedBraille(self, contracted)
+        if not contracted:
+            self.string += self.eol
+
 class ReviewComponent(Component):
     """A subclass of Component that is to be used for flat review mode."""
 
@@ -562,7 +703,7 @@ class ReviewText(Region):
         - zone: the flat review Zone associated with this component
         """
 
-        Region.__init__(self, string)
+        Region.__init__(self, string, expandOnCursor=True)
         self.accessible = accessible
         self.lineOffset = lineOffset
         self.zone = zone
@@ -573,6 +714,7 @@ class ReviewText(Region):
         associated with this region.  Note that the zeroeth character may have
         been scrolled off the display."""
 
+        offset = self.displayToBufferOffset(offset)
         newCaretOffset = self.lineOffset + offset
         self.accessible.queryText().setCaretOffset(newCaretOffset)
 
@@ -657,6 +799,10 @@ class Line:
         if region:
             region.processRoutingKey(regionOffset)
 
+    def setContractedBraille(self, contracted):
+        for region in self.regions:
+            region.setContractedBraille(contracted)
+
 def getRegionAtCell(cell):
     """Given a 1-based cell offset, return the braille region
     associated with that cell in the form of [region, offsetinregion]
@@ -1052,6 +1198,12 @@ def _processBrailleEvent(command):
             _lines[lineNum].processRoutingKey(cursor)
             consumed = True
 
+    if command in (0x2141, 65): # Toggle six dot braille
+        settings.enableContractedBraille = not settings.enableContractedBraille
+        for line in _lines:
+            line.setContractedBraille(settings.enableContractedBraille)
+        refresh()
+
     if settings.timeoutCallback and (settings.timeoutTime > 0):
         signal.alarm(0)
 
@@ -1067,7 +1219,7 @@ def _brlAPIKeyReader(source, condition):
         lower = key & 0xFFFFFFFF
         #keyType = lower >> 29
         keyCode = lower & 0x1FFFFFFF
-
+        
         # [[TODO: WDW - HACK If we have a cursor routing key, map
         # it back to the code we used to get with earlier versions
         # of BrlAPI (i.e., bit 0x100 was the indicator of a cursor
@@ -1103,9 +1255,11 @@ def setupKeyRanges(keys):
         #
         for key in keys:
             keySet.append(brlapi.KEY_TYPE_CMD | key)
-
+            
         brlAPI.acceptKeys(brlapi.rangeType_command, keySet)
 
+        brlAPI.acceptKeys(brlapi.rangeType_key, [65])
+
         debug.println(debug.LEVEL_FINEST, "Using BrlAPI v0.5.0+")
     except:
         debug.printException(debug.LEVEL_FINEST)
diff --git a/src/orca/braillegenerator.py b/src/orca/braillegenerator.py
index 4a0fb0a..dd5ebf0 100644
--- a/src/orca/braillegenerator.py
+++ b/src/orca/braillegenerator.py
@@ -331,9 +331,6 @@ class BrailleGenerator:
 
         text = ""
         state = obj.getState()
-        text = self._script.appendString(
-            text,
-            settings.brailleCheckBoxIndicators[indicatorindex])
 
         text = self._script.appendString(
             text, self._script.getDisplayedLabel(obj))
@@ -344,7 +341,9 @@ class BrailleGenerator:
             text, self._getTextForRole(obj, pyatspi.ROLE_CHECK_BOX))
 
         regions = []
-        componentRegion = braille.Component(obj, text)
+        componentRegion = braille.Component(
+            obj, text,
+            indicator=settings.brailleCheckBoxIndicators[indicatorindex])
         regions.append(componentRegion)
 
         return [regions, componentRegion]
@@ -372,9 +371,6 @@ class BrailleGenerator:
 
         text = ""
         state = obj.getState()
-        text = self._script.appendString(
-            text,
-            settings.brailleCheckBoxIndicators[indicatorindex])
 
         text = self._script.appendString(
             text, self._script.getDisplayedLabel(obj))
@@ -390,7 +386,9 @@ class BrailleGenerator:
                                       "")
 
         regions = []
-        componentRegion = braille.Component(obj, text)
+        componentRegion = braille.Component(
+            obj, text,
+            indicator=settings.brailleCheckBoxIndicators[indicatorindex])
         regions.append(componentRegion)
 
         return [regions, componentRegion]
@@ -764,9 +762,9 @@ class BrailleGenerator:
         #
         state = obj.getState()
         if state.contains(pyatspi.STATE_CHECKED):
-            text = self._script.appendString(
-                text,
-                settings.brailleCheckBoxIndicators[1])
+            indicator = settings.brailleCheckBoxIndicators[1]
+        else:
+            indicator = ''
 
         text = self._script.appendString(
             text, self._script.getDisplayedLabel(obj))
@@ -781,7 +779,7 @@ class BrailleGenerator:
                                       "")
 
         regions = []
-        componentRegion = braille.Component(obj, text)
+        componentRegion = braille.Component(obj, text, indicator=indicator)
         regions.append(componentRegion)
 
         return [regions, componentRegion]
@@ -968,10 +966,6 @@ class BrailleGenerator:
 
         text = ""
         state = obj.getState()
-        text = self._script.appendString(
-            settings.brailleRadioButtonIndicators[
-                int(state.contains(pyatspi.STATE_CHECKED))],
-            text)
 
         text = self._script.appendString(
             text, self._script.getDisplayedLabel(obj))
@@ -988,7 +982,10 @@ class BrailleGenerator:
         text = self._script.appendString(text, self._getTextForRole(obj))
 
         regions = []
-        componentRegion = braille.Component(obj, text)
+        componentRegion = braille.Component(
+            obj, text,
+            indicator=settings.brailleRadioButtonIndicators[ \
+            int(state.contains(pyatspi.STATE_CHECKED))])
         regions.append(componentRegion)
 
         return [regions, componentRegion]
@@ -1009,10 +1006,6 @@ class BrailleGenerator:
         text = ""
 
         state = obj.getState()
-        text = self._script.appendString(
-            settings.brailleRadioButtonIndicators[
-                state.contains(pyatspi.STATE_CHECKED)],
-            text)
 
         text = self._script.appendString(
             text, self._script.getDisplayedLabel(obj))
@@ -1028,7 +1021,10 @@ class BrailleGenerator:
                                       "")
 
         regions = []
-        componentRegion = braille.Component(obj, text)
+        componentRegion = braille.Component(
+            obj, text,
+            indicator=settings.brailleRadioButtonIndicators[ \
+            int(state.contains(pyatspi.STATE_CHECKED))])
         regions.append(componentRegion)
 
         return [regions, componentRegion]
diff --git a/src/orca/flat_review.py b/src/orca/flat_review.py
index f37fe68..97a1dc2 100644
--- a/src/orca/flat_review.py
+++ b/src/orca/flat_review.py
@@ -1638,6 +1638,9 @@ class Context:
                         regionWithFocus.cursorOffset += \
                             len(zone.words[wordIndex].string.decode("UTF-8"))
                 regionWithFocus.cursorOffset += self.charIndex
+                regionWithFocus.repositionCursor()
+                if isinstance(regionWithFocus, braille.ReviewComponent):
+                    regionWithFocus.expandRegion()
                 break
 
         return [regions, regionWithFocus]
diff --git a/src/orca/orca-setup.glade b/src/orca/orca-setup.glade
index 836edd6..3e1c035 100644
--- a/src/orca/orca-setup.glade
+++ b/src/orca/orca-setup.glade
@@ -1252,8 +1252,8 @@ Hyperlink</property>
 				  <property name="wrap">False</property>
 				  <property name="adjustment">10 1 9999 1 10 10</property>
 				  <accessibility>
-				    <atkrelation target="speakProgressBarLabel" type="labelled-by"/>
 				    <atkrelation target="speakProgressBarUnitsLabel" type="labelled-by"/>
+				    <atkrelation target="speakProgressBarLabel" type="labelled-by"/>
 				  </accessibility>
 				  <signal name="value_changed" handler="speakProgressBarValueChanged" last_modification_time="Thu, 14 Jun 2007 15:09:00 GMT"/>
 				</widget>
@@ -1525,6 +1525,7 @@ Sentence</property>
 
 		  <child>
 		    <widget class="GtkFrame" id="contractedBrailleFrame">
+		      <property name="visible">True</property>
 		      <property name="label_xalign">0</property>
 		      <property name="label_yalign">0.5</property>
 		      <property name="shadow_type">GTK_SHADOW_NONE</property>
@@ -1549,7 +1550,7 @@ Sentence</property>
 			      <property name="spacing">0</property>
 
 			      <child>
-				<widget class="GtkCheckButton" id="checkbutton1">
+				<widget class="GtkCheckButton" id="contractedBrailleCheckbutton">
 				  <property name="visible">True</property>
 				  <property name="can_focus">True</property>
 				  <property name="label" translatable="yes">_Enable Contracted Braille</property>
@@ -1612,6 +1613,7 @@ Sentence</property>
 				      <accessibility>
 					<atkrelation target="contractionTableLabel" type="labelled-by"/>
 				      </accessibility>
+				      <signal name="changed" handler="contractionTableComboChanged" last_modification_time="Fri, 18 Jan 2008 00:39:59 GMT"/>
 				    </widget>
 				    <packing>
 				      <property name="padding">0</property>
@@ -3504,8 +3506,8 @@ Custom</property>
 							  <property name="wrap">False</property>
 							  <property name="adjustment">1 24 256 1 10 10</property>
 							  <accessibility>
-							    <atkrelation target="magCursorSizeUnitsLabel" type="labelled-by"/>
 							    <atkrelation target="magCursorSizeLabel" type="labelled-by"/>
+							    <atkrelation target="magCursorSizeUnitsLabel" type="labelled-by"/>
 							  </accessibility>
 							  <signal name="value_changed" handler="magCursorSizeValueChanged" last_modification_time="Wed, 03 May 2006 15:31:48 GMT"/>
 							</widget>
@@ -3857,8 +3859,8 @@ Custom</property>
 							  <property name="wrap">False</property>
 							  <property name="adjustment">1 1 256 1 10 10</property>
 							  <accessibility>
-							    <atkrelation target="magCrossHairSizeUnitsLabel" type="labelled-by"/>
 							    <atkrelation target="magCrossHairSizeLabel" type="labelled-by"/>
+							    <atkrelation target="magCrossHairSizeUnitsLabel" type="labelled-by"/>
 							  </accessibility>
 							  <signal name="value_changed" handler="magCrossHairSizeValueChanged" last_modification_time="Wed, 03 May 2006 15:39:23 GMT"/>
 							</widget>
@@ -4295,8 +4297,8 @@ None</property>
 						  <property name="wrap">False</property>
 						  <property name="adjustment">0 0 100 1 10 10</property>
 						  <accessibility>
-						    <atkrelation target="magEdgeMarginLabel" type="labelled-by"/>
 						    <atkrelation target="magEdgeMarginUnitsLabel" type="labelled-by"/>
+						    <atkrelation target="magEdgeMarginLabel" type="labelled-by"/>
 						  </accessibility>
 						  <signal name="value_changed" handler="magEdgeMarginValueChanged" last_modification_time="Thu, 06 Dec 2007 22:57:50 GMT"/>
 						</widget>
diff --git a/src/orca/orca_gui_prefs.py b/src/orca/orca_gui_prefs.py
index aad6bd4..963c40a 100644
--- a/src/orca/orca_gui_prefs.py
+++ b/src/orca/orca_gui_prefs.py
@@ -49,6 +49,11 @@ import braille
 import speech
 import speechserver
 
+try:
+    import louis
+except ImportError:
+    louis = None
+
 from orca_i18n import _  # for gettext support
 
 (HANDLER, DESCRIP, MOD_MASK1, MOD_USED1, KEY1, OLDTEXT1, TEXT1, \
@@ -947,7 +952,13 @@ class OrcaSetupGUI(orca_glade.GladeWrapper):
     def contractedBrailleToggled(self, checkbox):
         hbox = self.widgets.get_widget('contractionTablesHBox')
         hbox.set_sensitive(checkbox.get_active())
+        self.prefsDict["enableContractedBraille"] = checkbox.get_active()
 
+    def contractionTableComboChanged(self, combobox):
+        model = combobox.get_model()
+        myIter = combobox.get_active_iter()
+        self.prefsDict["brailleContractionTable"] = model[myIter][1]
+        
     def textAttributeSpokenToggled(self, cell, path, model):
         """The user has toggled the state of one of the text attribute
         checkboxes to be spoken. Update our model to reflect this, then
@@ -1431,6 +1442,36 @@ class OrcaSetupGUI(orca_glade.GladeWrapper):
         state = prefs["brailleRolenameStyle"] == \
                             settings.BRAILLE_ROLENAME_STYLE_SHORT
         self.get_widget("abbrevRolenames").set_active(state)
+        if louis is None:
+            self.get_widget( \
+                "contractedBrailleCheckbutton").set_sensitive(False)
+        else:
+            self.get_widget("contractedBrailleCheckbutton").set_active( \
+                prefs["enableContractedBraille"])
+            # Set up contraction table combo box and set it to the
+            # currently used one.
+            # 
+            tablesCombo = self.get_widget("contractionTableCombo")
+            tableDict = louis.listTables()
+            selectedTableIter = None
+            selectedTable = prefs["brailleContractionTable"] or \
+                             louis.getDefaultTable()
+            if tableDict:
+                tablesModel = gtk.ListStore(str, str)
+                for name, fname in tableDict.items():
+                    it = tablesModel.append([name, fname])
+                    if os.path.join(louis.TABLES_DIR, fname) == selectedTable:
+                        selectedTable = it
+                cell = gtk.CellRendererText()
+                tablesCombo.pack_start(cell, True)
+                tablesCombo.add_attribute(cell, 'text', 0)
+                tablesCombo.set_model(tablesModel)
+                if selectedTable:
+                    tablesCombo.set_active_iter(selectedTable)
+                else:
+                    tablesCombo.set_active(0)
+            else:
+                tablesCombo.set_sensitive(False)
         if prefs["brailleVerbosityLevel"] == settings.VERBOSITY_LEVEL_BRIEF:
             self.get_widget("brailleBriefButton").set_active(True)
         else:
diff --git a/src/orca/orca_prefs.py b/src/orca/orca_prefs.py
index 4f4494e..8a04e7f 100644
--- a/src/orca/orca_prefs.py
+++ b/src/orca/orca_prefs.py
@@ -687,6 +687,8 @@ class OrcaPrefs:
             elif key == "textAttributesBrailleIndicator":
                 value = self._getTextAttributesBrailleIndicatorString( \
                                                               prefsDict[key])
+            elif key == "brailleContractionTable":
+                value = "'%s'" % prefsDict[key]
             else:
                 value = prefsDict[key]
 
diff --git a/src/orca/scripts/planner.py b/src/orca/scripts/planner.py
index 410c48e..8760a9a 100644
--- a/src/orca/scripts/planner.py
+++ b/src/orca/scripts/planner.py
@@ -94,19 +94,18 @@ class BrailleGenerator(braillegenerator.BrailleGenerator):
             allLabels = self._script.findByRole(filler, pyatspi.ROLE_LABEL)
             text += allLabels[0].name
 
+        text = self._script.appendString(text, self._getTextForRole(obj))
+
         if obj.getState().contains(pyatspi.STATE_CHECKED):
             brailleindicatorindex = 1
         else:
             brailleindicatorindex = 0
 
-        text = self._script.appendString(
-            settings.brailleRadioButtonIndicators[brailleindicatorindex],
-            text)
-
-        text = self._script.appendString(text, self._getTextForRole(obj))
-
         regions = []
-        componentRegion = braille.Component(obj, text)
+        componentRegion = braille.Component(
+            obj, text,
+            indicator=\
+            settings.brailleRadioButtonIndicators[brailleindicatorindex])
         regions.append(componentRegion)
 
         return [regions, componentRegion]
diff --git a/src/orca/settings.py b/src/orca/settings.py
index e44969b..15a3d43 100644
--- a/src/orca/settings.py
+++ b/src/orca/settings.py
@@ -155,7 +155,9 @@ userCustomizableSettings = [
     "enabledBrailledTextAttributes",
     "textAttributesBrailleIndicator",
     "enableProgressBarUpdates",
-    "progressBarUpdateInterval"
+    "progressBarUpdateInterval",
+    "enableContractedBraille",
+    "brailleContractionTable"
 ]
 
 # The name of the module that hold the user interface for the main window
@@ -905,3 +907,11 @@ ignoredEventsList = ['object:bounds-changed']
 # changes.  
 #
 inferLiveRegions = True
+
+# Contracted braille support.
+# 
+enableContractedBraille = False
+
+# Contracted braille table.
+# 
+brailleContractionTable = ''
