edit: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Initializers.Generated.cs;C474465
File: Initializers.Generated.cs
===================================================================
--- $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Initializers.Generated.cs;C474465  (server)    6/23/2008 7:23 PM
+++ Shelved Change: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Initializers.Generated.cs;MutableStringSqueeze
@@ -4051,6 +4051,14 @@
                 new System.Scripting.Func<System.Scripting.Runtime.CodeContext, Ruby.Builtins.MutableString, Ruby.Builtins.RubyRegex, System.Int32, Ruby.Builtins.RubyArray>(Ruby.Builtins.MutableStringOps.Split),
             });
             
+            module.DefineLibraryMethod("squeeze", 0x29, new System.Delegate[] {
+                new System.Scripting.Func<System.Scripting.Runtime.CodeContext, Ruby.Builtins.MutableString, System.Object[], Ruby.Builtins.MutableString>(Ruby.Builtins.MutableStringOps.Squeeze),
+            });
+            
+            module.DefineLibraryMethod("squeeze!", 0x29, new System.Delegate[] {
+                new System.Scripting.Func<System.Scripting.Runtime.CodeContext, Ruby.Builtins.MutableString, System.Object[], Ruby.Builtins.MutableString>(Ruby.Builtins.MutableStringOps.SqueezeInPlace),
+            });
+            
             module.DefineLibraryMethod("strip", 0x29, new System.Delegate[] {
                 new System.Scripting.Func<System.Scripting.Runtime.CodeContext, Ruby.Builtins.MutableString, System.Object>(Ruby.Builtins.MutableStringOps.Strip),
             });
===================================================================
edit: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Builtins/MutableStringOps.cs;C468100
File: MutableStringOps.cs
===================================================================
--- $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Builtins/MutableStringOps.cs;C468100  (server)    6/25/2008 3:39 PM
+++ Shelved Change: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Builtins/MutableStringOps.cs;MutableStringSqueeze
@@ -2749,6 +2749,65 @@
 
         #endregion
 
+        //-------------------------------------------------------- String#squeeze
+        //     str.squeeze   => new_str
+        //------------------------------------------------------------------------
+        //     Builds a set of characters from the string parameter(s) using the same technique
+        //     used for count's string params. Returns a new string where runs of the same character
+        //     that occur in this set are replaced by a single character. If no arguments are given, all
+        //     runs of identical characters are replaced by a single character.
+
+        //       "yellow moon".squeeze” => "yelow mon"
+        //       " now is the".squeeze(" ")  =>  " now is the"
+        //       "putters putt balls".squeeze("mz") => "puters put balls"	
+
+        #region squeeze
+        [RubyMethod("squeeze")]
+        public static MutableString/*!*/ Squeeze(CodeContext/*!*/ context, MutableString/*!*/ self, [NotNull]params object[] args) {
+            MutableString result = MutableString.Create(self);
+            SqueezeMutableString(context, result, args);
+            return RubyUtils.FlowTaint(context, self, CreateSubClass(context, self, result));
+        }
+
+        [RubyMethod("squeeze!")]
+        public static MutableString/*!*/ SqueezeInPlace(CodeContext/*!*/ context, MutableString/*!*/ self, [NotNull]params object[] args) {
+            RubyUtils.RequiresNotFrozen(context, self);
+            return SqueezeMutableString(context, self, args);
+        }
+
+        private static MutableString SqueezeMutableString(CodeContext context, MutableString s, object[] args) {
+            // if squeezeAll is true then there should be no ranges, and vice versa
+            Assert.NotNull(s);
+            Assert.NotNull(args);
+
+            // convert the args into a map of characters to be squeezed (same algorithm as count)
+            BitArray map = null;
+            if (args.Length > 0) {
+                MutableString[] ranges = new MutableString[args.Length];
+                for (int i = 0; i < args.Length; i++) {
+                    ranges[i] = Protocols.CastToString(context, args[i]);
+                }
+                map = new RangeParser(ranges).Parse();
+            }
+
+            // Do the squeeze in place
+            int j = 1, k = 1;
+            while (j < s.Length) {
+                if (s.GetChar(j) == s.GetChar(j-1) && (args.Length == 0 || map.Get(s.GetChar(j)))) {
+                    j++;
+                } else {
+                    s.SetChar(k, s.GetChar(j));
+                    j++; k++;
+                }
+            }
+            s.Remove(k, j-k);
+
+            // if not modified return null
+            return j == k ? null : s;
+        }
+
+        #endregion
+
         //------------------------------------------------------------ String#to_i
         //     str.to_i(base=10)   => integer
         //------------------------------------------------------------------------
===================================================================
