edit: $/Dev10/feature/vs_langs01_s/Merlin/Main/Languages/Ruby/IronRuby.Tests/Runtime/MutableStringTests.cs;C1496258
File: MutableStringTests.cs
===================================================================
--- $/Dev10/feature/vs_langs01_s/Merlin/Main/Languages/Ruby/IronRuby.Tests/Runtime/MutableStringTests.cs;C1496258  (server)    2/9/2010 5:34 PM
+++ Shelved Change: $/Dev10/feature/vs_langs01_s/Merlin/Main/Languages/Ruby/IronRuby.Tests/Runtime/MutableStringTests.cs;MutableStringConcatPerf2
@@ -339,26 +339,26 @@
 
             x = MS(invalid_utf8, RubyEncoding.UTF8);
             y = MS("a", RubyEncoding.UTF8);
-            Assert(x.Append(y).ToByteArray().ValueEquals(ArrayUtils.AppendRange(invalid_utf8, valid_utf8)));
+            Assert(x.Append(y).ToByteArray().ValueEquals(Utils.Concatenate(invalid_utf8, valid_utf8)));
 
             x = MS(invalid_utf8, RubyEncoding.UTF8);
             y = MS("a", RubyEncoding.UTF8);
-            Assert(y.Append(x).ToByteArray().ValueEquals(ArrayUtils.AppendRange(valid_utf8, invalid_utf8)));
+            Assert(y.Append(x).ToByteArray().ValueEquals(Utils.Concatenate(valid_utf8, invalid_utf8)));
 
             x = MS(invalid_utf8, RubyEncoding.UTF8);
-            Assert(x.Append(x).ToByteArray().ValueEquals(ArrayUtils.AppendRange(invalid_utf8, invalid_utf8)));
+            Assert(x.Append(x).ToByteArray().ValueEquals(Utils.Concatenate(invalid_utf8, invalid_utf8)));
 
 
             x = MS(invalid_utf8, RubyEncoding.UTF8);
             y = MS("ßa?", RubyEncoding.UTF8);
-            Assert(x.Append(y, 1, 1).ToByteArray().ValueEquals(ArrayUtils.AppendRange(invalid_utf8, valid_utf8)));
+            Assert(x.Append(y, 1, 1).ToByteArray().ValueEquals(Utils.Concatenate(invalid_utf8, valid_utf8)));
 
             x = MS(invalid_utf8, RubyEncoding.UTF8);
             y = MS("a", RubyEncoding.UTF8);
-            Assert(y.Append(x, 1, 2).ToByteArray().ValueEquals(ArrayUtils.AppendRange(valid_utf8, new byte[] { 0x85, 0x9c })));
+            Assert(y.Append(x, 1, 2).ToByteArray().ValueEquals(Utils.Concatenate(valid_utf8, new byte[] { 0x85, 0x9c })));
 
             x = MS(invalid_utf8, RubyEncoding.UTF8);
-            Assert(x.Append(x, 1, 2).ToByteArray().ValueEquals(ArrayUtils.AppendRange(invalid_utf8, new byte[] { 0x85, 0x9c })));
+            Assert(x.Append(x, 1, 2).ToByteArray().ValueEquals(Utils.Concatenate(invalid_utf8, new byte[] { 0x85, 0x9c })));
         }
 
         [Options(NoRuntime = true)]
@@ -559,7 +559,7 @@
             var s = MutableStringOps.Concatenate(s1, s2);
             Assert(s.Encoding == resultEncoding);
             var b = s.ToByteArray();
-            Assert(b.ValueCompareTo(b.Length, ArrayUtils.AppendRange(b1, b2)) == 0);
+            Assert(b.ValueCompareTo(b.Length, Utils.Concatenate(b1, b2)) == 0);
         }
 
         [Options(NoRuntime = true)]
@@ -691,7 +691,7 @@
             MutableString a;
             string s = "12123";
 
-            a = MutableString.CreateBinary(ArrayUtils.AppendRange(BinaryEncoding.Instance.GetBytes(s), new byte[] { 0, 0 }));
+            a = MutableString.CreateBinary(Utils.Concatenate(BinaryEncoding.Instance.GetBytes(s), new byte[] { 0, 0 }));
             a.Remove(s.Length, 2);
 
             Action<string> test1 = (value) => {
@@ -724,7 +724,7 @@
             MutableString a;
             string s = "12123";
 
-            a = MutableString.CreateBinary(ArrayUtils.AppendRange(BinaryEncoding.Instance.GetBytes(s), new byte[] { 0, 0 }));
+            a = MutableString.CreateBinary(Utils.Concatenate(BinaryEncoding.Instance.GetBytes(s), new byte[] { 0, 0 }));
             a.Remove(s.Length, 2);
 
             Action<string> test1 = (value) => {
===================================================================
edit: $/Dev10/feature/vs_langs01_s/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Builtins/MutableStringOps.cs;C1561136
File: MutableStringOps.cs
===================================================================
--- $/Dev10/feature/vs_langs01_s/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Builtins/MutableStringOps.cs;C1561136  (server)    2/9/2010 3:44 PM
+++ Shelved Change: $/Dev10/feature/vs_langs01_s/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Builtins/MutableStringOps.cs;MutableStringConcatPerf2
@@ -399,7 +399,7 @@
         [RubyMethod("+")]
         public static MutableString/*!*/ Concatenate(MutableString/*!*/ self, [DefaultProtocol, NotNull]MutableString/*!*/ other) {
             // doesn't create a subclass:
-            return MutableString.Create(self).Append(other).TaintBy(self).TaintBy(other);
+            return self.Concat(other).TaintBy(self).TaintBy(other);
         }
 
         #endregion
===================================================================
edit: $/Dev10/feature/vs_langs01_s/Merlin/Main/Languages/Ruby/Ruby/Builtins/MutableString.BinaryContent.cs;C1496258
File: MutableString.BinaryContent.cs
===================================================================
--- $/Dev10/feature/vs_langs01_s/Merlin/Main/Languages/Ruby/Ruby/Builtins/MutableString.BinaryContent.cs;C1496258  (server)    2/9/2010 12:20 PM
+++ Shelved Change: $/Dev10/feature/vs_langs01_s/Merlin/Main/Languages/Ruby/Ruby/Builtins/MutableString.BinaryContent.cs;MutableStringConcatPerf2
@@ -319,6 +319,52 @@
 
             #endregion
 
+            #region Concatenate (read-only)
+
+            public override Content/*!*/ Concat(Content/*!*/ content) {
+                return content.ConcatTo(this);
+            }
+
+            internal BinaryContent/*!*/ Concatenate(CharArrayContent/*!*/ content) {
+                int count = content.GetDataByteCount();
+                var result = new byte[_count + count];
+                Array.Copy(_data, 0, result, 0, _count);
+                content.GetDataBytes(result, _count);
+                return new BinaryContent(result, null);
+            }
+
+            internal BinaryContent/*!*/ Concatenate(StringContent/*!*/ content) {
+                int count = content.GetDataByteCount();
+                var result = new byte[_count + count];
+                Array.Copy(_data, 0, result, 0, _count);
+                content.GetDataBytes(result, _count);
+                return new BinaryContent(result, null);
+            }
+
+            // binary + binary(self) -> binary
+            public override Content/*!*/ ConcatTo(BinaryContent/*!*/ content) {
+                return new BinaryContent(Utils.Concatenate(content._data, content._count, _data, _count), null);
+            }
+
+            // chars + binary(self) -> binary
+            public override Content/*!*/ ConcatTo(CharArrayContent/*!*/ content) {
+                int count = content.GetDataByteCount();
+                var result = new byte[count + _count];
+                content.GetDataBytes(result, 0);
+                Array.Copy(_data, 0, result, count, _count);
+                return new BinaryContent(result, null);
+            }
+
+            // string + binary(self) -> binary
+            public override Content/*!*/ ConcatTo(StringContent/*!*/ content) {
+                int count = content.GetDataByteCount();
+                var result = new byte[count + _count];
+                content.GetDataBytes(result, 0);
+                Array.Copy(_data, 0, result, count, _count);
+                return new BinaryContent(result, null);
+            }
+
+            #endregion
 
             #region Append
 
===================================================================
edit: $/Dev10/feature/vs_langs01_s/Merlin/Main/Languages/Ruby/Ruby/Builtins/MutableString.CharArrayContent.cs;C1429753
File: MutableString.CharArrayContent.cs
===================================================================
--- $/Dev10/feature/vs_langs01_s/Merlin/Main/Languages/Ruby/Ruby/Builtins/MutableString.CharArrayContent.cs;C1429753  (server)    2/9/2010 11:17 AM
+++ Shelved Change: $/Dev10/feature/vs_langs01_s/Merlin/Main/Languages/Ruby/Ruby/Builtins/MutableString.CharArrayContent.cs;MutableStringConcatPerf2
@@ -59,12 +59,20 @@
                 } else if (additionalCapacity == 0) {
                     return _owner._encoding.StrictEncoding.GetBytes(_data, 0, _count);
                 } else {
-                    var result = new byte[_owner._encoding.StrictEncoding.GetByteCount(_data, 0, _count) + additionalCapacity];
-                    _owner._encoding.StrictEncoding.GetBytes(_data, 0, _count, result, 0);
+                    var result = new byte[GetDataByteCount() + additionalCapacity];
+                    GetDataBytes(result, 0);
                     return result;
                 }
             }
 
+            internal int GetDataByteCount() {
+                return _owner._encoding.StrictEncoding.GetByteCount(_data, 0, _count);
+            }
+
+            internal void GetDataBytes(byte[]/*!*/ bytes, int start) {
+                _owner._encoding.StrictEncoding.GetBytes(_data, 0, _count, bytes, start);
+            }
+
             public char DataGetChar(int index) {
                 Debug.Assert(index < _count);
                 return _data[index];
@@ -321,6 +329,41 @@
 
             #endregion
 
+            #region Concatenate (read-only)
+
+            public override Content/*!*/ Concat(Content/*!*/ content) {
+                return content.ConcatTo(this);
+            }
+
+            internal CharArrayContent/*!*/ Concatenate(StringContent/*!*/ content) {
+                int count = content.Data.Length;
+                var result = new char[_count + count];
+                Array.Copy(_data, 0, result, 0, _count);
+                content.Data.CopyTo(0, result, _count, count);
+                return new CharArrayContent(result, null);
+            }
+
+            // binary + chars(self) -> binary
+            public override Content/*!*/ ConcatTo(BinaryContent/*!*/ content) {
+                return content.Concatenate(this);
+            }
+
+            // chars + chars(self) -> chars
+            public override Content/*!*/ ConcatTo(CharArrayContent/*!*/ content) {
+                return new CharArrayContent(Utils.Concatenate(content._data, content._count, _data, _count), null);
+            }
+
+            // string + chars(self) -> chars
+            public override Content/*!*/ ConcatTo(StringContent/*!*/ content) {
+                int count = content.Data.Length;
+                var result = new char[count + _count];
+                content.Data.CopyTo(0, result, 0, count);
+                Array.Copy(_data, 0, result, count, _count);
+                return new CharArrayContent(result, null);
+            }
+
+            #endregion
+
             #region Append
 
             public override void Append(char c, int repeatCount) {
===================================================================
edit: $/Dev10/feature/vs_langs01_s/Merlin/Main/Languages/Ruby/Ruby/Builtins/MutableString.Content.cs;C1429753
File: MutableString.Content.cs
===================================================================
--- $/Dev10/feature/vs_langs01_s/Merlin/Main/Languages/Ruby/Ruby/Builtins/MutableString.Content.cs;C1429753  (server)    2/9/2010 3:58 PM
+++ Shelved Change: $/Dev10/feature/vs_langs01_s/Merlin/Main/Languages/Ruby/Ruby/Builtins/MutableString.Content.cs;MutableStringConcatPerf2
@@ -109,6 +109,11 @@
             public abstract int LastIndexOf(byte[]/*!*/ bytes, int start, int count);
             public abstract int LastIndexIn(Content/*!*/ str, int start, int count);
 
+            public abstract Content/*!*/ Concat(Content/*!*/ content);
+            public abstract Content/*!*/ ConcatTo(BinaryContent/*!*/ content);
+            public abstract Content/*!*/ ConcatTo(CharArrayContent/*!*/ content);
+            public abstract Content/*!*/ ConcatTo(StringContent/*!*/ content);
+
             // write:
             public abstract void Append(char c, int repeatCount);
             public abstract void Append(byte b, int repeatCount);
===================================================================
edit: $/Dev10/feature/vs_langs01_s/Merlin/Main/Languages/Ruby/Ruby/Builtins/MutableString.cs;C1496258
File: MutableString.cs
===================================================================
--- $/Dev10/feature/vs_langs01_s/Merlin/Main/Languages/Ruby/Ruby/Builtins/MutableString.cs;C1496258  (server)    2/9/2010 3:29 PM
+++ Shelved Change: $/Dev10/feature/vs_langs01_s/Merlin/Main/Languages/Ruby/Ruby/Builtins/MutableString.cs;MutableStringConcatPerf2
@@ -1034,6 +1034,19 @@
 
         #endregion
 
+        #region Concat (read-only)
+
+        /// <summary>
+        /// Returns a concatenation of this string with other.
+        /// </summary>
+        public MutableString/*!*/ Concat(MutableString/*!*/ other) {
+            ContractUtils.RequiresNotNull(other, "other");
+            var encoding = RequireCompatibleEncoding(other) ?? _encoding;
+            return new MutableString(_content.Concat(other._content), encoding);
+        }
+
+        #endregion
+
         #region Append
 
         /// <summary>
===================================================================
edit: $/Dev10/feature/vs_langs01_s/Merlin/Main/Languages/Ruby/Ruby/Builtins/MutableString.StringContent.cs;C1429753
File: MutableString.StringContent.cs
===================================================================
--- $/Dev10/feature/vs_langs01_s/Merlin/Main/Languages/Ruby/Ruby/Builtins/MutableString.StringContent.cs;C1429753  (server)    2/9/2010 5:53 PM
+++ Shelved Change: $/Dev10/feature/vs_langs01_s/Merlin/Main/Languages/Ruby/Ruby/Builtins/MutableString.StringContent.cs;MutableStringConcatPerf2
@@ -32,6 +32,10 @@
                 _data = data;
             }
 
+            internal string/*!*/ Data {
+                get { return _data; }
+            }
+
             internal BinaryContent/*!*/ SwitchToBinary() {
                 var bytes = DataToBytes();
                 return WrapContent(bytes, bytes.Length);
@@ -55,6 +59,14 @@
                 return _data.Length > 0 ? _owner._encoding.StrictEncoding.GetBytes(_data) : Utils.EmptyBytes;
             }
 
+            internal int GetDataByteCount() {
+                return _owner._encoding.StrictEncoding.GetByteCount(_data);
+            }
+
+            internal void GetDataBytes(byte[]/*!*/ bytes, int start) {
+                _owner._encoding.StrictEncoding.GetBytes(_data, 0, _data.Length, bytes, start);
+            }
+
             #region GetHashCode, Length, Clone (read-only), Count
 
             public override int GetHashCode(out int binarySum) {
@@ -151,7 +163,7 @@
             }
 
             public override void CheckEncoding() {
-                _owner._encoding.StrictEncoding.GetByteCount(_data);
+                GetDataByteCount();
             }
 
             #endregion
@@ -272,6 +284,29 @@
 
             #endregion
 
+            #region Concatenate (read-only)
+
+            public override Content/*!*/ Concat(Content/*!*/ content) {
+                return content.ConcatTo(this);
+            }
+
+            // binary + string -> binary
+            public override Content/*!*/ ConcatTo(BinaryContent/*!*/ content) {
+                return content.Concatenate(this);
+            }
+
+            // chars + string -> chars
+            public override Content/*!*/ ConcatTo(CharArrayContent/*!*/ content) {
+                return content.Concatenate(this);
+            }
+
+            // string + string -> string
+            public override Content/*!*/ ConcatTo(StringContent/*!*/ content) {
+                return new StringContent(content.Data + _data, null);
+            }
+
+            #endregion
+
             #region Append
 
             public override void Append(char c, int repeatCount) {
===================================================================
edit: $/Dev10/feature/vs_langs01_s/Merlin/Main/Languages/Ruby/Ruby/Builtins/RubyClass.cs;C1561136
File: RubyClass.cs
===================================================================
--- $/Dev10/feature/vs_langs01_s/Merlin/Main/Languages/Ruby/Ruby/Builtins/RubyClass.cs;C1561136  (server)    2/9/2010 5:34 PM
+++ Shelved Change: $/Dev10/feature/vs_langs01_s/Merlin/Main/Languages/Ruby/Ruby/Builtins/RubyClass.cs;MutableStringConcatPerf2
@@ -987,7 +987,7 @@
             }
 
             MemberInfo[] altResult = GetDeclaredClrMethods(type, bindingFlags, prefix + altName);
-            return ArrayUtils.AppendRange(result, altResult);
+            return Utils.Concatenate(result, altResult);
         }
 
         private static MemberInfo/*!*/[]/*!*/ GetDeclaredClrMethods(Type/*!*/ type, BindingFlags bindingFlags, string/*!*/ name) {
===================================================================
edit: $/Dev10/feature/vs_langs01_s/Merlin/Main/Languages/Ruby/Ruby/Runtime/Utils.cs;C1496258
File: Utils.cs
===================================================================
--- $/Dev10/feature/vs_langs01_s/Merlin/Main/Languages/Ruby/Ruby/Runtime/Utils.cs;C1496258  (server)    2/9/2010 10:51 AM
+++ Shelved Change: $/Dev10/feature/vs_langs01_s/Merlin/Main/Languages/Ruby/Ruby/Runtime/Utils.cs;MutableStringConcatPerf2
@@ -143,6 +143,17 @@
             }
         }
 
+        internal static T[]/*!*/ Concatenate<T>(T[]/*!*/ array1, T[]/*!*/ array2) {
+            return Concatenate(array1, array1.Length, array2, array2.Length);
+        }
+
+        internal static T[]/*!*/ Concatenate<T>(T[]/*!*/ array1, int itemCount1, T[]/*!*/ array2, int itemCount2) {
+            T[] result = new T[itemCount1 + itemCount2];
+            Array.Copy(array1, 0, result, 0, itemCount1);
+            Array.Copy(array2, 0, result, itemCount1, itemCount2);
+            return result;
+        }
+
         internal static int Append<T>(ref T[]/*!*/ array, int itemCount, T item, int repeatCount) {
             Resize(ref array, itemCount + repeatCount);
             Fill(array, itemCount, item, repeatCount);
===================================================================
edit: $/Dev10/feature/vs_langs01_s/Merlin/Main/Languages/Ruby/Scripts/ircoverage.bat;C1569144
File: ircoverage.bat
===================================================================
--- $/Dev10/feature/vs_langs01_s/Merlin/Main/Languages/Ruby/Scripts/ircoverage.bat;C1569144  (server)    2/9/2010 7:32 PM
+++ Shelved Change: $/Dev10/feature/vs_langs01_s/Merlin/Main/Languages/Ruby/Scripts/ircoverage.bat;MutableStringConcatPerf2
@@ -10,8 +10,8 @@
 xcopy /s /y "%SRC%\Microsoft.*.dll" "%DST%"
 
 %VSINSTR% "%SRC%\IronRuby.dll"
-%VSINSTR% "%SRC%\IronRuby.Yaml.dll"
 %VSINSTR% "%SRC%\IronRuby.Libraries.dll"
+%VSINSTR% "%SRC%\IronRuby.Libraries.Yaml.dll"
 
 "%PERF_TOOLS%\vsperfcmd.exe" /start:coverage /OUTPUT:"%DST%\IronRuby"
 
===================================================================
