Index: src/orca/scripts/apps/evolution/script.py
===================================================================
--- src/orca/scripts/apps/evolution/script.py	(revision 4330)
+++ src/orca/scripts/apps/evolution/script.py	(working copy)
@@ -432,7 +432,7 @@
 
                     if mode == pyatspi.TEXT_BOUNDARY_LINE_START or \
                        len(mystr) == 0 or mystr[len(mystr)-1] in '.?!':
-                        string = self.adjustForRepeats(string)
+                        string = speech.adjustForRepeats(string)
                         if string.isupper():
                             voice = settings.voices[settings.UPPERCASE_VOICE]
                         else:
@@ -461,7 +461,7 @@
         # If there is anything left unspoken, speak it now.
         #
         if len(string) != 0:
-            string = self.adjustForRepeats(string)
+            string = speech.adjustForRepeats(string)
             if string.isupper():
                 voice = settings.voices[settings.UPPERCASE_VOICE]
             else:
@@ -522,7 +522,7 @@
         self.updateBraille(newLocusOfFocus)
         if settings.enableSpeechIndentation:
             self.speakTextIndentation(obj, string)
-        line = self.adjustForRepeats(string)
+        line = speech.adjustForRepeats(string)
 
         if self.speakBlankLine(obj):
             # Translators: "blank" is a short word to mean the
Index: src/orca/scripts/apps/gedit/script.py
===================================================================
--- src/orca/scripts/apps/gedit/script.py	(revision 4330)
+++ src/orca/scripts/apps/gedit/script.py	(working copy)
@@ -147,7 +147,7 @@
 
                 if mode == pyatspi.TEXT_BOUNDARY_LINE_START or \
                    len(mystr) == 0 or mystr[len(mystr)-1] in '.?!':
-                    string = self.adjustForRepeats(string)
+                    string = speech.adjustForRepeats(string)
                     if string.isupper():
                         voice = settings.voices[settings.UPPERCASE_VOICE]
                     else:
@@ -185,7 +185,7 @@
         # If there is anything left unspoken, speak it now.
         #
         if len(string) != 0:
-            string = self.adjustForRepeats(string)
+            string = speech.adjustForRepeats(string)
             if string.isupper():
                 voice = settings.voices[settings.UPPERCASE_VOICE]
             else:
Index: src/orca/scripts/apps/acroread.py
===================================================================
--- src/orca/scripts/apps/acroread.py	(revision 4330)
+++ src/orca/scripts/apps/acroread.py	(working copy)
@@ -19,9 +19,9 @@
 
 """Custom script for acroread"""
 
-__id__        = "$Id:$"
-__version__   = "$Revision:$"
-__date__      = "$Date:$"
+__id__        = "$Id$"
+__version__   = "$Revision$"
+__date__      = "$Date$"
 __copyright__ = "Copyright (c) 2007-2008 Sun Microsystems Inc. Joanmarie Diggs"
 __license__   = "LGPL"
 
@@ -468,7 +468,7 @@
             utterances = self.speechGenerator.getSpeech(newLocusOfFocus, False)
             adjustedUtterances = []
             for utterance in utterances:
-                adjustedUtterances.append(self.adjustForRepeats(utterance))
+                adjustedUtterances.append(speech.adjustForRepeats(utterance))
             speech.speakUtterances(adjustedUtterances)
             brailleRegions = \
                      self.brailleGenerator.getBrailleRegions(newLocusOfFocus)
@@ -685,7 +685,7 @@
             else:
                 voice = self.voices[settings.DEFAULT_VOICE]
 
-            word = self.adjustForRepeats(word)
+            word = speech.adjustForRepeats(word)
             orca_state.lastWord = word
             speech.speak(word, voice)
             self.speakTextSelectionState(obj, startOffset, endOffset)
Index: src/orca/scripts/toolkits/Gecko/script.py
===================================================================
--- src/orca/scripts/toolkits/Gecko/script.py	(revision 4330)
+++ src/orca/scripts/toolkits/Gecko/script.py	(working copy)
@@ -1141,12 +1141,17 @@
             else:
                 contents = self.getLineContentsAtOffset(obj, characterOffset)
             utterances = self.getUtterancesFromContents(contents)
-            clumped = self.clumpUtterances(utterances)
+            #clumped2 = self.clumpUtterances(utterances)
+            clumped = speech.clumpUtterances(utterances)
+            #if clumped != clumped2:
+            #    print("clumped diffrent from clumped2, %s and %s" %(clumped,clumped2))
+            #else:
+            #    print("clumped == clumped2")
             for i in xrange(len(clumped)):
                 [obj, startOffset, endOffset, text] = \
                                              contents[min(i, len(contents)-1)]
                 [string, voice] = clumped[i]
-                string = self.adjustForRepeats(string)
+                string = speech.adjustForRepeats(string)
                 yield [speechserver.SayAllContext(obj, string,
                                                   startOffset, endOffset),
                        voice]
@@ -5303,43 +5308,17 @@
 
         return utterances
 
-    def clumpUtterances(self, utterances):
-        """Returns a list of utterances clumped together by acss.
-
-        Arguments:
-        -utterances: unclumped utterances
-        -speakRole: if True, speak the roles of objects
-        """
-
-        clumped = []
-
-        for [string, acss] in utterances:
-            if len(clumped) == 0:
-                clumped = [[string, acss]]
-            elif acss == clumped[-1][1]:
-                clumped [-1][0] = clumped[-1][0].rstrip(" ")
-                clumped[-1][0] += " " + string
-            else:
-                clumped.append([string, acss])
-
-        if (len(clumped) == 1) and (clumped[0][0] == "\n"):
-            if settings.speakBlankLines:
-                # Translators: "blank" is a short word to mean the
-                # user has navigated to an empty line.
-                #
-                return [[_("blank"), clumped[0][1]]]
-
-        if len(clumped):
-            clumped [-1][0] = clumped[-1][0].rstrip(" ")
-
-        return clumped
-
     def speakContents(self, contents, speakRole=True):
         """Speaks each string in contents using the associated voice/acss"""
         utterances = self.getUtterancesFromContents(contents, speakRole)
-        clumped = self.clumpUtterances(utterances)
+        #clumped2 = self.clumpUtterances(utterances)
+        clumped = speech.clumpUtterances(utterances)
+        #if clumped != clumped2:
+        #    print("clumped diffrent from clumped2, %s and %s" %(clumped,clumped2))
+        #else:
+        #    print("clumped == clumped2")
         for [string, acss] in clumped:
-            string = self.adjustForRepeats(string)
+            string = speech.adjustForRepeats(string)
             speech.speak(string, acss, False)
 
     def speakCharacterAtOffset(self, obj, characterOffset):
Index: src/orca/default.py
===================================================================
--- src/orca/default.py	(revision 4330)
+++ src/orca/default.py	(working copy)
@@ -2086,7 +2086,7 @@
             else:
                 voice = self.voices[settings.DEFAULT_VOICE]
 
-            phrase = self.adjustForRepeats(phrase)
+            phrase = speech.adjustForRepeats(phrase)
             speech.speak(phrase, voice)
 
     def sayLine(self, obj):
@@ -2117,7 +2117,7 @@
             if settings.enableSpeechIndentation:
                 self.speakTextIndentation(obj, line)
             line = self.adjustForLinks(obj, line, startOffset)
-            line = self.adjustForRepeats(line)
+            line = speech.adjustForRepeats(line)
             speech.speak(line, voice)
 
         else:
@@ -2182,7 +2182,7 @@
         else:
             voice = self.voices[settings.DEFAULT_VOICE]
 
-        word = self.adjustForRepeats(word)
+        word = speech.adjustForRepeats(word)
         orca_state.lastWord = word
         speech.speak(word, voice)
 
@@ -2304,7 +2304,7 @@
         else:
             voice = self.voices[settings.DEFAULT_VOICE]
  
-        sentence = self.adjustForRepeats(sentence)
+        sentence = speech.adjustForRepeats(sentence)
         speech.speak(sentence, voice)
  
     def echoPreviousWord(self, obj, offset=None):
@@ -2380,7 +2380,7 @@
         else:
             voice = self.voices[settings.DEFAULT_VOICE]
 
-        word = self.adjustForRepeats(word)
+        word = speech.adjustForRepeats(word)
         speech.speak(word, voice)
 
     def sayCharacter(self, obj):
@@ -4992,7 +4992,7 @@
             elif speechType == 3:
                 self.phoneticSpellCurrentItem(lineString)
             else:
-                lineString = self.adjustForRepeats(lineString)
+                lineString = speech.adjustForRepeats(lineString)
                 speech.speak(lineString)
 
         self.updateBrailleReview()
@@ -5156,7 +5156,7 @@
                 elif speechType == 3:
                     self.phoneticSpellCurrentItem(wordString)
                 elif speechType == 1:
-                    wordString = self.adjustForRepeats(wordString)
+                    wordString = speech.adjustForRepeats(wordString)
                     speech.speak(wordString)
 
         self.updateBrailleReview(targetCursorCell)
@@ -6280,7 +6280,7 @@
                 lastEndOffset = endOffset
                 offset = endOffset
 
-                lineString = self.adjustForRepeats(lineString)
+                lineString = speech.adjustForRepeats(lineString)
                 if lineString.isupper():
                     voice = settings.voices[settings.UPPERCASE_VOICE]
                 else:
@@ -6309,48 +6309,6 @@
             if not moreLines:
                 done = True
 
-    def _addRepeatSegment(self, segment, line, respectPunctuation=True):
-        """Add in the latest line segment, adjusting for repeat characters
-        and punctuation.
-
-        Arguments:
-        - segment: the segment of repeated characters.
-        - line: the current built-up line to characters to speak.
-        - respectPunctuation: if False, ignore punctuation level.
-
-        Returns: the current built-up line plus the new segment, after
-        adjusting for repeat character counts and punctuation.
-        """
-
-        style = settings.verbalizePunctuationStyle
-        isPunctChar = True
-        try:
-            level, action = punctuation_settings.getPunctuationInfo(segment[0])
-        except:
-            isPunctChar = False
-        count = len(segment)
-        if (count >= settings.repeatCharacterLimit) \
-           and (not segment[0] in self.whitespace):
-            if (not respectPunctuation) \
-               or (isPunctChar and (style <= level)):
-                repeatChar = chnames.getCharacterName(segment[0])
-                # Translators: Orca will tell you how many characters
-                # are repeated on a line of text.  For example: "22
-                # space characters".  The %d is the number and the %s
-                # is the spoken word for the character.
-                #
-                line += " " \
-                     + ngettext("%(count)d %(repeatChar)s character",
-                                "%(count)d %(repeatChar)s characters",
-                                count) \
-                       % {"count" : count, "repeatChar": repeatChar}
-            else:
-                line += segment
-        else:
-            line += segment
-
-        return line
-
     def adjustForLinks(self, obj, line, startOffset):
         """Adjust line to include the word "link" after any hypertext links.
 
@@ -6401,59 +6359,6 @@
 
         return "".join(adjustedLine).encode("UTF-8")
 
-    def adjustForRepeats(self, line):
-        """Adjust line to include repeat character counts.
-        As some people will want this and others might not,
-        there is a setting in settings.py that determines
-        whether this functionality is enabled.
-
-        repeatCharacterLimit = <n>
-
-        If <n> is 0, then there would be no repeat characters.
-        Otherwise <n> would be the number of same characters (or more)
-        in a row that cause the repeat character count output.
-        If the value is set to 1, 2 or 3 then it's treated as if it was
-        zero. In other words, no repeat character count is given.
-
-        Arguments:
-        - line: the string to adjust for repeat character counts.
-
-        Returns: a new line adjusted for repeat character counts (if enabled).
-        """
-
-        line = line.decode("UTF-8")
-
-        if (len(line) < 4) or (settings.repeatCharacterLimit < 4):
-            return line.encode("UTF-8")
-
-        newLine = u''
-        segment = lastChar = line[0]
-
-        multipleChars = False
-        for i in range(1, len(line)):
-            if line[i] == lastChar:
-                segment += line[i]
-            else:
-                multipleChars = True
-                newLine = self._addRepeatSegment(segment, newLine)
-                segment = line[i]
-
-            lastChar = line[i]
-
-        newLine = self._addRepeatSegment(segment, newLine, multipleChars)
-
-        # Pylint is confused and flags this with the following error:
-        #
-        # E1103:5188:Script.adjustForRepeats: Instance of 'True' has
-        # no 'encode' member (but some types could not be inferred)
-        #
-        # We know newLine is a unicode string, so we'll just tell pylint
-        # that we know what we are doing.
-        #
-        # pylint: disable-msg=E1103
-
-        return newLine.encode("UTF-8")
-
     def _getPronunciationForSegment(self, segment):
         """Adjust the word segment to potentially replace it with what
         those words actually sound like. Two pronunciation dictionaries
Index: src/orca/speech.py
===================================================================
--- src/orca/speech.py	(revision 4330)
+++ src/orca/speech.py	(working copy)
@@ -36,6 +36,7 @@
 import keynames
 import orca
 import orca_state
+import punctuation_settings
 import settings
 
 from acss import ACSS
@@ -224,6 +225,11 @@
     else:
         return False
 
+def speakClumpedUtterances(clumped):
+    for [string, acss] in clumped:
+        string = adjustForRepeats(string)
+        speak(string, acss, False)
+            
 def speakUtterances(utterances, acss=None, interrupt=True):
     """Speaks the given list of utterances immediately.
 
@@ -345,3 +351,129 @@
                 server.shutdown()
             except:
                 debug.printException(debug.LEVEL_OFF)
+
+
+def clumpUtterances(utterances):
+    """Returns a list of utterances clumped together by acss.
+    Arguments:
+    -utterances: unclumped utterances
+    -speakRole: if True, speak the roles of objects
+    """
+
+    clumped = []
+    for [string, acss] in utterances:
+        if len(clumped) == 0:
+            clumped = [[string, acss]]
+        elif acss == clumped[-1][1]:
+            clumped [-1][0] = clumped[-1][0].rstrip(" ")
+            clumped[-1][0] += " " + string
+        else:
+            clumped.append([string, acss])
+
+    if (len(clumped) == 1) and (clumped[0][0] == "\n"):
+        if settings.speakBlankLines:
+            # Translators: "blank" is a short word to mean the
+            # user has navigated to an empty line.
+            #
+            return [['blank', clumped[0][1]]]
+
+    if len(clumped):
+        clumped [-1][0] = clumped[-1][0].rstrip(" ")
+    return clumped  
+
+
+def adjustForRepeats(line):
+    """Adjust line to include repeat character counts.
+    As some people will want this and others might not,
+    there is a setting in settings.py that determines
+    whether this functionality is enabled.
+
+    repeatCharacterLimit = <n>
+
+    If <n> is 0, then there would be no repeat characters.
+    Otherwise <n> would be the number of same characters (or more)
+    in a row that cause the repeat character count output.
+    If the value is set to 1, 2 or 3 then it's treated as if it was
+    zero. In other words, no repeat character count is given.
+
+    Arguments:
+    - line: the string to adjust for repeat character counts.
+
+    Returns: a new line adjusted for repeat character counts (if enabled).
+    """
+
+    line = line.decode("UTF-8")
+
+    if (len(line) < 4) or (settings.repeatCharacterLimit < 4):
+        return line.encode("UTF-8")
+
+    newLine = u''
+    segment = lastChar = line[0]
+
+    multipleChars = False
+    for i in range(1, len(line)):
+        if line[i] == lastChar:
+            segment += line[i]
+        else:
+            multipleChars = True
+            newLine = _addRepeatSegment(segment, newLine)
+            segment = line[i]
+
+        lastChar = line[i]
+
+    newLine = _addRepeatSegment(segment, newLine, multipleChars)
+
+    # Pylint is confused and flags this with the following error:
+    #
+    # E1103:5188:Script.adjustForRepeats: Instance of 'True' has
+    # no 'encode' member (but some types could not be inferred)
+    #
+    # We know newLine is a unicode string, so we'll just tell pylint
+    # that we know what we are doing.
+    #
+    # pylint: disable-msg=E1103
+
+    return newLine.encode("UTF-8")
+
+
+def _addRepeatSegment(segment, line, respectPunctuation=True):
+    """Add in the latest line segment, adjusting for repeat characters
+    and punctuation.
+
+    Arguments:
+    - segment: the segment of repeated characters.
+    - line: the current built-up line to characters to speak.
+    - respectPunctuation: if False, ignore punctuation level.
+
+    Returns: the current built-up line plus the new segment, after
+    adjusting for repeat character counts and punctuation.
+    """
+
+    style = settings.verbalizePunctuationStyle
+    isPunctChar = True
+    try:
+        level, action = punctuation_settings.getPunctuationInfo(segment[0])
+    except:
+        isPunctChar = False
+    count = len(segment)
+    if (count >= settings.repeatCharacterLimit) \
+       and (not segment[0] in self.whitespace):
+        if (not respectPunctuation) \
+           or (isPunctChar and (style <= level)):
+            repeatChar = chnames.getCharacterName(segment[0])
+            # Translators: Orca will tell you how many characters
+            # are repeated on a line of text.  For example: "22
+            # space characters".  The %d is the number and the %s
+            # is the spoken word for the character.
+            #
+            line += " " \
+                 + ngettext("%(count)d %(repeatChar)s character",
+                            "%(count)d %(repeatChar)s characters",
+                            count) \
+                   % {"count" : count, "repeatChar": repeatChar}
+        else:
+            line += segment
+    else:
+        line += segment
+
+    return line
