edit: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/IronRuby.Tests/RubyTests.cs;C1000972
File: RubyTests.cs
===================================================================
--- $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/IronRuby.Tests/RubyTests.cs;C1000972  (server)    7/16/2009 12:00 PM
+++ Shelved Change: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/IronRuby.Tests/RubyTests.cs;mangling
@@ -46,8 +46,8 @@
                 Scenario_ParseRegex1,
 
                 Scenario_RubyCategorizer1,
-                Scenario_RubyNameMangling1,
-                Scenario_RubyNameMangling2,
+                NameMangling1,
+                NameMangling2,
 
                 OverloadResolution_Block1,
                 OverloadResolution_ParamArrays1,
===================================================================
edit: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Initializers.Generated.cs;C999418
File: Initializers.Generated.cs
===================================================================
--- $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Initializers.Generated.cs;C999418  (server)    7/16/2009 3:28 PM
+++ Shelved Change: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Initializers.Generated.cs;mangling
@@ -124,7 +124,7 @@
                 new System.Func<IronRuby.Builtins.RubyClass, IronRuby.Builtins.RubyIO>(IronRuby.Builtins.RubyIOOps.CreateIO), 
                 new System.Func<IronRuby.Builtins.RubyClass, System.Int32, IronRuby.Builtins.MutableString, IronRuby.Builtins.RubyIO>(IronRuby.Builtins.RubyIOOps.CreateIO)
             );
-            IronRuby.Builtins.RubyClass def28 = DefineClass("IronRuby::Clr::Name", typeof(IronRuby.Runtime.ClrName), 0x00000003, Context.ObjectClass, LoadIronRuby__Clr__Name_Instance, null, null, IronRuby.Builtins.RubyModule.EmptyArray);
+            IronRuby.Builtins.RubyClass def28 = DefineClass("IronRuby::Clr::Name", typeof(IronRuby.Runtime.ClrName), 0x00000003, Context.ObjectClass, LoadIronRuby__Clr__Name_Instance, LoadIronRuby__Clr__Name_Class, null, IronRuby.Builtins.RubyModule.EmptyArray);
             DefineGlobalClass("MatchData", typeof(IronRuby.Builtins.MatchData), 0x00000003, Context.ObjectClass, LoadMatchData_Instance, LoadMatchData_Class, null, IronRuby.Builtins.RubyModule.EmptyArray);
             DefineGlobalClass("Method", typeof(IronRuby.Builtins.RubyMethod), 0x00000003, Context.ObjectClass, LoadMethod_Instance, null, null, IronRuby.Builtins.RubyModule.EmptyArray);
             // Skipped primitive: Module
@@ -2417,6 +2417,25 @@
             
         }
         
+        private static void LoadIronRuby__Clr__Name_Class(IronRuby.Builtins.RubyModule/*!*/ module) {
+            module.DefineLibraryMethod("clr_to_ruby", 0x61, 
+                new System.Func<IronRuby.Builtins.RubyClass, System.String, IronRuby.Builtins.MutableString>(IronRuby.Builtins.ClrNameOps.Mangle)
+            );
+            
+            module.DefineLibraryMethod("mangle", 0x61, 
+                new System.Func<IronRuby.Builtins.RubyClass, System.String, IronRuby.Builtins.MutableString>(IronRuby.Builtins.ClrNameOps.Mangle)
+            );
+            
+            module.DefineLibraryMethod("ruby_to_clr", 0x61, 
+                new System.Func<IronRuby.Builtins.RubyClass, System.String, IronRuby.Builtins.MutableString>(IronRuby.Builtins.ClrNameOps.Unmangle)
+            );
+            
+            module.DefineLibraryMethod("unmangle", 0x61, 
+                new System.Func<IronRuby.Builtins.RubyClass, System.String, IronRuby.Builtins.MutableString>(IronRuby.Builtins.ClrNameOps.Unmangle)
+            );
+            
+        }
+        
         private static void LoadIronRuby__Clr__String_Instance(IronRuby.Builtins.RubyModule/*!*/ module) {
             module.DefineLibraryMethod("%", 0x51, 
                 new System.Func<IronRuby.Builtins.StringFormatterSiteStorage, System.String, System.Object, System.String>(IronRuby.Builtins.ClrString.Format)
===================================================================
edit: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Builtins/ModuleOps.cs;C942557
File: ModuleOps.cs
===================================================================
--- $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Builtins/ModuleOps.cs;C942557  (server)    7/16/2009 3:13 PM
+++ Shelved Change: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Builtins/ModuleOps.cs;mangling
@@ -310,7 +310,9 @@
         public static RubyMethod/*!*/ DefineMethod(RubyScope/*!*/ scope, RubyModule/*!*/ self,
             [NotNull]ClrName/*!*/ methodName, [NotNull]RubyMethod/*!*/ method) {
             var result = DefineMethod(scope, self, methodName.MangledName, method);
-            self.AddMethodAlias(methodName.ActualName, methodName.MangledName);
+            if (methodName.HasAlternative) {
+                self.AddMethodAlias(methodName.ActualName, methodName.MangledName);
+            }
             return result;
         }
 
@@ -329,7 +331,9 @@
         public static UnboundMethod/*!*/ DefineMethod(RubyScope/*!*/ scope, RubyModule/*!*/ self,
             [NotNull]ClrName/*!*/ methodName, [NotNull]UnboundMethod/*!*/ method) {
             var result = DefineMethod(scope, self, methodName.MangledName, method);
-            self.AddMethodAlias(methodName.ActualName, methodName.MangledName);
+            if (methodName.HasAlternative) {
+                self.AddMethodAlias(methodName.ActualName, methodName.MangledName);
+            }
             return result;
         }
 
@@ -366,7 +370,9 @@
             RubyModule/*!*/ self, [NotNull]ClrName/*!*/ methodName) {
 
             var result = DefineMethod(scope, block, self, methodName.MangledName);
-            self.AddMethodAlias(methodName.ActualName, methodName.MangledName);
+            if (methodName.HasAlternative) {
+                self.AddMethodAlias(methodName.ActualName, methodName.MangledName);
+            }
             return result;
         }
 
@@ -386,7 +392,9 @@
             [NotNull]ClrName/*!*/ methodName, [NotNull]Proc/*!*/ method) {
 
             var result = DefineMethod(scope, self, methodName.MangledName, method);
-            self.AddMethodAlias(methodName.ActualName, methodName.MangledName);
+            if (methodName.HasAlternative) {
+                self.AddMethodAlias(methodName.ActualName, methodName.MangledName);
+            }
             return result;
         }
 
===================================================================
edit: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Extensions/ClrNameOps.cs;C948840
File: ClrNameOps.cs
===================================================================
--- $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Extensions/ClrNameOps.cs;C948840  (server)    7/16/2009 3:19 PM
+++ Shelved Change: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Extensions/ClrNameOps.cs;mangling
@@ -88,5 +88,29 @@
         public static object Compare(BinaryOpStorage/*!*/ comparisonStorage, RespondToStorage/*!*/ respondToStorage, ClrName/*!*/ self, object other) {
             return MutableStringOps.Compare(comparisonStorage, respondToStorage, self.MangledName, other);
         }
+
+        /// <summary>
+        /// Converts a Ruby name to PascalCase name (e.g. "foo_bar" to "FooBar").
+        /// Returns null if the name is not a well-formed Ruby name (it contains upper-case latter or subsequent underscores).
+        /// Characters that are not upper case letters are treated as lower-case letters.
+        /// </summary>
+        [RubyMethod("ruby_to_clr", RubyMethodAttributes.PublicSingleton)]
+        [RubyMethod("unmangle", RubyMethodAttributes.PublicSingleton)]
+        public static MutableString Unmangle(RubyClass/*!*/ self, [DefaultProtocol]string/*!*/ rubyName) {
+            var clr = RubyUtils.TryUnmangleName(rubyName);
+            return clr != null ? MutableString.Create(clr) : null;
+        }
+
+        /// <summary>
+        /// Converts a camelCase or PascalCase name to a Ruby name (e.g. "FooBar" to "foo_bar").
+        /// Returns null if the name is not in camelCase or PascalCase (FooBAR, foo, etc.).
+        /// Characters that are not upper case letters are treated as lower-case letters.
+        /// </summary>
+        [RubyMethod("clr_to_ruby", RubyMethodAttributes.PublicSingleton)]
+        [RubyMethod("mangle", RubyMethodAttributes.PublicSingleton)]
+        public static MutableString Mangle(RubyClass/*!*/ self, [DefaultProtocol]string/*!*/ clrName) {
+            var ruby = RubyUtils.TryMangleName(clrName);
+            return ruby != null ? MutableString.Create(ruby) : null;
+        }
     }
 }
===================================================================
edit: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Builtins/RubyModule.cs;C955994
File: RubyModule.cs
===================================================================
--- $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Builtins/RubyModule.cs;C955994  (server)    7/16/2009 11:21 AM
+++ Shelved Change: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Builtins/RubyModule.cs;mangling
@@ -1636,7 +1636,7 @@
 
             if (virtualLookup) {
                 string mangled;
-                if ((mangled = RubyUtils.MangleName(name)) != name && TryGetDefinedMethod(mangled, ref skipHidden, out method)
+                if ((mangled = RubyUtils.TryMangleName(name)) != null && TryGetDefinedMethod(mangled, ref skipHidden, out method)
                     && method.IsRubyMember) {
                     return true;
                 }
===================================================================
edit: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Compiler/Parser/Parser.cs;C993045
File: Parser.cs
===================================================================
--- $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Compiler/Parser/Parser.cs;C993045  (server)    7/16/2009 11:21 AM
+++ Shelved Change: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Compiler/Parser/Parser.cs;mangling
@@ -508,7 +508,7 @@
         public static string/*!*/ TerminalToString(int terminal) {
             Debug.Assert(terminal >= 0);
             if (((Tokens)terminal).ToString() != terminal.ToString()) {
-                return IronRuby.Runtime.RubyUtils.MangleName(((Tokens)terminal).ToString()).ToUpper();
+                return IronRuby.Runtime.RubyUtils.TryMangleName(((Tokens)terminal).ToString()).ToUpper();
             } else {
                 return CharToString((char)terminal);
             }
===================================================================
edit: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Runtime/ClrName.cs;C948840
File: ClrName.cs
===================================================================
--- $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Runtime/ClrName.cs;C948840  (server)    7/16/2009 11:21 AM
+++ Shelved Change: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Runtime/ClrName.cs;mangling
@@ -35,12 +35,16 @@
         public string/*!*/ MangledName {
             get {
                 if (_mangled == null) {
-                    _mangled = RubyUtils.MangleName(_actual);
+                    _mangled = RubyUtils.TryMangleName(_actual) ?? _actual;
                 }
                 return _mangled;
             }
         }
 
+        public bool HasAlternative {
+            get { return !ReferenceEquals(_actual, MangledName); }
+        }
+
         public ClrName(string/*!*/ actualName) {
             ContractUtils.RequiresNotNull(actualName, "actualName");
             _actual = actualName;
===================================================================
edit: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Runtime/RubyUtils.cs;C999418
File: RubyUtils.cs
===================================================================
--- $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Runtime/RubyUtils.cs;C999418  (server)    7/15/2009 6:04 PM
+++ Shelved Change: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Runtime/RubyUtils.cs;mangling
@@ -188,69 +188,167 @@
 
         #region Names
 
-        // Unmangles a method name. Not all names can be unmangled.
-        // For a name to be unmangle-able, it must be lower_case_with_underscores.
-        // If a name can't be unmangled, this function returns null
+        /// <summary>
+        /// Converts a Ruby name to PascalCase name (foo_bar -> FooBar).
+        /// Returns null if the name is not a well-formed Ruby name (it contains upper-case latter or subsequent underscores).
+        /// Characters that are not upper case letters are treated as lower-case letters.
+        /// </summary>
         public static string TryUnmangleName(string/*!*/ name) {
-            if (name.ToUpper().Equals("INITIALIZE")) {
-                // Special case for compatibility with CLR
-                return name;
+            ContractUtils.RequiresNotNull(name, "name");
+            if (name.Length == 0) {
+                return null;
             }
 
-            StringBuilder sb = new StringBuilder(name.Length);
-            bool upcase = true;
-            foreach (char c in name) {
-                if (char.IsUpper(c)) {
-                    // can't unmangle a name with uppercase letters
+            StringBuilder mangled = new StringBuilder();
+
+            bool lastWasSpecial = false;
+            int i = 0, j = 0;
+            while (i < name.Length) {
+                char c;
+                while (j < name.Length && (c = name[j]) != '_') {
+                    if (Char.IsUpper(c)) {
+                        return null;
+                    }
+                    j++;
+                }
+
+                if (j == i || j == name.Length - 1) {
                     return null;
                 }
 
-                if (c == '_') {
-                    if (upcase) {
-                        // can't unmangle a name with consecutive or leading underscores
+                if (j - i == 1) {
+                    // "id_f_xxx" -/-> "IDFXxx"
+                    if (lastWasSpecial) {
                         return null;
                     }
-                    upcase = true;
+                    mangled.Append(Char.ToUpperInvariant(name[i]));
+                    lastWasSpecial = false;
                 } else {
-                    if (upcase) {
-                        sb.Append(char.ToUpper(c));
-                        upcase = false;
+                    string special = MapSpecialWord(name, i, j - i);
+                    if (special != null) {
+                        // "id_id" -/-> "IDID"
+                        if (lastWasSpecial) {
+                            return null;
+                        }
+                        mangled.Append(special.ToUpperInvariant());
+                        lastWasSpecial = true;
                     } else {
-                        sb.Append(c);
+                        mangled.Append(Char.ToUpperInvariant(name[i]));
+                        mangled.Append(name, i + 1, j - i - 1);
+                        lastWasSpecial = false;
                     }
                 }
+
+                i = ++j;
             }
-            if (upcase) {
-                // string was empty or ended with an underscore, can't unmangle
-                return null;
-            }
-            return sb.ToString();
+
+            return mangled.ToString();
         }
 
-        public static string/*!*/ MangleName(string/*!*/ name) {
-            Assert.NotNull(name);
+        /// <summary>
+        /// Converts a camelCase or PascalCase name to a Ruby name (FooBar -> foo_bar).
+        /// Returns null if the name is not in camelCase or PascalCase (FooBAR, foo, etc.).
+        /// Characters that are not upper case letters are treated as lower-case letters.
+        /// </summary>
+        public static string TryMangleName(string/*!*/ name) {
+            ContractUtils.RequiresNotNull(name, "name");
+            StringBuilder mangled = null;
+            int i = 0;
+            while (i < name.Length) {
+                char c = name[i];
+                if (Char.IsUpper(c)) {
+                    int j = i + 1;
+                    while (j < name.Length && Char.IsUpper(name, j)) {
+                        j++;
+                    }
 
-            if (name.ToUpper().Equals("INITIALIZE")) {
-                // Special case for compatibility with CLR
-                return name;
-            }
+                    if (j < name.Length) {
+                        j--;
+                    }
 
-            StringBuilder result = new StringBuilder(name.Length);
+                    if (mangled == null) {
+                        mangled = new StringBuilder();
+                        mangled.Append(name, 0, i);
+                    } 
 
-            for (int i = 0; i < name.Length; i++) {
-                if (Char.IsUpper(name[i])) {
-                    if (!(i == 0 || i + 1 < name.Length && Char.IsUpper(name[i + 1]) || i + 1 == name.Length && Char.IsUpper(name[i - 1]))) {
-                        result.Append('_');
+                    if (i > 0) {
+                        mangled.Append('_');
                     }
-                    result.Append(Char.ToLower(name[i]));
+
+                    int count = j - i;
+                    if (count == 0) {
+                        // NaN{end}, NaNXxx
+                        if (i + 2 < name.Length && 
+                            Char.IsUpper(name[i + 2]) && 
+                            (i + 3 == name.Length || Char.IsUpper(name[i + 3]) && 
+                            (i + 4 < name.Length && !Char.IsUpper(name[i + 4])))) {
+                            return null;
+                        } else {
+                            // X{end}, In, NaN, Xml, Html, ...
+                            mangled.Append(Char.ToLowerInvariant(c));
+                            i++;
+                        }
+                    } else if (count == 1) {
+                        // FXx
+                        mangled.Append(Char.ToLowerInvariant(c));
+                        i++;
+                    } else {
+                        // FOXxx, FOOXxx, FOOOXxx, ...
+                        string special = MapSpecialWord(name, i, count);
+                        if (special != null) {
+                            mangled.Append(special.ToLowerInvariant());
+                            i = j;
+                        } else {
+                            return null;
+                        }
+                    }
                 } else {
-                    result.Append(name[i]);
+                    if (mangled != null) {
+                        mangled.Append(c);
+                    }
+                    i++;
                 }
             }
 
-            return result.ToString();
+            return mangled != null ? mangled.ToString() : null;
         }
 
+        private static string MapSpecialWord(string/*!*/ name, int start, int count) {
+            if (count == 2) {
+                return IsTwoLetterWord(name, start) ? null : name.Substring(start, count);
+            }
+
+            return null;
+        }
+
+        private static bool IsTwoLetterWord(string/*!*/ str, int index) {
+            int c = LetterPair(str, index);
+            switch (c) {
+                case ('a' << 8) | 't':
+                case ('a' << 8) | 's':
+                case ('b' << 8) | 'y':
+                case ('d' << 8) | 'o':
+                case ('i' << 8) | 'd':
+                case ('i' << 8) | 't':
+                case ('i' << 8) | 'f':
+                case ('i' << 8) | 'n':
+                case ('i' << 8) | 's':
+                case ('g' << 8) | 'o':
+                case ('m' << 8) | 'y':
+                case ('o' << 8) | 'f':
+                case ('o' << 8) | 'k':
+                case ('o' << 8) | 'n':
+                case ('t' << 8) | 'o':
+                case ('u' << 8) | 'p':
+                    return true;
+            }
+            return false;
+        }
+
+        private static int LetterPair(string/*!*/ str, int index) {
+            return (str[index + 1] & 0xff00) == 0 ? (Char.ToLowerInvariant(str[index]) << 8) | Char.ToLowerInvariant(str[index + 1]) : -1;
+        }
+
         #endregion
 
         #region Constants
===================================================================
edit: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Runtime/Utils.cs;C993045
File: Utils.cs
===================================================================
--- $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Runtime/Utils.cs;C993045  (server)    7/16/2009 11:56 AM
+++ Shelved Change: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Runtime/Utils.cs;mangling
@@ -327,6 +327,19 @@
             return defaultResult;
         }
 
+        internal static bool SubstringEquals(string/*!*/ name, int start, int count, string/*!*/ other) {
+            if (count != other.Length) {
+                return false;
+            }
+
+            for (int i = 0; i < count; i++) {
+                if (name[start + i] != other[i]) {
+                    return false;
+                }
+            }
+            return true;
+        }
+
         public static TOutput[]/*!*/ ConvertAll<TInput, TOutput>(this TInput[]/*!*/ array, Converter<TInput, TOutput>/*!*/ converter) {
             var result = new TOutput[array.Length];
             for (int i = 0; i < array.Length; i++) {
===================================================================
edit: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Tests/Interop/net/bcl/string/construction_spec.rb;C949767
File: construction_spec.rb
===================================================================
--- $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Tests/Interop/net/bcl/string/construction_spec.rb;C949767  (server)    7/16/2009 3:11 PM
+++ Shelved Change: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Tests/Interop/net/bcl/string/construction_spec.rb;mangling
@@ -7,7 +7,7 @@
       return "a";
     }
 
-    public string Aa(){
+    public string AA(){
       return "aa";
     }
   }
===================================================================
