<?xml version="1.0" encoding="UTF-8"?>
<commit>
  <added type="array">
    <added>
      <filename>Merlin/Main/Languages/IronPython/IronPython.Modules/_bytesio.cs</filename>
    </added>
    <added>
      <filename>Merlin/Main/Languages/IronPython/IronPython.Modules/_codecs.cs</filename>
    </added>
    <added>
      <filename>Merlin/Main/Languages/IronPython/IronPython.Modules/_fileio.cs</filename>
    </added>
    <added>
      <filename>Merlin/Main/Languages/Ruby/Experimental/Arrays/hash.rb</filename>
    </added>
  </added>
  <modified type="array">
    <modified>
      <diff>@@ -58,6 +58,9 @@ describe &quot;Array#hash&quot; do
     a.fill 'a', 0..3
     b = %w|a a a a|
     a.hash.should == b.hash
+
+    # recursively:
+    [[a], [[a]]].hash.should == [[a], [[a]]].hash
   end
 
   it &quot;returns the same value if arrays are #eql?&quot; do</diff>
      <filename>Merlin/External.LCA_RESTRICTED/Languages/IronRuby/mspec/rubyspec/core/array/hash_spec.rb</filename>
    </modified>
    <modified>
      <diff></diff>
      <filename>Merlin/Main/Languages/IronPython/IronPython.Modules/IronPython.Modules.Build.csproj</filename>
    </modified>
    <modified>
      <diff>@@ -2,7 +2,7 @@
   &lt;PropertyGroup&gt;
     &lt;Configuration Condition=&quot; '$(Configuration)' == '' &quot;&gt;Debug&lt;/Configuration&gt;
     &lt;Platform Condition=&quot; '$(Platform)' == '' &quot;&gt;AnyCPU&lt;/Platform&gt;
-    &lt;ProductVersion&gt;9.0.30729&lt;/ProductVersion&gt;
+    &lt;ProductVersion&gt;9.0.21022&lt;/ProductVersion&gt;
     &lt;SchemaVersion&gt;2.0&lt;/SchemaVersion&gt;
     &lt;ProjectGuid&gt;{155CE436-1669-4A48-8095-410F2430237F}&lt;/ProjectGuid&gt;
     &lt;OutputType&gt;Library&lt;/OutputType&gt;
@@ -90,8 +90,9 @@
     &lt;Compile Include=&quot;array.cs&quot; /&gt;
     &lt;Compile Include=&quot;binascii.cs&quot; /&gt;
     &lt;Compile Include=&quot;cmath.cs&quot; /&gt;
-    &lt;Compile Include=&quot;codecs.cs&quot; /&gt;
+    &lt;Compile Include=&quot;_codecs.cs&quot; /&gt;
     &lt;Compile Include=&quot;ModuleOps.cs&quot; /&gt;
+    &lt;Compile Include=&quot;_bytesio.cs&quot; /&gt;
     &lt;Compile Include=&quot;_codecs_cn.cs&quot; /&gt;
     &lt;Compile Include=&quot;_collections.cs&quot; /&gt;
     &lt;Compile Include=&quot;copy_reg.cs&quot; /&gt;
@@ -106,6 +107,7 @@
     &lt;Compile Include=&quot;marshal.cs&quot; /&gt;
     &lt;Compile Include=&quot;math.cs&quot; /&gt;
     &lt;Compile Include=&quot;math.Generated.cs&quot; /&gt;
+    &lt;Compile Include=&quot;_fileio.cs&quot; /&gt;
     &lt;Compile Include=&quot;_md5.cs&quot; /&gt;
     &lt;Compile Include=&quot;nt.cs&quot; /&gt;
     &lt;Compile Include=&quot;operator.cs&quot; /&gt;
@@ -185,4 +187,4 @@
   &lt;Target Name=&quot;AfterBuild&quot;&gt;
   &lt;/Target&gt;
   --&gt;
-&lt;/Project&gt;
\ No newline at end of file
+&lt;/Project&gt;</diff>
      <filename>Merlin/Main/Languages/IronPython/IronPython.Modules/IronPython.Modules.csproj</filename>
    </modified>
    <modified>
      <diff>@@ -237,6 +237,7 @@ namespace IronPython.Modules {
             public void remove(object value) {
                 lock (_lockObj) {
                     int found = -1;
+                    int startVersion = _version;
                     WalkDeque(delegate(int index) {
                         if (PythonOps.EqualRetBool(_data[index], value)) {
                             found = index;
@@ -244,6 +245,9 @@ namespace IronPython.Modules {
                         }
                         return true;
                     });
+                    if (_version != startVersion) {
+                        throw PythonOps.IndexError(&quot;deque mutated during remove().&quot;);
+                    }
 
                     if (found == _head) {
                         popleft();
@@ -481,15 +485,15 @@ namespace IronPython.Modules {
             #region IEnumerable Members
 
             IEnumerator IEnumerable.GetEnumerator() {
-                return new deque_iterator(this);
+                return new DequeIterator(this);
             }
 
-            [PythonType]
-            private class deque_iterator : IEnumerator {
+            [PythonType(&quot;deque_iterator&quot;)]
+            private sealed class DequeIterator : IEnumerable, IEnumerator {
                 private readonly deque _deque;
                 private int _curIndex, _moveCnt, _version;
 
-                public deque_iterator(deque d) {
+                public DequeIterator(deque d) {
                     lock (d._lockObj) {
                         _deque = d;
                         _curIndex = d._head - 1;
@@ -529,6 +533,14 @@ namespace IronPython.Modules {
                 }
 
                 #endregion
+
+                #region IEnumerable Members
+
+                public IEnumerator GetEnumerator() {
+                    return this;
+                }
+
+                #endregion
             }
 
             #endregion</diff>
      <filename>Merlin/Main/Languages/IronPython/IronPython.Modules/_collections.cs</filename>
    </modified>
    <modified>
      <diff>@@ -40,8 +40,10 @@ namespace IronPython.Modules {
             private char _typeCode;
             private WeakRefTracker _tracker;
 
-            public PythonArray(string type, [Optional]object initializer) {
-                if (type == null || type.Length != 1) throw PythonOps.TypeError(&quot;expected character, got {0}&quot;, DynamicHelpers.GetPythonType(type));
+            public PythonArray([BytesConversion]string type, [Optional]object initializer) {
+                if (type == null || type.Length != 1) {
+                    throw PythonOps.TypeError(&quot;expected character, got {0}&quot;, PythonTypeOps.GetName(type));
+                }
 
                 _typeCode = type[0];
                 _data = CreateData(_typeCode);
@@ -201,8 +203,20 @@ namespace IronPython.Modules {
                     throw PythonOps.TypeError(&quot;cannot extend with different typecode&quot;);
                 }
 
-                string buf = iterable as string;
-                if (buf != null &amp;&amp; _typeCode != 'u') {
+                string str = iterable as string;
+                if (str != null &amp;&amp; _typeCode != 'u') {
+                    fromstring(str);
+                    return;
+                }
+
+                Bytes bytes = iterable as Bytes;
+                if (bytes != null) {
+                    fromstring(bytes);
+                    return;
+                }
+
+                PythonBuffer buf = iterable as PythonBuffer;
+                if (buf != null) {
                     fromstring(buf);
                     return;
                 }
@@ -237,17 +251,27 @@ namespace IronPython.Modules {
                 fromstring(bytes);
             }
 
-            public void fromstring(string s) {
+            public void fromstring([NotNull]Bytes b) {
+                if ((b.Count % itemsize) != 0) throw PythonOps.ValueError(&quot;string length not a multiple of itemsize&quot;);
+                
+                FromStream(new MemoryStream(b._bytes, false));
+            }
+
+            public void fromstring([NotNull]string s) {
                 if ((s.Length % itemsize) != 0) throw PythonOps.ValueError(&quot;string length not a multiple of itemsize&quot;);
                 byte[] bytes = new byte[s.Length];
                 for (int i = 0; i &lt; bytes.Length; i++) {
-                    bytes[i] = (byte)s[i];
+                    bytes[i] = checked((byte)s[i]);
                 }
                 MemoryStream ms = new MemoryStream(bytes);
 
                 FromStream(ms);
             }
 
+            public void fromstring([NotNull]PythonBuffer buf) {
+                fromstring(buf.ToString());
+            }
+
             public void fromunicode(CodeContext/*!*/ context, string s) {
                 if (s == null) throw PythonOps.TypeError(&quot;expected string&quot;);
                 if (s.Length == 0) throw PythonOps.ValueError(&quot;empty string&quot;);
@@ -341,16 +365,11 @@ namespace IronPython.Modules {
                         case 'u': return new string((char)val, 1);
                         case 'h': return (int)(short)val;
                         case 'H': return (int)(ushort)val;
-                        case 'l': return BigInteger.Create((int)val);
+                        case 'l': return val;
                         case 'i': return val;
                         case 'L': return BigInteger.Create((uint)val);
                         case 'I':
-                            uint tmp = (uint)val;
-                            if (tmp &lt;= Int32.MaxValue) {
-                                return (int)(uint)val;
-                            }
-
-                            return (BigInteger)tmp;
+                            return (BigInteger)(uint)val;
                         case 'f': return (double)(float)val;
                         case 'd': return val;
                         default:
@@ -362,6 +381,26 @@ namespace IronPython.Modules {
                 }
             }
 
+            internal byte[] RawGetItem(int index) {
+                MemoryStream ms = new MemoryStream();
+                BinaryWriter bw = new BinaryWriter(ms);
+                switch (_typeCode) {
+                    case 'c': bw.Write((byte)(char)_data.GetData(index)); break;
+                    case 'b': bw.Write((sbyte)_data.GetData(index)); break;
+                    case 'B': bw.Write((byte)_data.GetData(index)); break;
+                    case 'u': bw.Write((char)_data.GetData(index)); break;
+                    case 'h': bw.Write((short)_data.GetData(index)); break;
+                    case 'H': bw.Write((ushort)_data.GetData(index)); break;
+                    case 'l':
+                    case 'i': bw.Write((int)_data.GetData(index)); break;
+                    case 'L':
+                    case 'I': bw.Write((uint)_data.GetData(index)); break;
+                    case 'f': bw.Write((float)_data.GetData(index)); break;
+                    case 'd': bw.Write((double)_data.GetData(index)); break;
+                }
+                return ms.ToArray();
+            }
+
             public void __delitem__(int index) {
                 _data.RemoveAt(PythonOps.FixIndex(index, _data.Length));
             }
@@ -474,8 +513,10 @@ namespace IronPython.Modules {
 
             private void CheckSliceAssignType(object value) {
                 PythonArray pa = value as PythonArray;
-                if (pa != null &amp;&amp; pa._typeCode != _typeCode) {
-                    throw PythonOps.TypeError(&quot;bad array type&quot;);
+                if (pa == null) {
+                    throw PythonOps.TypeError(&quot;can only assign array (not \&quot;{0}\&quot;) to array slice&quot;, PythonTypeOps.GetName(value));
+                } else if (pa != null &amp;&amp; pa._typeCode != _typeCode) {
+                    throw PythonOps.TypeError(&quot;bad argument type for built-in operation&quot;);
                 }
             }
 
@@ -603,8 +644,14 @@ namespace IronPython.Modules {
                 public abstract IntPtr GetAddress();
             }
 
-            private MemoryStream ToStream() {
+            internal MemoryStream ToStream() {
                 MemoryStream ms = new MemoryStream();
+                ToStream(ms);
+                ms.Seek(0, SeekOrigin.Begin);
+                return ms;
+            }
+
+            internal void ToStream(Stream ms) {
                 BinaryWriter bw = new BinaryWriter(ms);
                 for (int i = 0; i &lt; _data.Length; i++) {
                     switch (_typeCode) {
@@ -622,8 +669,6 @@ namespace IronPython.Modules {
                         case 'd': bw.Write((double)_data.GetData(i)); break;
                     }
                 }
-                ms.Seek(0, SeekOrigin.Begin);
-                return ms;                
             }
 
             internal byte[] ToByteArray() {
@@ -659,7 +704,7 @@ namespace IronPython.Modules {
             }
 
             // a version of FromStream that overwrites starting at 'index'
-            internal void FromStream(int index, Stream ms) {
+            internal void FromStream(Stream ms, int index) {
                 BinaryReader br = new BinaryReader(ms);
 
                 for (int i = index; i &lt; ms.Length / itemsize + index; i++) {
@@ -683,6 +728,68 @@ namespace IronPython.Modules {
                 }
             }
 
+            // a version of FromStream that overwrites up to 'nbytes' bytes, starting at 'index' (padding
+            // with trailing zeros if necessary for alignment). Returns the number of bytes written.
+            internal long FromStream(Stream ms, int index, int nbytes) {
+                BinaryReader br = new BinaryReader(ms);
+
+                if (nbytes &lt;= 0) {
+                    return 0;
+                }
+
+                int len = Math.Min((int)(ms.Length - ms.Position), nbytes);
+                for (int i = index; i &lt; len / itemsize + index; i++) {
+                    object value;
+                    switch (_typeCode) {
+                        case 'c': value = (char)br.ReadByte(); break;
+                        case 'b': value = (sbyte)br.ReadByte(); break;
+                        case 'B': value = br.ReadByte(); break;
+                        case 'u': value = br.ReadChar(); break;
+                        case 'h': value = br.ReadInt16(); break;
+                        case 'H': value = br.ReadUInt16(); break;
+                        case 'i': value = br.ReadInt32(); break;
+                        case 'I': value = br.ReadUInt32(); break;
+                        case 'l': value = br.ReadInt32(); break;
+                        case 'L': value = br.ReadUInt32(); break;
+                        case 'f': value = br.ReadSingle(); break;
+                        case 'd': value = br.ReadDouble(); break;
+                        default: throw new InvalidOperationException(); // should never happen
+                    }
+                    _data.SetData(i, value);
+                }
+
+                if (len % itemsize &gt; 0) {
+                    Int64 value = 0;
+                    for (int i = 0; i &lt; len % itemsize; i++) {
+                        value &lt;&lt;= 8;
+                        value |= br.ReadByte();
+                    }
+
+                    switch (_typeCode) {
+                        case 'c': _data.SetData(len / itemsize + index, (char)value); break;
+                        case 'b': _data.SetData(len / itemsize + index, (sbyte)value); break;
+                        case 'B': _data.SetData(len / itemsize + index, (byte)value); break;
+                        case 'u': _data.SetData(len / itemsize + index, (char)value); break;
+                        case 'h': _data.SetData(len / itemsize + index, (short)value); break;
+                        case 'H': _data.SetData(len / itemsize + index, (ushort)value); break;
+                        case 'l':
+                        case 'i': _data.SetData(len / itemsize + index, (int)value); break;
+                        case 'L':
+                        case 'I': _data.SetData(len / itemsize + index, (uint)value); break;
+                        case 'f': _data.SetData(len / itemsize + index, BitConverter.ToSingle(BitConverter.GetBytes((Int32)value), 0)); break;
+#if !SILVERLIGHT
+                        case 'd': _data.SetData(len / itemsize + index, BitConverter.Int64BitsToDouble(value)); break;
+#else
+                        case 'd': _data.SetData(len / itemsize + index, BitConverter.ToDouble(BitConverter.GetBytes(value), 0)); break;
+#endif
+                        default:
+                            throw PythonOps.ValueError(&quot;Bad type code (expected one of 'c', 'b', 'B', 'u', 'H', 'h', 'i', 'I', 'l', 'L', 'f', 'd')&quot;);
+                    }
+                }
+
+                return len;
+            }
+
             private class ArrayData&lt;T&gt; : ArrayData {
                 private T[] _data;
                 private int _count;
@@ -870,8 +977,12 @@ namespace IronPython.Modules {
                 }
 
                 StringBuilder sb = new StringBuilder(res);
-                if (_typeCode == 'c') {
-                    sb.Append(&quot;, '&quot;);
+                if (_typeCode == 'c' || _typeCode == 'u') {
+                    if (_typeCode == 'u') {
+                        sb.Append(&quot;, u'&quot;);
+                    } else {
+                        sb.Append(&quot;, '&quot;);
+                    }
                     for (int i = 0; i &lt; _data.Length; i++) {
                         sb.Append((char)_data.GetData(i));
                     }</diff>
      <filename>Merlin/Main/Languages/IronPython/IronPython.Modules/array.cs</filename>
    </modified>
    <modified>
      <diff>@@ -37,10 +37,16 @@ using IronPython.Runtime.Types;
 [assembly: PythonModule(&quot;nt&quot;, typeof(IronPython.Modules.PythonNT))]
 namespace IronPython.Modules {
     public static class PythonNT {
+#if !SILVERLIGHT
+        private static Dictionary&lt;int, Process&gt; _processToIdMapping = new Dictionary&lt;int, Process&gt;();
+        private static List&lt;int&gt; _freeProcessIds = new List&lt;int&gt;();
+        private static int _processCount;
+#endif
+
         #region Public API Surface
 
 #if !SILVERLIGHT // FailFast
-        public static void abort() {
+        public static void abort() {            
             System.Environment.FailFast(&quot;IronPython os.abort&quot;);
         }
 #endif
@@ -404,10 +410,30 @@ namespace IronPython.Modules {
         }
 
 #if !SILVERLIGHT
+        /// &lt;summary&gt;
+        /// spawns a new process.
+        /// 
+        /// If mode is nt.P_WAIT then then the call blocks until the process exits and the return value
+        /// is the exit code.
+        /// 
+        /// Otherwise the call returns a handle to the process.  The caller must then call nt.waitpid(pid, options)
+        /// to free the handle and get the exit code of the process.  Failure to call nt.waitpid will result
+        /// in a handle leak.
+        /// &lt;/summary&gt;
         public static object spawnl(CodeContext/*!*/ context, int mode, string path, params object[] args) {
             return SpawnProcessImpl(context, MakeProcess(), mode, path, args);
         }
 
+        /// &lt;summary&gt;
+        /// spawns a new process.
+        /// 
+        /// If mode is nt.P_WAIT then then the call blocks until the process exits and the return value
+        /// is the exit code.
+        /// 
+        /// Otherwise the call returns a handle to the process.  The caller must then call nt.waitpid(pid, options)
+        /// to free the handle and get the exit code of the process.  Failure to call nt.waitpid will result
+        /// in a handle leak.
+        /// &lt;/summary&gt;
         public static object spawnle(CodeContext/*!*/ context, int mode, string path, params object[] args) {
             if (args.Length &lt; 1) {
                 throw PythonOps.TypeError(&quot;spawnle() takes at least three arguments ({0} given)&quot;, 2 + args.Length);
@@ -422,10 +448,30 @@ namespace IronPython.Modules {
             return SpawnProcessImpl(context, process, mode, path, slicedArgs);
         }
 
+        /// &lt;summary&gt;
+        /// spawns a new process.
+        /// 
+        /// If mode is nt.P_WAIT then then the call blocks until the process exits and the return value
+        /// is the exit code.
+        /// 
+        /// Otherwise the call returns a handle to the process.  The caller must then call nt.waitpid(pid, options)
+        /// to free the handle and get the exit code of the process.  Failure to call nt.waitpid will result
+        /// in a handle leak.
+        /// &lt;/summary&gt;
         public static object spawnv(CodeContext/*!*/ context, int mode, string path, object args) {
             return SpawnProcessImpl(context, MakeProcess(), mode, path, args);
         }
 
+        /// &lt;summary&gt;
+        /// spawns a new process.
+        /// 
+        /// If mode is nt.P_WAIT then then the call blocks until the process exits and the return value
+        /// is the exit code.
+        /// 
+        /// Otherwise the call returns a handle to the process.  The caller must then call nt.waitpid(pid, options)
+        /// to free the handle and get the exit code of the process.  Failure to call nt.waitpid will result
+        /// in a handle leak.
+        /// &lt;/summary&gt;
         public static object spawnve(CodeContext/*!*/ context, int mode, string path, object args, object env) {
             Process process = MakeProcess();
             SetEnvironment(process.StartInfo.EnvironmentVariables, env);
@@ -453,13 +499,30 @@ namespace IronPython.Modules {
             if (!process.Start()) {
                 throw PythonOps.OSError(&quot;Cannot start process: {0}&quot;, path);
             }
-            if (mode == (int)P_WAIT) {
+            if (mode == P_WAIT) {
                 process.WaitForExit();
                 int exitCode = process.ExitCode;
                 process.Close();
                 return exitCode;
-            } else {
-                return process.Id;
+            }
+
+            lock (_processToIdMapping) {
+                int id;
+                if (_freeProcessIds.Count &gt; 0) {
+                    id = _freeProcessIds[_freeProcessIds.Count - 1];
+                    _freeProcessIds.RemoveAt(_freeProcessIds.Count - 1);
+                } else {
+                    // process IDs are handles on CPython/Win32 so we match
+                    // that behavior and return something that is handle like.  Handles
+                    // on NT are guaranteed to have the low 2 bits not set and users
+                    // could use these for their own purposes.  We therefore match that
+                    // behavior here.
+                    _processCount += 4; 
+                    id = _processCount;
+                }
+
+                _processToIdMapping[id] = process;
+                return ScriptingRuntimeHelpers.Int32ToObject(id);
             }
         }
 
@@ -824,6 +887,54 @@ namespace IronPython.Modules {
             return sr;
         }
 
+        public static string strerror(int code) {
+            switch(code) {
+                case PythonErrorNumber.E2BIG: return &quot;Arg list too long&quot;;
+                case PythonErrorNumber.EACCES: return &quot;Permission denied&quot;;
+                case PythonErrorNumber.EAGAIN: return &quot;Resource temporarily unavailable&quot;;
+                case PythonErrorNumber.EBADF: return &quot;Bad file descriptor&quot;;
+                case PythonErrorNumber.EBUSY: return &quot;Resource device&quot;;
+                case PythonErrorNumber.ECHILD: return &quot;No child processes&quot;;
+                case PythonErrorNumber.EDEADLK: return &quot;Resource deadlock avoided&quot;;
+                case PythonErrorNumber.EDOM: return &quot;Domain error&quot;;
+                case PythonErrorNumber.EDQUOT: return &quot;Unknown error&quot;;
+                case PythonErrorNumber.EEXIST: return &quot;File exists&quot;;
+                case PythonErrorNumber.EFAULT: return &quot;Bad address&quot;;
+                case PythonErrorNumber.EFBIG: return &quot;File too large&quot;;
+                case PythonErrorNumber.EILSEQ: return &quot;Illegal byte sequence&quot;;
+                case PythonErrorNumber.EINTR: return &quot;Interrupted function call&quot;;
+                case PythonErrorNumber.EINVAL: return &quot;Invalid argument&quot;;
+                case PythonErrorNumber.EIO: return &quot;Input/output error&quot;;
+                case PythonErrorNumber.EISCONN: return &quot;Unknown error&quot;;
+                case PythonErrorNumber.EISDIR: return &quot;Is a directory&quot;;
+                case PythonErrorNumber.EMFILE: return &quot;Too many open files&quot;;
+                case PythonErrorNumber.EMLINK: return &quot;Too many links&quot;;
+                case PythonErrorNumber.ENAMETOOLONG: return &quot;Filename too long&quot;;
+                case PythonErrorNumber.ENFILE: return &quot;Too many open files in system&quot;;
+                case PythonErrorNumber.ENODEV: return &quot;No such device&quot;;
+                case PythonErrorNumber.ENOENT: return &quot;No such file or directory&quot;;
+                case PythonErrorNumber.ENOEXEC: return &quot;Exec format error&quot;;
+                case PythonErrorNumber.ENOLCK: return &quot;No locks available&quot;;
+                case PythonErrorNumber.ENOMEM: return &quot;Not enough space&quot;;
+                case PythonErrorNumber.ENOSPC: return &quot;No space left on device&quot;;
+                case PythonErrorNumber.ENOSYS: return &quot;Function not implemented&quot;;
+                case PythonErrorNumber.ENOTDIR: return &quot;Not a directory&quot;;
+                case PythonErrorNumber.ENOTEMPTY: return &quot;Directory not empty&quot;;
+                case PythonErrorNumber.ENOTSOCK: return &quot;Unknown error&quot;;
+                case PythonErrorNumber.ENOTTY: return &quot;Inappropriate I/O control operation&quot;;
+                case PythonErrorNumber.ENXIO: return &quot;No such device or address&quot;;
+                case PythonErrorNumber.EPERM: return &quot;Operation not permitted&quot;;
+                case PythonErrorNumber.EPIPE: return &quot;Broken pipe&quot;;
+                case PythonErrorNumber.ERANGE: return &quot;Result too large&quot;;
+                case PythonErrorNumber.EROFS: return &quot;Read-only file system&quot;;
+                case PythonErrorNumber.ESPIPE: return &quot;Invalid seek&quot;;
+                case PythonErrorNumber.ESRCH: return &quot;No such process&quot;;
+                case PythonErrorNumber.EXDEV: return &quot;Improper link&quot;;
+                default:
+                    return &quot;Unknown error &quot; + code;
+            }
+        }
+
         private static PythonType WindowsError {
             get {
 #if !SILVERLIGHT
@@ -963,12 +1074,23 @@ namespace IronPython.Modules {
         }
 
         public static PythonTuple waitpid(int pid, object options) {
-            System.Diagnostics.Process process = System.Diagnostics.Process.GetProcessById(pid);
-            if (process == null) {
-                throw PythonExceptions.CreateThrowable(PythonExceptions.OSError, PythonErrorNumber.ECHILD, &quot;Cannot find process &quot; + pid);
+            Process process;
+            lock (_processToIdMapping) {
+                if (!_processToIdMapping.TryGetValue(pid, out process)) {
+                    throw PythonExceptions.CreateThrowable(PythonExceptions.OSError, PythonErrorNumber.ECHILD, &quot;No child processes&quot;);
+                }
             }
+
             process.WaitForExit();
-            return PythonTuple.MakeTuple(pid, process.ExitCode);
+            PythonTuple res = PythonTuple.MakeTuple(pid, process.ExitCode);
+
+            lock (_processToIdMapping) {
+                // lower 3 bits are user defined and ignored (matching NT's handle semantics)
+                _processToIdMapping.Remove(pid &amp; ~0x03);
+                _freeProcessIds.Add(pid &amp; ~0x03);
+            }
+
+            return res;
         }
 #endif
 </diff>
      <filename>Merlin/Main/Languages/IronPython/IronPython.Modules/nt.cs</filename>
    </modified>
    <modified>
      <diff>@@ -418,7 +418,7 @@ namespace IronPython.Modules {
                     throw MakeException(_context, e);
                 }
 
-                buffer.FromStream(0, new MemoryStream(byteBuffer));
+                buffer.FromStream(new MemoryStream(byteBuffer), 0);
                 return bytesRead;
             }
 
@@ -479,7 +479,7 @@ namespace IronPython.Modules {
                     throw MakeException(_context, e);
                 }
 
-                buffer.FromStream(0, new MemoryStream(byteBuffer));
+                buffer.FromStream(new MemoryStream(byteBuffer), 0);
                 PythonTuple remoteAddress = EndPointToTuple((IPEndPoint)remoteEP);
                 return PythonTuple.MakeTuple(bytesRead, remoteAddress);
             }</diff>
      <filename>Merlin/Main/Languages/IronPython/IronPython.Modules/socket.cs</filename>
    </modified>
    <modified>
      <diff>@@ -209,9 +209,9 @@ namespace IronPython.Modules {
                 } catch (SystemExitException) {
                     // ignore and quit
                 } catch (Exception e) {
-                    PythonOps.Print(_context, &quot;Unhandled exception on thread&quot;);
+                    PythonOps.PrintWithDest(_context, PythonContext.GetContext(_context).SystemStandardError, &quot;Unhandled exception on thread&quot;);
                     string result = _context.LanguageContext.FormatException(e);
-                    PythonOps.Print(_context, result);
+                    PythonOps.PrintWithDest(_context, PythonContext.GetContext(_context).SystemStandardError, result);
                 }
             }
         }</diff>
      <filename>Merlin/Main/Languages/IronPython/IronPython.Modules/thread.cs</filename>
    </modified>
    <modified>
      <diff>@@ -23,11 +23,15 @@ Project(&quot;{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}&quot;) = &quot;Microsoft.Scripting.Extensi
 EndProject
 Project(&quot;{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}&quot;) = &quot;Microsoft.Dynamic&quot;, &quot;..\..\..\..\ndp\fx\src\Dynamic\System\Dynamic\Microsoft.Dynamic.csproj&quot;, &quot;{D4AE44AD-07B9-41DC-BB3B-1FDCDE3C987D}&quot;
 EndProject
+Project(&quot;{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}&quot;) = &quot;IronPythonConsoleAny&quot;, &quot;IronPythonConsoleAny\IronPythonConsoleAny.csproj&quot;, &quot;{F1D861C5-D9D5-4CDA-968B-8275F5D9F6D2}&quot;
+EndProject
+Project(&quot;{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}&quot;) = &quot;IronPythonWindowAny&quot;, &quot;IronPythonWindowAny\IronPythonWindowAny.csproj&quot;, &quot;{7F6F9AB3-9943-4316-BD4C-A10F580BC75C}&quot;
+EndProject
 Project(&quot;{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}&quot;) = &quot;Microsoft.Scripting.Debugging&quot;, &quot;..\..\Debugging\Microsoft.Scripting.Debugging\Microsoft.Scripting.Debugging.csproj&quot;, &quot;{ED82A346-1CD9-4CB0-9C00-4CDD4CF577CF}&quot;
 EndProject
 Global
 	GlobalSection(TeamFoundationVersionControl) = preSolution
-		SccNumberOfProjects = 12
+		SccNumberOfProjects = 13
 		SccEnterpriseProvider = {4CA58AB2-18FA-4F8D-95D4-32DDF27D184C}
 		SccTeamFoundationServer = http://vstfdevdiv:8080/
 		SccProjectUniqueName0 = IronPython\\IronPython.csproj
@@ -85,11 +89,21 @@ Global
 		SccAuxPath10 = http://vstfdevdiv:8080
 		SccLocalPath10 = ..\\..\\..\\..\\ndp\\fx\\src\\Dynamic\\System\\Dynamic
 		SccProvider10 = {4CA58AB2-18FA-4F8D-95D4-32DDF27D184C}
-		SccProjectUniqueName11 = ..\\..\\Debugging\\Microsoft.Scripting.Debugging\\Microsoft.Scripting.Debugging.csproj
-		SccProjectName11 = ../../Debugging/Microsoft.Scripting.Debugging
+		SccProjectUniqueName11 = IronPythonConsoleAny\\IronPythonConsoleAny.csproj
+		SccProjectName11 = IronPythonConsoleAny
+		SccLocalPath11 = IronPythonConsoleAny
 		SccAuxPath11 = http://vstfdevdiv:8080
-		SccLocalPath11 = ..\\..\\Debugging\\Microsoft.Scripting.Debugging
 		SccProvider11 = {4CA58AB2-18FA-4F8D-95D4-32DDF27D184C}
+		SccProjectUniqueName12 = IronPythonWindowAny\\IronPythonWindowAny.csproj
+		SccProjectName12 = IronPythonWindowAny
+		SccLocalPath12 = IronPythonWindowAny
+		SccAuxPath12 = http://vstfdevdiv:8080
+		SccProvider12 = {4CA58AB2-18FA-4F8D-95D4-32DDF27D184C}
+		SccProjectUniqueName13 = ..\\..\\Debugging\\Microsoft.Scripting.Debugging\\Microsoft.Scripting.Debugging.csproj
+		SccProjectName13 = ../../Debugging/Microsoft.Scripting.Debugging
+		SccAuxPath13 = http://vstfdevdiv:8080
+		SccLocalPath13 = ..\\..\\Debugging\\Microsoft.Scripting.Debugging
+		SccProvider13 = {4CA58AB2-18FA-4F8D-95D4-32DDF27D184C}
 	EndGlobalSection
 	GlobalSection(SolutionConfigurationPlatforms) = preSolution
 		Build Debug|Any CPU = Build Debug|Any CPU
@@ -249,6 +263,18 @@ Global
 		{D4AE44AD-07B9-41DC-BB3B-1FDCDE3C987D}.Signed Release|Any CPU.ActiveCfg = Release|Any CPU
 		{D4AE44AD-07B9-41DC-BB3B-1FDCDE3C987D}.Silverlight Debug|Any CPU.ActiveCfg = Debug|Any CPU
 		{D4AE44AD-07B9-41DC-BB3B-1FDCDE3C987D}.Silverlight Release|Any CPU.ActiveCfg = Release|Any CPU
+		{F1D861C5-D9D5-4CDA-968B-8275F5D9F6D2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{F1D861C5-D9D5-4CDA-968B-8275F5D9F6D2}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{F1D861C5-D9D5-4CDA-968B-8275F5D9F6D2}.FxCop|Any CPU.ActiveCfg = Release|Any CPU
+		{F1D861C5-D9D5-4CDA-968B-8275F5D9F6D2}.FxCop|Any CPU.Build.0 = Release|Any CPU
+		{F1D861C5-D9D5-4CDA-968B-8275F5D9F6D2}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{F1D861C5-D9D5-4CDA-968B-8275F5D9F6D2}.Release|Any CPU.Build.0 = Release|Any CPU
+		{7F6F9AB3-9943-4316-BD4C-A10F580BC75C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{7F6F9AB3-9943-4316-BD4C-A10F580BC75C}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{7F6F9AB3-9943-4316-BD4C-A10F580BC75C}.FxCop|Any CPU.ActiveCfg = Release|Any CPU
+		{7F6F9AB3-9943-4316-BD4C-A10F580BC75C}.FxCop|Any CPU.Build.0 = Release|Any CPU
+		{7F6F9AB3-9943-4316-BD4C-A10F580BC75C}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{7F6F9AB3-9943-4316-BD4C-A10F580BC75C}.Release|Any CPU.Build.0 = Release|Any CPU
 		{ED82A346-1CD9-4CB0-9C00-4CDD4CF577CF}.Build Debug|Any CPU.ActiveCfg = Debug|Any CPU
 		{ED82A346-1CD9-4CB0-9C00-4CDD4CF577CF}.Build Debug|Any CPU.Build.0 = Debug|Any CPU
 		{ED82A346-1CD9-4CB0-9C00-4CDD4CF577CF}.Build Release|Any CPU.ActiveCfg = Release|Any CPU</diff>
      <filename>Merlin/Main/Languages/IronPython/IronPython.sln</filename>
    </modified>
    <modified>
      <diff>@@ -140,6 +140,17 @@ namespace IronPython.Runtime.Binding {
                 case TypeCode.Char:
                     res = TryToCharConversion(self);
                     break;
+                case TypeCode.String:
+                    if (self.GetLimitType() == typeof(Bytes) &amp;&amp; !_context.PythonOptions.Python30) {
+                        res = new DynamicMetaObject(
+                            Ast.Call(
+                                typeof(PythonOps).GetMethod(&quot;MakeString&quot;),
+                                AstUtils.Convert(self.Expression, typeof(IList&lt;byte&gt;))
+                            ),
+                            BindingRestrictionsHelpers.GetRuntimeTypeRestriction(self.Expression, typeof(Bytes))
+                        );
+                    }
+                    break;
                 case TypeCode.Object:
                     // !!! Deferral?
                     if (type.IsArray &amp;&amp; self.Value is PythonTuple &amp;&amp; type.GetArrayRank() == 1) {
@@ -169,23 +180,14 @@ namespace IronPython.Runtime.Binding {
                             res = TryToGenericInterfaceConversion(self, type, typeof(IEnumerable), typeof(IEnumerableOfTWrapper&lt;&gt;));
                         }
                     } else if (type == typeof(IEnumerable)) {
-                        if (self.GetLimitType() == typeof(string)) {
-                            // replace strings normal enumeration with our own which returns strings instead of chars.
-                            res = new DynamicMetaObject(
-                                Ast.Call(
-                                    typeof(StringOps).GetMethod(&quot;ConvertToIEnumerable&quot;),
-                                    AstUtils.Convert(self.Expression, typeof(string))
-                                ),
-                                BindingRestrictionsHelpers.GetRuntimeTypeRestriction(self.Expression, typeof(string))
-                            );
-                        } else if (!typeof(IEnumerable).IsAssignableFrom(self.GetLimitType()) &amp;&amp; IsIndexless(self)) {
-                            res = PythonProtocol.ConvertToIEnumerable(this, self.Restrict(self.GetLimitType()));
+                        if (!typeof(IEnumerable).IsAssignableFrom(self.GetLimitType()) &amp;&amp; IsIndexless(self)) {
+                            res = ConvertToIEnumerable(this, self.Restrict(self.GetLimitType()));
                         }
                     } else if (type == typeof(IEnumerator)) {
                         if (!typeof(IEnumerator).IsAssignableFrom(self.GetLimitType()) &amp;&amp;
                             !typeof(IEnumerable).IsAssignableFrom(self.GetLimitType()) &amp;&amp;
                             IsIndexless(self)) {
-                            res = PythonProtocol.ConvertToIEnumerator(this, self.Restrict(self.GetLimitType()));
+                            res = ConvertToIEnumerator(this, self.Restrict(self.GetLimitType()));
                         }
                     }
                     break;
@@ -257,7 +259,30 @@ namespace IronPython.Runtime.Binding {
                     res = (T)(object)new Func&lt;CallSite, object, bool&gt;(ObjectToBoolConversion);
                 }
             } else if (target != null) {
-                if (target.GetType() == Type || Type.IsAssignableFrom(target.GetType())) {
+                // Special cases - string or bytes to IEnumerable or IEnumerator
+                if (target is string) {
+                    if (typeof(T) == typeof(Func&lt;CallSite, string, IEnumerable&gt;)) {
+                        res = (T)(object)new Func&lt;CallSite, string, IEnumerable&gt;(StringToIEnumerableConversion);
+                    } else if (typeof(T) == typeof(Func&lt;CallSite, string, IEnumerator&gt;)) {
+                        res = (T)(object)new Func&lt;CallSite, string, IEnumerator&gt;(StringToIEnumeratorConversion);
+                    } else if (typeof(T) == typeof(Func&lt;CallSite, object, IEnumerable&gt;)) {
+                        res = (T)(object)new Func&lt;CallSite, object, IEnumerable&gt;(ObjectToIEnumerableConversion);
+                    } else if (typeof(T) == typeof(Func&lt;CallSite, object, IEnumerator&gt;)) {
+                        res = (T)(object)new Func&lt;CallSite, object, IEnumerator&gt;(ObjectToIEnumeratorConversion);
+                    }
+                } else if (target.GetType() == typeof(Bytes)) {
+                    if (typeof(T) == typeof(Func&lt;CallSite, Bytes, IEnumerable&gt;)) {
+                        res = (T)(object)new Func&lt;CallSite, Bytes, IEnumerable&gt;(BytesToIEnumerableConversion);
+                    } else if (typeof(T) == typeof(Func&lt;CallSite, Bytes, IEnumerator&gt;)) {
+                        res = (T)(object)new Func&lt;CallSite, Bytes, IEnumerator&gt;(BytesToIEnumeratorConversion);
+                    } else if (typeof(T) == typeof(Func&lt;CallSite, object, IEnumerable&gt;)) {
+                        res = (T)(object)new Func&lt;CallSite, object, IEnumerable&gt;(ObjectToIEnumerableConversion);
+                    } else if (typeof(T) == typeof(Func&lt;CallSite, object, IEnumerator&gt;)) {
+                        res = (T)(object)new Func&lt;CallSite, object, IEnumerator&gt;(ObjectToIEnumeratorConversion);
+                    }
+                }
+                
+                if (res == null &amp;&amp; (target.GetType() == Type || Type.IsAssignableFrom(target.GetType()))) {
                     if (typeof(T) == typeof(Func&lt;CallSite, object, object&gt;)) {
                         // called via a helper call site in the runtime (e.g. Converter.Convert)
                         res = (T)(object)new Func&lt;CallSite, object, object&gt;(new IdentityConversion(target.GetType()).Convert);
@@ -350,6 +375,70 @@ namespace IronPython.Runtime.Binding {
             return ((CallSite&lt;Func&lt;CallSite, object, bool&gt;&gt;)site).Update(site, value);
         }
 
+        public IEnumerable StringToIEnumerableConversion(CallSite site, string value) {
+            if (value == null) {
+                return ((CallSite&lt;Func&lt;CallSite, string, IEnumerable&gt;&gt;)site).Update(site, value);
+            }
+
+            return PythonOps.StringEnumerable(value);
+        }
+
+        public IEnumerator StringToIEnumeratorConversion(CallSite site, string value) {
+            if (value == null) {
+                return ((CallSite&lt;Func&lt;CallSite, string, IEnumerator&gt;&gt;)site).Update(site, value);
+            }
+
+            return PythonOps.StringEnumerator(value);
+        }
+
+        public IEnumerable BytesToIEnumerableConversion(CallSite site, Bytes value) {
+            if (value == null) {
+                return ((CallSite&lt;Func&lt;CallSite, Bytes, IEnumerable&gt;&gt;)site).Update(site, value);
+            }
+
+            return _context.PythonOptions.Python30 ?
+                PythonOps.BytesIntEnumerable(value) :
+                PythonOps.BytesEnumerable(value);
+        }
+
+        public IEnumerator BytesToIEnumeratorConversion(CallSite site, Bytes value) {
+            if (value == null) {
+                return ((CallSite&lt;Func&lt;CallSite, Bytes, IEnumerator&gt;&gt;)site).Update(site, value);
+            }
+
+            return _context.PythonOptions.Python30 ?
+                (IEnumerator)PythonOps.BytesIntEnumerator(value) :
+                (IEnumerator)PythonOps.BytesEnumerator(value);
+        }
+
+        public IEnumerable ObjectToIEnumerableConversion(CallSite site, object value) {
+            if (value != null) {
+                if (value is string) {
+                    return PythonOps.StringEnumerable((string)value);
+                } else if (value.GetType() == typeof(Bytes)) {
+                    return _context.PythonOptions.Python30 ?
+                        PythonOps.BytesIntEnumerable((Bytes)value) :
+                        PythonOps.BytesEnumerable((Bytes)value);
+                }
+            }
+
+            return ((CallSite&lt;Func&lt;CallSite, object, IEnumerable&gt;&gt;)site).Update(site, value);
+        }
+
+        public IEnumerator ObjectToIEnumeratorConversion(CallSite site, object value) {
+            if (value != null) {
+                if (value is string) {
+                    return PythonOps.StringEnumerator((string)value);
+                } else if (value.GetType() == typeof(Bytes)) {
+                    return _context.PythonOptions.Python30 ?
+                        (IEnumerator)PythonOps.BytesIntEnumerator((Bytes)value) :
+                        (IEnumerator)PythonOps.BytesEnumerator((Bytes)value);
+                }
+            }
+
+            return ((CallSite&lt;Func&lt;CallSite, object, IEnumerator&gt;&gt;)site).Update(site, value);
+        }
+
         class IdentityConversion {
             private readonly Type _type;
 
@@ -580,6 +669,108 @@ namespace IronPython.Runtime.Binding {
             );
         }
 
+        internal static DynamicMetaObject ConvertToIEnumerable(DynamicMetaObjectBinder/*!*/ conversion, DynamicMetaObject/*!*/ metaUserObject) {
+            PythonType pt = MetaPythonObject.GetPythonType(metaUserObject);
+            PythonContext pyContext = PythonContext.GetPythonContext(conversion);
+            CodeContext context = pyContext.SharedContext;
+            PythonTypeSlot pts;
+
+            if (pt.TryResolveSlot(context, Symbols.Iterator, out pts)) {
+                return MakeIterRule(metaUserObject, &quot;CreatePythonEnumerable&quot;);
+            } else if (pt.TryResolveSlot(context, Symbols.GetItem, out pts)) {
+                return MakeGetItemIterable(metaUserObject, pyContext, pts, &quot;CreateItemEnumerable&quot;);
+            }
+
+            return null;
+        }
+
+        internal static DynamicMetaObject ConvertToIEnumerator(DynamicMetaObjectBinder/*!*/ conversion, DynamicMetaObject/*!*/ metaUserObject) {
+            PythonType pt = MetaPythonObject.GetPythonType(metaUserObject);
+            PythonContext state = PythonContext.GetPythonContext(conversion);
+            CodeContext context = state.SharedContext;
+            PythonTypeSlot pts;
+
+
+            if (pt.TryResolveSlot(context, Symbols.Iterator, out pts)) {
+                ParameterExpression tmp = Ast.Parameter(typeof(object), &quot;iterVal&quot;);
+
+                return new DynamicMetaObject(
+                    Expression.Block(
+                        new[] { tmp },
+                        Expression.Call(
+                            typeof(PythonOps).GetMethod(&quot;CreatePythonEnumerator&quot;),
+                            Ast.Block(
+                                MetaPythonObject.MakeTryGetTypeMember(
+                                    state,
+                                    pts,
+                                    metaUserObject.Expression,
+                                    tmp
+                                ),
+                                Ast.Dynamic(
+                                    new PythonInvokeBinder(
+                                        state,
+                                        new CallSignature(0)
+                                    ),
+                                    typeof(object),
+                                    AstUtils.Constant(context),
+                                    tmp
+                                )
+                            )
+                        )
+                    ),
+                    metaUserObject.Restrictions
+                );
+            } else if (pt.TryResolveSlot(context, Symbols.GetItem, out pts)) {
+                return MakeGetItemIterable(metaUserObject, state, pts, &quot;CreateItemEnumerator&quot;);
+            }
+
+            return null;
+        }
+
+        private static DynamicMetaObject MakeGetItemIterable(DynamicMetaObject metaUserObject, PythonContext state, PythonTypeSlot pts, string method) {
+            ParameterExpression tmp = Ast.Parameter(typeof(object), &quot;getitemVal&quot;);
+            return new DynamicMetaObject(
+                Expression.Block(
+                    new[] { tmp },
+                    Expression.Call(
+                        typeof(PythonOps).GetMethod(method),
+                        Ast.Block(
+                            MetaPythonObject.MakeTryGetTypeMember(
+                                state,
+                                pts,
+                                tmp,
+                                metaUserObject.Expression,
+                                Ast.Call(
+                                    typeof(DynamicHelpers).GetMethod(&quot;GetPythonType&quot;),
+                                    AstUtils.Convert(
+                                        metaUserObject.Expression,
+                                        typeof(object)
+                                    )
+                                )
+                            ),
+                            tmp
+                        ),
+                        AstUtils.Constant(
+                            CallSite&lt;Func&lt;CallSite, CodeContext, object, int, object&gt;&gt;.Create(
+                                new PythonInvokeBinder(state, new CallSignature(1))
+                            )
+                        )
+                    )
+                ),
+                metaUserObject.Restrictions
+            );
+        }
+
+        private static DynamicMetaObject/*!*/ MakeIterRule(DynamicMetaObject/*!*/ self, string methodName) {
+            return new DynamicMetaObject(
+                Ast.Call(
+                    typeof(PythonOps).GetMethod(methodName),
+                    AstUtils.Convert(self.Expression, typeof(object))
+                ),
+                self.Restrictions
+            );
+        }
+
         #endregion
 
         public override string ToString() {</diff>
      <filename>Merlin/Main/Languages/IronPython/IronPython/Runtime/Binding/ConversionBinder.cs</filename>
    </modified>
    <modified>
      <diff>@@ -180,9 +180,9 @@ namespace IronPython.Runtime.Binding {
                         } else if (type == typeof(BigInteger)) {
                             return MakeConvertRuleForCall(conversion, type, this, Symbols.ConvertToLong, &quot;ConvertToLong&quot;);
                         } else if (type == typeof(IEnumerable)) {
-                            return PythonProtocol.ConvertToIEnumerable(conversion, Restrict(Value.GetType()));
+                            return PythonConversionBinder.ConvertToIEnumerable(conversion, Restrict(Value.GetType()));
                         } else if (type == typeof(IEnumerator)){
-                            return PythonProtocol.ConvertToIEnumerator(conversion, Restrict(Value.GetType()));
+                            return PythonConversionBinder.ConvertToIEnumerator(conversion, Restrict(Value.GetType()));
                         } else if (type.IsSubclassOf(typeof(Delegate))) {
                             return MakeDelegateTarget(conversion, type, Restrict(Value.GetType()));
                         }</diff>
      <filename>Merlin/Main/Languages/IronPython/IronPython/Runtime/Binding/MetaUserObject.cs</filename>
    </modified>
    <modified>
      <diff>@@ -205,12 +205,12 @@ namespace IronPython.Runtime.Binding {
         }
         
         private IEnumerator GetListEnumerator(CallSite site, List value) {
-            return new listiterator(value);
+            return new ListIterator(value);
         }
 
         private IEnumerator GetListEnumerator(CallSite site, object value) {
             if (value != null &amp;&amp; value.GetType() == typeof(List)) {
-                return new listiterator((List)value);
+                return new ListIterator((List)value);
             }
 
             return ((CallSite&lt;Func&lt;CallSite, object, IEnumerator&gt;&gt;)site).Update(site, value);</diff>
      <filename>Merlin/Main/Languages/IronPython/IronPython/Runtime/Binding/PythonOperationBinder.cs</filename>
    </modified>
    <modified>
      <diff>@@ -76,18 +76,24 @@ namespace IronPython.Runtime.Binding {
         }
 
         public override bool CanConvertFrom(Type fromType, ParameterWrapper toParameter, NarrowingLevel level) {
-            if ((fromType == typeof(List) || fromType.IsSubclassOf(typeof(List))) &amp;&amp; 
-                toParameter.Type.IsGenericType &amp;&amp; 
-                toParameter.Type.GetGenericTypeDefinition() == typeof(IList&lt;&gt;)) {
-                if (toParameter.ParameterInfo.IsDefined(typeof(BytesConversionAttribute), false) ||
-                    toParameter.ParameterInfo.IsDefined(typeof(BytesConversionNoStringAttribute), false)) {
+            if ((fromType == typeof(List) || fromType.IsSubclassOf(typeof(List)))) {
+                if (toParameter.Type.IsGenericType &amp;&amp;
+                    toParameter.Type.GetGenericTypeDefinition() == typeof(IList&lt;&gt;) &amp;&amp;
+                    (toParameter.ParameterInfo.IsDefined(typeof(BytesConversionAttribute), false) ||
+                     toParameter.ParameterInfo.IsDefined(typeof(BytesConversionNoStringAttribute), false))) {
                     return false;
                 }
-            } else if (fromType == typeof(string) &amp;&amp; 
-                toParameter.Type == typeof(IList&lt;byte&gt;) &amp;&amp; 
-                !Binder.Context.PythonOptions.Python30) {                
-                // string -&gt; byte array, we allow this in Python 2.6
-                if (toParameter.ParameterInfo.IsDefined(typeof(BytesConversionAttribute), false)) {
+            } else if (fromType == typeof(string)) {
+                if (toParameter.Type == typeof(IList&lt;byte&gt;) &amp;&amp;
+                    !Binder.Context.PythonOptions.Python30 &amp;&amp;
+                    toParameter.ParameterInfo.IsDefined(typeof(BytesConversionAttribute), false)) {
+                    // string -&gt; byte array, we allow this in Python 2.6
+                    return true;
+                }
+            } else if (fromType == typeof(Bytes)) {
+                if (toParameter.Type == typeof(string) &amp;&amp;
+                    !Binder.Context.PythonOptions.Python30 &amp;&amp;
+                    toParameter.ParameterInfo.IsDefined(typeof(BytesConversionAttribute), false)) {
                     return true;
                 }
             }</diff>
      <filename>Merlin/Main/Languages/IronPython/IronPython/Runtime/Binding/PythonOverloadResolver.cs</filename>
    </modified>
    <modified>
      <diff>@@ -464,18 +464,28 @@ namespace IronPython.Runtime.Binding {
                     ),
                     self.Restrictions
                 );
-            } else if (self.GetLimitType() == typeof(PythonDictionary)) {
+            } else if (self.GetLimitType() == typeof(Bytes)) {
                 self = self.Restrict(self.GetLimitType());
 
-                return new DynamicMetaObject(
-                    Expression.Call(
-                        typeof(PythonOps).GetMethod(&quot;MakeDictionaryKeyEnumerator&quot;),
-                        self.Expression
-                    ),
-                    self.Restrictions
-                );
+                if (operation.Context.PythonOptions.Python30) {
+                    return new DynamicMetaObject(
+                        Expression.Call(
+                            typeof(PythonOps).GetMethod(&quot;BytesIntEnumerator&quot;),
+                            self.Expression
+                        ),
+                        self.Restrictions
+                    );
+                } else {
+                    return new DynamicMetaObject(
+                        Expression.Call(
+                            typeof(PythonOps).GetMethod(&quot;BytesEnumerator&quot;),
+                            self.Expression
+                        ),
+                        self.Restrictions
+                    );
+                }
             } else if (self.Value is IEnumerable ||
-                       typeof(IEnumerable).IsAssignableFrom(self.GetLimitType())) {
+                    typeof(IEnumerable).IsAssignableFrom(self.GetLimitType())) {
                 self = self.Restrict(self.GetLimitType());
 
                 return new DynamicMetaObject(
@@ -489,8 +499,8 @@ namespace IronPython.Runtime.Binding {
                     self.Restrictions
                 );
 
-            } else if (self.Value is IEnumerator ||                                 // check for COM object (and fast check when we have values)
-                       typeof(IEnumerator).IsAssignableFrom(self.GetLimitType())) { // check if we don't have a value
+            } else if (self.Value is IEnumerator ||                              // check for COM object (and fast check when we have values)
+                    typeof(IEnumerator).IsAssignableFrom(self.GetLimitType())) { // check if we don't have a value
                 DynamicMetaObject ieres = new DynamicMetaObject(
                     Ast.Convert(
                         self.Expression,
@@ -520,7 +530,7 @@ namespace IronPython.Runtime.Binding {
 
             ParameterExpression tmp = Ast.Parameter(typeof(IEnumerator), &quot;enum&quot;);
             IPythonConvertible pyConv = self as IPythonConvertible;
-            PythonConversionBinder convBinder = new PythonConversionBinder(PythonContext.GetPythonContext(operation), typeof(IEnumerator), ConversionResultKind.ExplicitTry);
+            PythonConversionBinder convBinder = PythonContext.GetPythonContext(operation).Convert(typeof(IEnumerator), ConversionResultKind.ExplicitTry);
 
             DynamicMetaObject res;
             if (pyConv != null) {</diff>
      <filename>Merlin/Main/Languages/IronPython/IronPython/Runtime/Binding/PythonProtocol.Operations.cs</filename>
    </modified>
    <modified>
      <diff>@@ -106,108 +106,6 @@ namespace IronPython.Runtime.Binding {
             return Ast.NotEqual(callAsInt, AstUtils.Constant(0));
         }
 
-        internal static DynamicMetaObject ConvertToIEnumerable(DynamicMetaObjectBinder/*!*/ conversion, DynamicMetaObject/*!*/ metaUserObject) {
-            PythonType pt = MetaPythonObject.GetPythonType(metaUserObject);
-            PythonContext pyContext = PythonContext.GetPythonContext(conversion);
-            CodeContext context = pyContext.SharedContext;
-            PythonTypeSlot pts;
-
-            if (pt.TryResolveSlot(context, Symbols.Iterator, out pts)) {
-                return MakeIterRule(metaUserObject, &quot;CreatePythonEnumerable&quot;);
-            } else if (pt.TryResolveSlot(context, Symbols.GetItem, out pts)) {
-                return MakeGetItemIterable(metaUserObject, pyContext, pts, &quot;CreateItemEnumerable&quot;);
-            }
-
-            return null;
-        }
-
-        internal static DynamicMetaObject ConvertToIEnumerator(DynamicMetaObjectBinder/*!*/ conversion, DynamicMetaObject/*!*/ metaUserObject) {
-            PythonType pt = MetaPythonObject.GetPythonType(metaUserObject);
-            PythonContext state = PythonContext.GetPythonContext(conversion);
-            CodeContext context = state.SharedContext;
-            PythonTypeSlot pts;
-
-            
-            if (pt.TryResolveSlot(context, Symbols.Iterator, out pts)) {
-                ParameterExpression tmp = Ast.Parameter(typeof(object), &quot;iterVal&quot;);
-
-                return new DynamicMetaObject(
-                    Expression.Block(
-                        new [] { tmp },
-                        Expression.Call(
-                            typeof(PythonOps).GetMethod(&quot;MakePythonEnumerator&quot;),
-                            Ast.Block(
-                                MetaPythonObject.MakeTryGetTypeMember(
-                                    state,
-                                    pts,
-                                    metaUserObject.Expression,
-                                    tmp
-                                ),
-                                Ast.Dynamic(
-                                    new PythonInvokeBinder(
-                                        state,
-                                        new CallSignature(0)
-                                    ),
-                                    typeof(object),
-                                    AstUtils.Constant(context),
-                                    tmp
-                                )
-                            )
-                        )
-                    ),
-                    metaUserObject.Restrictions
-                );
-            } else if (pt.TryResolveSlot(context, Symbols.GetItem, out pts)) {
-                return MakeGetItemIterable(metaUserObject, state, pts, &quot;CreateItemEnumerator&quot;);
-            }
-
-            return null;
-        }
-
-        private static DynamicMetaObject MakeGetItemIterable(DynamicMetaObject metaUserObject, PythonContext state, PythonTypeSlot pts, string method) {
-            ParameterExpression tmp = Ast.Parameter(typeof(object), &quot;getitemVal&quot;);
-            return new DynamicMetaObject(
-                Expression.Block(
-                    new[] { tmp },
-                    Expression.Call(
-                        typeof(PythonOps).GetMethod(method),
-                        Ast.Block(
-                            MetaPythonObject.MakeTryGetTypeMember(
-                                state,
-                                pts,
-                                tmp,
-                                metaUserObject.Expression,
-                                Ast.Call(
-                                    typeof(DynamicHelpers).GetMethod(&quot;GetPythonType&quot;),
-                                    AstUtils.Convert(
-                                        metaUserObject.Expression,
-                                        typeof(object)
-                                    )
-                                )
-                            ),
-                            tmp
-                        ),
-                        AstUtils.Constant(
-                            CallSite&lt;Func&lt;CallSite, CodeContext, object, int, object&gt;&gt;.Create(
-                                new PythonInvokeBinder(state, new CallSignature(1))
-                            )
-                        )
-                    )
-                ),
-                metaUserObject.Restrictions
-            );
-        }
-
-        private static DynamicMetaObject/*!*/ MakeIterRule(DynamicMetaObject/*!*/ self, string methodName) {            
-            return new DynamicMetaObject(
-                Ast.Call(
-                    typeof(PythonOps).GetMethod(methodName),
-                    AstUtils.Convert(self.Expression, typeof(object))
-                ),
-                self.Restrictions
-            );
-        }
-
         #endregion
 
         #region Calls
@@ -270,6 +168,16 @@ namespace IronPython.Runtime.Binding {
                     callArgs
                 );
 
+                if (PythonFunction._MaximumDepth != Int32.MaxValue) {
+                    body = Ast.TryFinally(
+                        Ast.Block(
+                            Ast.Call(typeof(PythonOps).GetMethod(&quot;FunctionPushFrame&quot;)),
+                            body
+                        ),
+                        Ast.Call(typeof(PythonOps).GetMethod(&quot;FunctionPopFrame&quot;))
+                    );
+                }
+
                 return BindingHelpers.AddDynamicTestAndDefer(
                     call,
                     new DynamicMetaObject(body, self.Restrictions.Merge(BindingRestrictions.Combine(args))),</diff>
      <filename>Merlin/Main/Languages/IronPython/IronPython/Runtime/Binding/PythonProtocol.cs</filename>
    </modified>
    <modified>
      <diff>@@ -132,7 +132,7 @@ namespace IronPython.Runtime {
                 return value;
             }
 
-            throw PythonOps.TypeError(&quot;bad operand type for abs(): '{0}'&quot;, DynamicHelpers.GetPythonType(o).Name);
+            throw PythonOps.TypeError(&quot;bad operand type for abs(): '{0}'&quot;, PythonTypeOps.GetName(o));
         }
 
         public static bool all(object x) {
@@ -987,8 +987,8 @@ namespace IronPython.Runtime {
             return false;
         }
 
-        public static IEnumerator iter(object o) {
-            return PythonOps.GetEnumerator(o);
+        public static object iter(CodeContext/*!*/ context, object o) {
+            return PythonOps.GetEnumeratorObject(context, o);
         }
 
         public static object iter(CodeContext/*!*/ context, object func, object sentinel) {
@@ -1048,11 +1048,9 @@ namespace IronPython.Runtime {
             );
         }
 
-        public static List map(CodeContext/*!*/ context, object func, IEnumerable enumerator) {
-            if (enumerator == null) {
-                throw PythonOps.TypeError(&quot;NoneType is not iterable&quot;);
-            }
-
+        public static List map(CodeContext/*!*/ context, object func, [NotNull]IEnumerable enumerator) {
+            IEnumerator en = PythonOps.GetEnumerator(enumerator);
+            
             List ret = new List();            
             CallSite&lt;Func&lt;CallSite, CodeContext, object, object, object&gt;&gt; mapSite = null;
 
@@ -1060,18 +1058,23 @@ namespace IronPython.Runtime {
                 mapSite = MakeMapSite&lt;object, object&gt;(context);
             }
 
-            foreach (object o in enumerator) {
+            while (en.MoveNext()) {
                 if (func == null) {
-                    ret.AddNoLock(o);
+                    ret.AddNoLock(en.Current);
                 } else {
-                    ret.AddNoLock(mapSite.Target(mapSite, context, func, o));
+                    ret.AddNoLock(mapSite.Target(mapSite, context, func, en.Current));
                 }
             }
         
             return ret;
         }
 
-        public static List map(CodeContext/*!*/ context, SiteLocalStorage&lt;CallSite&lt;Func&lt;CallSite, CodeContext, object, object, object&gt;&gt;&gt; storage, object func, [NotNull]string enumerator) {
+        public static List map(
+            CodeContext/*!*/ context,
+            SiteLocalStorage&lt;CallSite&lt;Func&lt;CallSite, CodeContext, object, object, object&gt;&gt;&gt; storage,
+            object func,
+            [NotNull]string enumerator
+        ) {
             CallSite&lt;Func&lt;CallSite, CodeContext, object, object, object&gt;&gt; mapSite;
             if (storage.Data == null &amp;&amp; func != null) {
                 storage.Data = MakeMapSite&lt;object, object&gt;(context);
@@ -1090,68 +1093,96 @@ namespace IronPython.Runtime {
             return ret;
         }
 
-        public static List map(CodeContext/*!*/ context, SiteLocalStorage&lt;CallSite&lt;Func&lt;CallSite, CodeContext, PythonType, object, object&gt;&gt;&gt; storage, [NotNull]PythonType/*!*/ func, [NotNull]IEnumerable enumerator) {
-            CallSite&lt;Func&lt;CallSite, CodeContext, PythonType, object, object&gt;&gt; mapSite;
-            if (storage.Data == null) {
-                storage.Data = MakeMapSite&lt;PythonType, object&gt;(context);
-            }
-            mapSite = storage.Data;
+        public static List map(
+            CodeContext/*!*/ context,
+            SiteLocalStorage&lt;CallSite&lt;Func&lt;CallSite, CodeContext, PythonType, object, object&gt;&gt;&gt; storage,
+            [NotNull]PythonType/*!*/ func,
+            [NotNull]string enumerator
+        ) {
+            CallSite&lt;Func&lt;CallSite, CodeContext, PythonType, string, object&gt;&gt; mapSite = MakeMapSite&lt;PythonType, string&gt;(context);
 
-            List ret = new List();
-            foreach (object o in enumerator) {
-                ret.AddNoLock(mapSite.Target(mapSite, context, func, o));
+            List ret = new List(enumerator.Length);
+            foreach (char o in enumerator) {
+                ret.AddNoLock(mapSite.Target(mapSite, context, func, ScriptingRuntimeHelpers.CharToString(o)));
             }
             return ret;
         }
 
-        public static List map(CodeContext/*!*/ context, SiteLocalStorage&lt;CallSite&lt;Func&lt;CallSite, CodeContext, BuiltinFunction, object, object&gt;&gt;&gt; storage, [NotNull]BuiltinFunction/*!*/ func, [NotNull]IEnumerable enumerator) {
-            CallSite&lt;Func&lt;CallSite, CodeContext, BuiltinFunction, object, object&gt;&gt; mapSite;
+        public static List map(
+            CodeContext/*!*/ context,
+            SiteLocalStorage&lt;CallSite&lt;Func&lt;CallSite, CodeContext, PythonType, object, object&gt;&gt;&gt; storage,
+            [NotNull]PythonType/*!*/ func,
+            [NotNull]IEnumerable enumerator
+        ) {
+            CallSite&lt;Func&lt;CallSite, CodeContext, PythonType, object, object&gt;&gt; mapSite;
             if (storage.Data == null) {
-                storage.Data = MakeMapSite&lt;BuiltinFunction, object&gt;(context);
+                storage.Data = MakeMapSite&lt;PythonType, object&gt;(context);
             }
             mapSite = storage.Data;
 
+            IEnumerator en = PythonOps.GetEnumerator(enumerator);
             List ret = new List();
-            foreach (object o in enumerator) {
-                ret.AddNoLock(mapSite.Target(mapSite, context, func, o));
+            while (en.MoveNext()) {
+                ret.AddNoLock(mapSite.Target(mapSite, context, func, en.Current));
             }
             return ret;
         }
 
-        public static List map(CodeContext/*!*/ context, SiteLocalStorage&lt;CallSite&lt;Func&lt;CallSite, CodeContext, PythonFunction, object, object&gt;&gt;&gt; storage, [NotNull]PythonFunction/*!*/ func, [NotNull]IList enumerator) {
-            CallSite&lt;Func&lt;CallSite, CodeContext, PythonFunction, object, object&gt;&gt; mapSite;
+        public static List map(
+            CodeContext/*!*/ context,
+            SiteLocalStorage&lt;CallSite&lt;Func&lt;CallSite, CodeContext, BuiltinFunction, object, object&gt;&gt;&gt; storage,
+            [NotNull]BuiltinFunction/*!*/ func,
+            [NotNull]string enumerator
+        ) {
+            CallSite&lt;Func&lt;CallSite, CodeContext, BuiltinFunction, object, object&gt;&gt; mapSite;
             if (storage.Data == null) {
-                storage.Data = MakeMapSite&lt;PythonFunction, object&gt;(context);
+                storage.Data = MakeMapSite&lt;BuiltinFunction, object&gt;(context);
             }
             mapSite = storage.Data;
 
-            List ret = new List(enumerator.Count);
-            foreach (object o in enumerator) {
-                ret.AddNoLock(mapSite.Target(mapSite, context, func, o));
+            List ret = new List(enumerator.Length);
+            foreach (char o in enumerator) {
+                ret.AddNoLock(mapSite.Target(mapSite, context, func, ScriptingRuntimeHelpers.CharToString(o)));
             }
             return ret;
         }
 
-        public static List map(CodeContext/*!*/ context, SiteLocalStorage&lt;CallSite&lt;Func&lt;CallSite, CodeContext, BuiltinFunction, object, object&gt;&gt;&gt; storage, [NotNull]BuiltinFunction/*!*/ func, [NotNull]string enumerator) {
+        public static List map(
+            CodeContext/*!*/ context,
+            SiteLocalStorage&lt;CallSite&lt;Func&lt;CallSite, CodeContext, BuiltinFunction, object, object&gt;&gt;&gt; storage,
+            [NotNull]BuiltinFunction/*!*/ func,
+            [NotNull]IEnumerable enumerator
+        ) {
             CallSite&lt;Func&lt;CallSite, CodeContext, BuiltinFunction, object, object&gt;&gt; mapSite;
             if (storage.Data == null) {
                 storage.Data = MakeMapSite&lt;BuiltinFunction, object&gt;(context);
             }
             mapSite = storage.Data;
 
-            List ret = new List(enumerator.Length);
-            foreach (char o in enumerator) {
-                ret.AddNoLock(mapSite.Target(mapSite, context, func, ScriptingRuntimeHelpers.CharToString(o)));
+            IEnumerator en = PythonOps.GetEnumerator(enumerator);
+            List ret = new List();
+            while (en.MoveNext()) {
+                ret.AddNoLock(mapSite.Target(mapSite, context, func, en.Current));
             }
             return ret;
         }
 
-        public static List map(CodeContext/*!*/ context, SiteLocalStorage&lt;CallSite&lt;Func&lt;CallSite, CodeContext, PythonType, object, object&gt;&gt;&gt; storage, [NotNull]PythonType/*!*/ func, [NotNull]string enumerator) {
-            CallSite&lt;Func&lt;CallSite, CodeContext, PythonType, string, object&gt;&gt; mapSite = MakeMapSite&lt;PythonType, string&gt;(context);
+        public static List map(
+            CodeContext/*!*/ context,
+            SiteLocalStorage&lt;CallSite&lt;Func&lt;CallSite, CodeContext, PythonFunction, object, object&gt;&gt;&gt; storage,
+            [NotNull]PythonFunction/*!*/ func,
+            [NotNull]IList enumerator
+        ) {
+            CallSite&lt;Func&lt;CallSite, CodeContext, PythonFunction, object, object&gt;&gt; mapSite;
+            if (storage.Data == null) {
+                storage.Data = MakeMapSite&lt;PythonFunction, object&gt;(context);
+            }
+            mapSite = storage.Data;
 
-            List ret = new List(enumerator.Length);
-            foreach (char o in enumerator) {
-                ret.AddNoLock(mapSite.Target(mapSite, context, func, ScriptingRuntimeHelpers.CharToString(o)));
+            IEnumerator en = PythonOps.GetEnumerator(enumerator);
+            List ret = new List(enumerator.Count);
+            while (en.MoveNext()) {
+                ret.AddNoLock(mapSite.Target(mapSite, context, func, en.Current));
             }
             return ret;
         }
@@ -1443,7 +1474,7 @@ namespace IronPython.Runtime {
                 return bytes[0];
             }
                 
-            throw PythonOps.TypeError(&quot;expected a character, but {0} found&quot;, DynamicHelpers.GetPythonType(value));
+            throw PythonOps.TypeError(&quot;expected a character, but {0} found&quot;, PythonTypeOps.GetName(value));
         }
 
         public static object pow(CodeContext/*!*/ context, object x, object y) {
@@ -1465,12 +1496,12 @@ namespace IronPython.Runtime {
         public static void print(CodeContext/*!*/ context, [ParamDictionary]IAttributesCollection kwargs, params object[] args) {
             object sep = AttrCollectionPop(kwargs, &quot;sep&quot;, &quot; &quot;);
             if (sep != null &amp;&amp; !(sep is string)) {
-                throw PythonOps.TypeError(&quot;sep must be None or str, not {0}&quot;, DynamicHelpers.GetPythonType(sep));
+                throw PythonOps.TypeError(&quot;sep must be None or str, not {0}&quot;, PythonTypeOps.GetName(sep));
             }
 
             object end = AttrCollectionPop(kwargs, &quot;end&quot;, &quot;\n&quot;);
             if (sep != null &amp;&amp; !(sep is string)) {
-                throw PythonOps.TypeError(&quot;end must be None or str, not {0}&quot;, DynamicHelpers.GetPythonType(end));
+                throw PythonOps.TypeError(&quot;end must be None or str, not {0}&quot;, PythonTypeOps.GetName(end));
             }
 
             object file = AttrCollectionPop(kwargs, &quot;file&quot;, null);</diff>
      <filename>Merlin/Main/Languages/IronPython/IronPython/Runtime/Builtin.cs</filename>
    </modified>
    <modified>
      <diff>@@ -26,6 +26,21 @@ using IronPython.Runtime.Operations;
 using IronPython.Runtime.Types;
 
 namespace IronPython.Runtime {
+    /// &lt;summary&gt;
+    /// bytearray(string, encoding[, errors]) -&gt; bytearray
+    /// bytearray(iterable) -&gt; bytearray
+    /// 
+    /// Construct a mutable bytearray object from:
+    ///  - an iterable yielding values in range(256), including:
+    ///     + a list of integer values
+    ///     + a bytes, bytearray, buffer, or array object
+    ///  - a text string encoded using the specified encoding
+    ///  
+    /// bytearray([int]) -&gt; bytearray
+    /// 
+    /// Construct a zero-ititialized bytearray of the specified length.
+    /// (default=0)
+    /// &lt;/summary&gt;
     [PythonType(&quot;bytearray&quot;)]
     public class ByteArray : IList&lt;byte&gt;, ICodeFormattable, IValueEquality {
         private List&lt;byte&gt;/*!*/ _bytes;
@@ -42,10 +57,6 @@ namespace IronPython.Runtime {
             _bytes = new List&lt;byte&gt;();
         }
 
-        public void __init__(List/*!*/ source) {
-            _bytes = ByteOps.GetBytes(source);
-        }
-
         public void __init__(int source) {
             _bytes = new List&lt;byte&gt;(source);
             for (int i = 0; i &lt; source; i++) {
@@ -53,16 +64,12 @@ namespace IronPython.Runtime {
             }
         }
 
-        public void __init__(double source) {
-            throw PythonOps.TypeError(&quot;'float' object is not iterable&quot;);
-        }
-
-        public void __init__(IList&lt;byte&gt;/*!*/ source) {            
+        public void __init__([NotNull]IList&lt;byte&gt;/*!*/ source) {            
             _bytes = new List&lt;byte&gt;(source);
         }
 
-        public void __init__(IEnumerable/*!*/ source) {
-            _bytes = ByteOps.GetBytes(new List(source));
+        public void __init__(object source) {
+            __init__(GetBytes(source));
         }
 
         public void __init__(CodeContext/*!*/ context, string source, string encoding, [DefaultParameterValue(&quot;strict&quot;)]string errors) {
@@ -78,18 +85,20 @@ namespace IronPython.Runtime {
         }
 
         public void append(object item) {
-            append(Converter.ConvertToIndex(item));
+            lock(this) {
+                _bytes.Add(GetByte(item));
+            }
         }
 
-        public void extend(IList&lt;byte&gt;/*!*/ seq) {
+        public void extend([NotNull]IEnumerable&lt;byte&gt;/*!*/ seq) {
             using (new OrderedLocker(this, seq)) {
                 // use the original count for if we're extending this w/ this
                 _bytes.AddRange(seq);
             }
         }
 
-        public void extend(List/*!*/ seq) {
-            extend(ByteOps.GetBytes(seq));
+        public void extend(object seq) {
+            extend(GetBytes(seq));
         }
 
         public void insert(int index, int value) {
@@ -146,7 +155,7 @@ namespace IronPython.Runtime {
                 if (value is ByteArray) {
                     throw PythonOps.TypeError(&quot;an integer or string of size 1 is required&quot;);
                 }
-                _bytes.RemoveAt(_bytes.IndexOfByte(ByteOps.GetByteListOk(value), 0, _bytes.Count));
+                _bytes.RemoveAt(_bytes.IndexOfByte(GetByte(value), 0, _bytes.Count));
             }
         }
         
@@ -508,7 +517,7 @@ namespace IronPython.Runtime {
         }
 
         public PythonTuple/*!*/ partition([NotNull]List/*!*/ sep) {
-            return partition(ByteOps.GetBytes(sep));
+            return partition(GetBytes(sep));
         }
 
         public ByteArray/*!*/ replace([BytesConversion]IList&lt;byte&gt;/*!*/ old, [BytesConversion]IList&lt;byte&gt; new_) {
@@ -616,7 +625,7 @@ namespace IronPython.Runtime {
         }
 
         public PythonTuple/*!*/ rpartition([NotNull]List/*!*/ sep) {
-            return rpartition(ByteOps.GetBytes(sep));
+            return rpartition(GetBytes(sep));
         }
 
         public List/*!*/ rsplit() {
@@ -825,6 +834,23 @@ namespace IronPython.Runtime {
             return IndexOf(value.ToByteChecked()) != -1;
         }
 
+        public bool __contains__(CodeContext/*!*/ context, object value) {
+            if (value is Extensible&lt;int&gt;) {
+                return IndexOf(((Extensible&lt;int&gt;)value).Value.ToByteChecked()) != -1;
+            }
+
+            BigInteger biVal = value as BigInteger;
+            if (biVal == null &amp;&amp; value is Extensible&lt;BigInteger&gt;) {
+                biVal = ((Extensible&lt;BigInteger&gt;)value).Value;
+            }
+            if (biVal != null) {
+                return IndexOf(biVal.ToByteChecked()) != -1;
+            }
+
+            throw PythonOps.TypeError(&quot;Type {0} doesn't support the buffer API&quot;,
+                PythonContext.GetContext(context).PythonOptions.Python30 ? PythonTypeOps.GetOldName(value) : PythonTypeOps.GetName(value));
+        }
+
         public PythonTuple __reduce__(CodeContext/*!*/ context) {
             return PythonTuple.MakeTuple(
                 DynamicHelpers.GetPythonType(this), 
@@ -967,7 +993,7 @@ namespace IronPython.Runtime {
             }
             set {
                 lock (this) {
-                    _bytes[PythonOps.FixIndex(index, _bytes.Count)] = ByteOps.GetByteListOk(value);
+                    _bytes[PythonOps.FixIndex(index, _bytes.Count)] = GetByte(value);
                 }
             }
         }
@@ -1037,7 +1063,7 @@ namespace IronPython.Runtime {
                         IEnumerator ie = PythonOps.GetEnumerator(value);
                         list = new List&lt;byte&gt;();
                         while (ie.MoveNext()) {
-                            list.Add(ByteOps.GetByteListOk(ie.Current));
+                            list.Add(GetByte(ie.Current));
                         }
                     }
                 }
@@ -1221,16 +1247,27 @@ namespace IronPython.Runtime {
             }
         }
 
+        private static byte GetByte(object/*!*/ value) {
+            if (value is double || value is Extensible&lt;double&gt; || value is float) {
+                throw PythonOps.TypeError(&quot;an integer or string of size 1 is required&quot;);
+            }
+            return ByteOps.GetByteListOk(value);
+        }
+
         private static IList&lt;byte&gt;/*!*/ GetBytes(object/*!*/ value) {
             ListGenericWrapper&lt;byte&gt; genWrapper = value as ListGenericWrapper&lt;byte&gt;;
             if (genWrapper == null &amp;&amp; value is IList&lt;byte&gt;) {
                 return (IList&lt;byte&gt;)value;
             }
 
+            if (value is string || value is Extensible&lt;string&gt;) {
+                throw PythonOps.TypeError(&quot;unicode argument without an encoding&quot;);
+            }
+
             List&lt;byte&gt; ret = new List&lt;byte&gt;();
             IEnumerator ie = PythonOps.GetEnumerator(value);
             while (ie.MoveNext()) {
-                ret.Add(ByteOps.GetByteListOk(ie.Current));
+                ret.Add(GetByte(ie.Current));
             }
             return ret;
         }
@@ -1320,6 +1357,10 @@ namespace IronPython.Runtime {
 
         #endregion
 
+        public IEnumerator __iter__() {
+            return PythonOps.BytesIntEnumerator(this);
+        }
+
         #region IEnumerable&lt;byte&gt; Members
 
         [PythonHidden]</diff>
      <filename>Merlin/Main/Languages/IronPython/IronPython/Runtime/ByteArray.cs</filename>
    </modified>
    <modified>
      <diff>@@ -19,6 +19,8 @@ using System.Collections.Generic;
 using System.Linq.Expressions;
 using System.Reflection.Emit;
 using System.Runtime.InteropServices;
+using System.Text;
+using System.Threading;
 
 using Microsoft.Scripting.Math;
 using Microsoft.Scripting.Runtime;
@@ -37,12 +39,12 @@ namespace IronPython.Runtime {
             _bytes = new byte[0];
         }
 
-        public Bytes(IList&lt;byte&gt;/*!*/ bytes) {
+        public Bytes([BytesConversion, NotNull]IList&lt;byte&gt;/*!*/ bytes) {
             _bytes = ArrayUtils.ToArray(bytes);
         }
 
-        public Bytes(List bytes) {
-            _bytes = ByteOps.GetBytes(bytes).ToArray();
+        public Bytes([NotNull]List bytes) {
+            _bytes = ByteOps.GetBytes(bytes, ByteOps.GetByteListOk).ToArray();
         }
 
         public Bytes(int size) {
@@ -617,10 +619,35 @@ namespace IronPython.Runtime {
             return this.IndexOf(bytes, 0) != -1;
         }
 
-        public bool __contains__(int value) {
+        public bool __contains__(CodeContext/*!*/ context, int value) {
+            if (!PythonContext.GetContext(context).PythonOptions.Python30) {
+                throw PythonOps.TypeError(&quot;'in &lt;bytes&gt;' requires string or bytes as left operand, not int&quot;);
+            }
+
             return IndexOf(value.ToByteChecked()) != -1;
         }
 
+        public bool __contains__(CodeContext/*!*/ context, object value) {
+            if (!PythonContext.GetContext(context).PythonOptions.Python30) {
+                throw PythonOps.TypeError(&quot;'in &lt;bytes&gt;' requires string or bytes as left operand, not {0}&quot;, PythonTypeOps.GetName(value));
+            }
+
+            if (value is Extensible&lt;int&gt;) {
+                return IndexOf(((Extensible&lt;int&gt;)value).Value.ToByteChecked()) != -1;
+            }
+
+            BigInteger biVal = value as BigInteger;
+            if (biVal == null &amp;&amp; value is Extensible&lt;BigInteger&gt;) {
+                biVal = ((Extensible&lt;BigInteger&gt;)value).Value;
+            }
+            if (biVal != null) {
+                return IndexOf(biVal.ToByteChecked()) != -1;
+            }
+
+            // 3.0 error message
+            throw PythonOps.TypeError(&quot;Type {0} doesn't support the buffer API&quot;, PythonTypeOps.GetOldName(value));
+        }
+
         public PythonTuple __reduce__(CodeContext/*!*/ context) {
             return PythonTuple.MakeTuple(
                 DynamicHelpers.GetPythonType(this),
@@ -635,6 +662,10 @@ namespace IronPython.Runtime {
         public virtual string/*!*/ __repr__(Microsoft.Scripting.Runtime.CodeContext context) {
             return _bytes.BytesRepr();
         }
+        
+        public override string/*!*/ ToString() {
+            return PythonOps.MakeString(this);
+        }
 
         public static Bytes/*!*/ operator +(Bytes/*!*/ self, Bytes/*!*/ other) {
             if (self == null) {
@@ -661,6 +692,14 @@ namespace IronPython.Runtime {
             return new ByteArray(bytes);
         }
 
+        public static string/*!*/ operator +(Bytes/*!*/ self, string/*!*/ other) {
+            return self.ToString() + other;
+        }
+
+        public static string/*!*/ operator +(string/*!*/ other, Bytes/*!*/ self) {
+            return other + self.ToString();
+        }
+
         public static Bytes/*!*/ operator *(Bytes/*!*/ x, int y) {
             if (y == 1) {
                 return x;
@@ -845,20 +884,27 @@ namespace IronPython.Runtime {
 
         public override bool Equals(object obj) {
             IList&lt;byte&gt; bytes = obj as IList&lt;byte&gt;;
-            if (bytes == null) {
-                return false;
+            if (bytes != null) {
+                return _bytes.Compare(bytes) == 0;
             }
 
-            return _bytes.Compare(bytes) == 0;
-        }
+            string s = obj as string;
+            if (s == null) {
+                Extensible&lt;string&gt; es = obj as Extensible&lt;string&gt;;
+                if (es != null) {
+                    s = es.Value;
+                }
+            }
 
-        public override int GetHashCode() {
-            int res = 6551;
-            for (int i = 0; i &lt; _bytes.Length; i++) {
-                res = (res &lt;&lt; 5) ^ _bytes[i].GetHashCode();
+            if (s != null) {
+                return ToString() == s;
             }
 
-            return res;
+            return false;
+        }
+
+        public override int GetHashCode() {
+            return ToString().GetHashCode();
         }
 
         #endregion</diff>
      <filename>Merlin/Main/Languages/IronPython/IronPython/Runtime/Bytes.cs</filename>
    </modified>
    <modified>
      <diff>@@ -19,10 +19,13 @@ using System.Text;
 
 namespace IronPython {
     /// &lt;summary&gt;
-    /// Marks that the argument is typed to accept a bytes or bytearray object.  This
-    /// attribute disallows passing a Python list object and auto-applying our generic
-    /// conversion.  It also enables conversion of a string to a IList of byte in
-    /// IronPython 2.6.
+    /// For IList&lt;byte/&gt; arguments: Marks that the argument is typed to accept a bytes or
+    /// bytearray object.  This attribute disallows passing a Python list object and
+    /// auto-applying our generic conversion.  It also enables conversion of a string to
+    /// a IList of byte in IronPython 2.6.
+    /// 
+    /// For string arguments: Marks that the argument is typed to accept a bytes object
+    /// as well. (2.6 only)
     /// &lt;/summary&gt;
     [AttributeUsage(AttributeTargets.Parameter)]
     public sealed class BytesConversionAttribute : Attribute {</diff>
      <filename>Merlin/Main/Languages/IronPython/IronPython/Runtime/BytesConversionAttribute.cs</filename>
    </modified>
    <modified>
      <diff>@@ -153,39 +153,50 @@ namespace IronPython.Runtime {
     }
 
     /* 
-     * Enumeraters exposed to .NET code
-     * 
+     * Enumerators exposed to .NET code
      */
+
     [PythonType(&quot;enumerator&quot;)]
     public class PythonEnumerator : IEnumerator {
         private readonly object _baseObject;
         private object _nextMethod;
         private object _current;
 
-        public static bool TryCreate(object baseEnumerator, out IEnumerator enumerator) {
-            object iter;
+        public static bool TryCastIEnumer(object baseObject, out IEnumerator enumerator) {
+            if (baseObject is IEnumerator) {
+                enumerator = (IEnumerator)baseObject;
+                return true;
+            }
 
-            if (baseEnumerator is IEnumerator) {
-                enumerator = (IEnumerator)baseEnumerator;
+            if (baseObject is IEnumerable) {
+                enumerator = ((IEnumerable)baseObject).GetEnumerator();
                 return true;
             }
 
-            if (baseEnumerator is IEnumerable) {
-                enumerator = ((IEnumerable)baseEnumerator).GetEnumerator();
+            enumerator = null;
+            return false;
+        }
+
+        public static bool TryCreate(object baseObject, out IEnumerator enumerator) {
+            if (TryCastIEnumer(baseObject, out enumerator)) {
                 return true;
             }
 
-            if (PythonOps.TryGetBoundAttr(baseEnumerator, Symbols.Iterator, out iter)) {
+            object iter;
+            if (PythonOps.TryGetBoundAttr(baseObject, Symbols.Iterator, out iter)) {
                 object iterator = PythonCalls.Call(iter);
                 // don't re-wrap if we don't need to (common case is PythonGenerator).
-                enumerator = PythonOps.MakePythonEnumerator(iterator);
+                if (TryCastIEnumer(iterator, out enumerator)) {
+                    return true;
+                }
+                enumerator = new PythonEnumerator(iterator);
                 return true;
             } else {
                 enumerator = null;
                 return false;
             }
         }
-       
+
         public static IEnumerator Create(object baseObject) {
             IEnumerator res;
             if (!TryCreate(baseObject, out res)) {
@@ -194,7 +205,7 @@ namespace IronPython.Runtime {
             return res;
         }
 
-        public PythonEnumerator(object iter) {
+        internal PythonEnumerator(object iter) {
             Debug.Assert(!(iter is PythonGenerator));
 
             this._baseObject = iter;
@@ -272,13 +283,13 @@ namespace IronPython.Runtime {
         #region IEnumerable Members
 
         IEnumerator IEnumerable.GetEnumerator() {
-            return new PythonEnumerator(_iterator);
+            return _iterator as IEnumerator ?? new PythonEnumerator(_iterator);
         }
 
         #endregion
     }
 
-    [PythonType(&quot;item-enumerator&quot;)]
+    [PythonType(&quot;iterator&quot;)]
     public class ItemEnumerator : IEnumerator {
         private readonly object _getItemMethod;
         private readonly CallSite&lt;Func&lt;CallSite, CodeContext, object, int, object&gt;&gt; _site;
@@ -326,7 +337,7 @@ namespace IronPython.Runtime {
         #endregion
     }
 
-    [PythonType(&quot;item-enumerable&quot;)]
+    [PythonType(&quot;iterable&quot;)]
     public class ItemEnumerable : IEnumerable {
         private readonly object _getitem;
         private readonly CallSite&lt;Func&lt;CallSite, CodeContext, object, int, object&gt;&gt; _site;</diff>
      <filename>Merlin/Main/Languages/IronPython/IronPython/Runtime/Enumerate.cs</filename>
    </modified>
    <modified>
      <diff>@@ -474,6 +474,20 @@ namespace IronPython.Runtime.Exceptions {
                 base.__init__(args);
             }
 
+            public override string ToString() {
+                if (_errno != null &amp;&amp; _strerror != null) {
+                    if (_filename != null) {
+                        return String.Format(&quot;[Errno {0}] {1}: {2}&quot;, _errno, _strerror, _filename);
+                    } else {
+                        return String.Format(&quot;[Errno {0}] {1}&quot;, _errno, _strerror);
+                    }
+                } else if (args is PythonTuple &amp;&amp; ((PythonTuple)args).Count &gt; 0) {
+                    return PythonOps.ToString(((PythonTuple)args)[0]);
+                }
+
+                return String.Empty;
+            }
+
             private const int EACCES = 13;
             private const int ENOENT = 2;
 </diff>
      <filename>Merlin/Main/Languages/IronPython/IronPython/Runtime/Exceptions/PythonExceptions.cs</filename>
    </modified>
    <modified>
      <diff>@@ -291,11 +291,11 @@ namespace IronPython.Runtime {
             // we can call it w/o requiring an explicit conversion.  If the
             // user overrides this we'll place a conversion in the wrapper
             // helper
-            return new listiterator(this);
+            return new ListIterator(this);
         }
 
         public virtual IEnumerator __reversed__() {
-            return new listreverseiterator(this);
+            return new ListReverseIterator(this);
         }
 
         public virtual bool __contains__(object value) {
@@ -1342,12 +1342,13 @@ namespace IronPython.Runtime {
         #endregion
     }
 
-    public sealed class listiterator : IEnumerator, IEnumerable, IEnumerable&lt;object&gt;, IEnumerator&lt;object&gt; {
+    [PythonType(&quot;listiterator&quot;)]
+    public sealed class ListIterator : IEnumerator, IEnumerable, IEnumerable&lt;object&gt;, IEnumerator&lt;object&gt; {
         private int _index;
         private readonly List _list;
         private bool _iterating;
 
-        public listiterator(List l) {
+        public ListIterator(List l) {
             _list = l;
             Reset();
         }
@@ -1373,15 +1374,11 @@ namespace IronPython.Runtime {
             return _iterating;
         }
 
-        public object __iter__() {
-            return this;
-        }
-
         #endregion
 
         #region IEnumerable Members
 
-        IEnumerator IEnumerable.GetEnumerator() {
+        public IEnumerator GetEnumerator() {
             return this;
         }
 
@@ -1403,12 +1400,13 @@ namespace IronPython.Runtime {
         #endregion
     }
 
-    public sealed class listreverseiterator : IEnumerator, IEnumerable, IEnumerable&lt;object&gt;, IEnumerator&lt;object&gt; {
+    [PythonType(&quot;listreverseiterator&quot;)]
+    public sealed class ListReverseIterator : IEnumerator, IEnumerable, IEnumerable&lt;object&gt;, IEnumerator&lt;object&gt; {
         private int _index;
         private readonly List _list;
         private bool _iterating;
 
-        public listreverseiterator(List l) {
+        public ListReverseIterator(List l) {
             _list = l;
             Reset();
         }
@@ -1434,15 +1432,11 @@ namespace IronPython.Runtime {
             return _iterating;
         }
 
-        public object __iter__() {
-            return this;
-        }
-
         #endregion
 
         #region IEnumerable Members
 
-        IEnumerator IEnumerable.GetEnumerator() {
+        public IEnumerator GetEnumerator() {
             return this;
         }
 </diff>
      <filename>Merlin/Main/Languages/IronPython/IronPython/Runtime/List.cs</filename>
    </modified>
    <modified>
      <diff>@@ -64,7 +64,7 @@ namespace IronPython.Runtime {
                                 buf.Append((char)val);
                                 i += len;
                             } else {
-                                throw PythonOps.UnicodeDecodeError(@&quot;'unicodeescape' codec can't decode bytes in position {0}: truncated \uXXXX escape&quot;, i);
+                                throw PythonOps.UnicodeEncodeError(@&quot;'unicodeescape' codec can't decode bytes in position {0}: truncated \uXXXX escape&quot;, i);
                             }
                         } else {
                             buf.Append('\\');</diff>
      <filename>Merlin/Main/Languages/IronPython/IronPython/Runtime/LiteralParser.cs</filename>
    </modified>
    <modified>
      <diff>@@ -5,7 +5,7 @@ using System.Text;
 namespace IronPython.Runtime {
     [PythonType]
     public sealed class NullImporter {
-        public static string __module__ = &quot;imp&quot;;        // logically lives in imp, but physically lives in IronPython.dll so Importer.cs can access it
+        public const string __module__ = &quot;imp&quot;;        // logically lives in imp, but physically lives in IronPython.dll so Importer.cs can access it
 
         public NullImporter(string path_string) {
         }</diff>
      <filename>Merlin/Main/Languages/IronPython/IronPython/Runtime/NullImporter.cs</filename>
    </modified>
    <modified>
      <diff>@@ -14,11 +14,13 @@
  * ***************************************************************************/
 
 using System;
+using System.Collections;
 using System.Collections.Generic;
 
-using IronPython.Runtime.Types;
-using Microsoft.Scripting.Runtime;
 using Microsoft.Scripting.Math;
+using Microsoft.Scripting.Runtime;
+
+using IronPython.Runtime.Types;
 
 namespace IronPython.Runtime.Operations {
     public static partial class ByteOps {
@@ -30,6 +32,22 @@ namespace IronPython.Runtime.Operations {
             }
         }
 
+        internal static byte ToByteChecked(this BigInteger item) {
+            int val;
+            if (item.AsInt32(out val)) {
+                return ToByteChecked(val);
+            }
+            throw PythonOps.ValueError(&quot;byte must be in range(0, 256)&quot;);
+        }
+
+        internal static byte ToByteChecked(this double item) {
+            try {
+                return checked((byte)item);
+            } catch (OverflowException) {
+                throw PythonOps.ValueError(&quot;byte must be in range(0, 256)&quot;);
+            }
+        }
+
         internal static bool IsSign(this byte ch) {
             return ch == '+' || ch == '-';
         }
@@ -73,14 +91,6 @@ namespace IronPython.Runtime.Operations {
                     b == 11;
         }
 
-        internal static IList&lt;byte&gt; GetBytes(object obj) {
-            IList&lt;byte&gt; ret = obj as IList&lt;byte&gt;;
-            if (ret == null) {
-                throw PythonOps.TypeError(&quot;expected string , got {0} Type&quot;, DynamicHelpers.GetPythonType(obj).Name);
-            }
-            return ret;
-        }
-
         internal static void AppendJoin(object value, int index, List&lt;byte&gt; byteList) {
             IList&lt;byte&gt; strVal;
 
@@ -91,51 +101,95 @@ namespace IronPython.Runtime.Operations {
             }
         }
 
-        internal static List&lt;byte&gt; GetBytes(List bytes) {
+        internal static IList&lt;byte&gt; CoerceBytes(object obj) {
+            IList&lt;byte&gt; ret = obj as IList&lt;byte&gt;;
+            if (ret == null) {
+                throw PythonOps.TypeError(&quot;expected string, got {0} Type&quot;, PythonTypeOps.GetName(obj));
+            }
+            return ret;
+        }
+
+        internal static List&lt;byte&gt; GetBytes(ICollection bytes) {
+            return GetBytes(bytes, GetByte);
+        }
+
+        internal static List&lt;byte&gt; GetBytes(ICollection bytes, Func&lt;object, byte&gt; conversion) {
             List&lt;byte&gt; res = new List&lt;byte&gt;(bytes.Count);
             foreach (object o in bytes) {
-                res.Add(GetByte(o));
+                res.Add(conversion.Invoke(o));
             }
             return res;
         }
-
         
+        internal static byte GetByteStringOk(object o) {
+            string s;
+            Extensible&lt;string&gt; es;
+            if (!Object.ReferenceEquals(s = o as string, null)) {
+                if (s.Length == 1) {
+                    return ((int)s[0]).ToByteChecked();
+                } else {
+                    throw PythonOps.TypeError(&quot;an integer or string of size 1 is required&quot;);
+                }
+            } else if (!Object.ReferenceEquals(es = o as Extensible&lt;string&gt;, null)) {
+                if (es.Value.Length == 1) {
+                    return ((int)es.Value[0]).ToByteChecked();
+                } else {
+                    throw PythonOps.TypeError(&quot;an integer or string of size 1 is required&quot;);
+                }
+            } else {
+                return GetByteListOk(o);
+            }
+        }
+
         internal static byte GetByteListOk(object o) {
             IList&lt;byte&gt; lbval = o as IList&lt;byte&gt;;
             if (lbval != null) {
-                if (lbval.Count != 1) {
-                    throw PythonOps.ValueError(&quot;string must be of size 1&quot;);
+                if (lbval.Count == 1) {
+                    return lbval[0];
                 }
-                return lbval[0];
+                throw PythonOps.ValueError(&quot;an integer or string of size 1 is required&quot;);
             }
 
             return GetByte(o);
         }
 
         internal static byte GetByte(object o) {
-            byte b;
             Extensible&lt;int&gt; ei;
             BigInteger bi;
+            Extensible&lt;BigInteger&gt; ebi;
+            Extensible&lt;double&gt; ed;
             int i;
             if (o is int) {
-                b = ((int)o).ToByteChecked();
-            } else if ((ei = o as Extensible&lt;int&gt;) != null) {
-                b = ei.Value.ToByteChecked();
+                return ((int)o).ToByteChecked();
             } else if (!Object.ReferenceEquals(bi = o as BigInteger, null)) {
-                int val;
-                if (bi.AsInt32(out val)) {
-                    b = ToByteChecked(val);
-                } else {
-                    // force error
-                    ToByteChecked(257);
-                    b = 0;
-                }
-            } else if(Converter.TryConvertToIndex(o, out i)) {
-                b = i.ToByteChecked();
-            } else{                
+                return bi.ToByteChecked();
+            } else if (o is double) {
+                return ((double)o).ToByteChecked();
+            } else if ((ei = o as Extensible&lt;int&gt;) != null) {
+                return ei.Value.ToByteChecked();
+            } else if (!Object.ReferenceEquals(ebi = o as Extensible&lt;BigInteger&gt;, null)) {
+                return ebi.Value.ToByteChecked();
+            } else if (!Object.ReferenceEquals(ed = o as Extensible&lt;double&gt;, null)) {
+                return ed.Value.ToByteChecked();
+            } else if (o is byte) {
+                return (byte)o;
+            } else if (o is sbyte) {
+                return ((int)(sbyte)o).ToByteChecked();
+            } else if (o is char) {
+                return ((int)(char)o).ToByteChecked();
+            } else if (o is short) {
+                return ((int)(short)o).ToByteChecked();
+            } else if (o is ushort) {
+                return ((int)(ushort)o).ToByteChecked();
+            } else if (o is uint) {
+                return BigInteger.Create((uint)o).ToByteChecked();
+            } else if (o is float) {
+                return ((double)(float)o).ToByteChecked();
+            } else if (Converter.TryConvertToIndex(o, out i)) {
+                return i.ToByteChecked();
+            } else {
                 throw PythonOps.TypeError(&quot;an integer or string of size 1 is required&quot;);
             }
-            return b;
         }
     }
 }</diff>
      <filename>Merlin/Main/Languages/IronPython/IronPython/Runtime/Operations/ByteOps.cs</filename>
    </modified>
    <modified>
      <diff>@@ -14,11 +14,13 @@
  * ***************************************************************************/
 
 using System;
+using System.Collections;
 using System.Collections.Generic;
+using System.Diagnostics;
 using System.Text;
 
+using Microsoft.Scripting.Runtime;
 using Microsoft.Scripting.Utils;
-using System.Diagnostics;
 
 namespace IronPython.Runtime.Operations {
     internal static class IListOfByteOps {
@@ -40,6 +42,24 @@ namespace IronPython.Runtime.Operations {
             return self.Count &gt; other.Count ? +1 : -1;
         }
 
+        internal static int Compare(this IList&lt;byte&gt;/*!*/ self, string other) {
+            for (int i = 0; i &lt; self.Count &amp;&amp; i &lt; other.Length; i++) {
+                if ((char)self[i] != other[i]) {
+                    if ((char)self[i] &gt; other[i]) {
+                        return 1;
+                    } else {
+                        return -1;
+                    }
+                }
+            }
+
+            if (self.Count == other.Length) {
+                return 0;
+            }
+
+            return self.Count &gt; other.Length ? +1 : -1;
+        }
+
         internal static bool EndsWith(this IList&lt;byte&gt;/*!*/ self, IList&lt;byte&gt;/*!*/ suffix) {
             if (self.Count &lt; suffix.Count) {
                 return false;
@@ -93,7 +113,7 @@ namespace IronPython.Runtime.Operations {
 
         internal static bool EndsWith(this IList&lt;byte&gt;/*!*/ bytes, PythonTuple/*!*/ suffix) {
             foreach (object obj in suffix) {
-                if (bytes.EndsWith(ByteOps.GetBytes(obj))) {
+                if (bytes.EndsWith(ByteOps.CoerceBytes(obj))) {
                     return true;
                 }
             }
@@ -111,7 +131,7 @@ namespace IronPython.Runtime.Operations {
                 }
             }
             foreach (object obj in suffix) {
-                if (bytes.Substring(start).EndsWith(ByteOps.GetBytes(obj))) {
+                if (bytes.Substring(start).EndsWith(ByteOps.CoerceBytes(obj))) {
                     return true;
                 }
             }
@@ -141,7 +161,7 @@ namespace IronPython.Runtime.Operations {
             }
 
             foreach (object obj in suffix) {
-                if (bytes.Substring(start, end - start).EndsWith(ByteOps.GetBytes(obj))) {
+                if (bytes.Substring(start, end - start).EndsWith(ByteOps.CoerceBytes(obj))) {
                     return true;
                 }
             }
@@ -1004,7 +1024,7 @@ namespace IronPython.Runtime.Operations {
             if (end &lt; start) return false;
 
             foreach (object obj in prefix) {
-                if (bytes.Substring(start, end - start).StartsWith(ByteOps.GetBytes(obj))) {
+                if (bytes.Substring(start, end - start).StartsWith(ByteOps.CoerceBytes(obj))) {
                     return true;
                 }
             }
@@ -1021,7 +1041,7 @@ namespace IronPython.Runtime.Operations {
                 }
             }
             foreach (object obj in prefix) {
-                if (bytes.Substring(start).StartsWith(ByteOps.GetBytes(obj))) {
+                if (bytes.Substring(start).StartsWith(ByteOps.CoerceBytes(obj))) {
                     return true;
                 }
             }
@@ -1030,7 +1050,7 @@ namespace IronPython.Runtime.Operations {
 
         internal static bool StartsWith(this IList&lt;byte&gt;/*!*/ bytes, PythonTuple/*!*/ prefix) {
             foreach (object obj in prefix) {
-                if (bytes.StartsWith(ByteOps.GetBytes(obj))) {
+                if (bytes.StartsWith(ByteOps.CoerceBytes(obj))) {
                     return true;
                 }
             }
@@ -1231,5 +1251,92 @@ namespace IronPython.Runtime.Operations {
             }
             return res;
         }
+
+        #region Conversion and Enumeration
+
+        [PythonType(&quot;bytes_iterator&quot;)]
+        private class PythonBytesEnumerator&lt;T&gt; : IEnumerable, IEnumerator&lt;T&gt; {
+            private readonly IList&lt;byte&gt;/*!*/ _bytes;
+            private readonly Func&lt;byte, T&gt;/*!*/ _conversion;
+            private int _index;
+
+            public PythonBytesEnumerator(IList&lt;byte&gt; bytes, Func&lt;byte, T&gt; conversion) {
+                Assert.NotNull(bytes);
+                Assert.NotNull(conversion);
+
+                _bytes = bytes;
+                _conversion = conversion;
+                _index = -1;
+            }
+
+            #region IEnumerator&lt;T&gt; Members
+
+            public T Current {
+                get {
+                    if (_index &lt; 0) {
+                        throw PythonOps.SystemError(&quot;Enumeration has not started. Call MoveNext.&quot;);
+                    } else if (_index &gt;= _bytes.Count) {
+                        throw PythonOps.SystemError(&quot;Enumeration already finished.&quot;);
+                    }
+                    return _conversion(_bytes[_index]);
+                }
+            }
+
+            #endregion
+
+            #region IDisposable Members
+
+            public void Dispose() { }
+
+            #endregion
+
+            #region IEnumerator Members
+
+            object IEnumerator.Current {
+                get {
+                    return ((IEnumerator&lt;T&gt;)this).Current;
+                }
+            }
+
+            public bool MoveNext() {
+                if (_index &gt;= _bytes.Count) {
+                    return false;
+                }
+                _index++;
+                return _index != _bytes.Count;
+            }
+
+            public void Reset() {
+                _index = -1;
+            }
+
+            #endregion
+
+            #region IEnumerable Members
+
+            public IEnumerator GetEnumerator() {
+                return this;
+            }
+
+            #endregion
+        }
+
+        internal static IEnumerable BytesEnumerable(IList&lt;byte&gt; bytes) {
+            return new PythonBytesEnumerator&lt;Bytes&gt;(bytes, b =&gt; Bytes.Make(new byte[] { b }));
+        }
+
+        internal static IEnumerable BytesIntEnumerable(IList&lt;byte&gt; bytes) {
+            return new PythonBytesEnumerator&lt;int&gt;(bytes, b =&gt; (int)b);
+        }
+
+        internal static IEnumerator&lt;Bytes&gt; BytesEnumerator(IList&lt;byte&gt; bytes) {
+            return new PythonBytesEnumerator&lt;Bytes&gt;(bytes, b =&gt; Bytes.Make(new byte[] { b }));
+        }
+
+        internal static IEnumerator&lt;int&gt; BytesIntEnumerator(IList&lt;byte&gt; bytes) {
+            return new PythonBytesEnumerator&lt;int&gt;(bytes, b =&gt; (int)b);
+        }
+
+        #endregion
     }
 }</diff>
      <filename>Merlin/Main/Languages/IronPython/IronPython/Runtime/Operations/IListOfByteOps.cs</filename>
    </modified>
    <modified>
      <diff>@@ -179,10 +179,32 @@ namespace IronPython.Runtime.Operations {
             return type\u00F8.CreateInstance(context, args, names);
         }
 
-        public static object IterMethod(CodeContext/*!*/ context, object self) {
+        // 3.0-only
+        public static object IterMethodForString(string self) {
+            return PythonOps.StringEnumerator(self);
+        }
+
+        // 3.0-only
+        public static object IterMethodForBytes(Bytes self) {
+            return PythonOps.BytesIntEnumerator(self);
+        }
+
+        public static object IterMethodForEnumerator(IEnumerator self) {
             return self;
         }
 
+        public static object IterMethodForEnumerable(IEnumerable self) {
+            return self.GetEnumerator();
+        }
+
+        public static object IterMethodForGenericEnumerator&lt;T&gt;(IEnumerator&lt;T&gt; self) {
+            return self;
+        }
+
+        public static object IterMethodForGenericEnumerable&lt;T&gt;(IEnumerable&lt;T&gt; self) {
+            return self.GetEnumerator();
+        }
+
         public static object NextMethod(object self) {
             IEnumerator i = (IEnumerator)self;
             if (i.MoveNext()) return i.Current;</diff>
      <filename>Merlin/Main/Languages/IronPython/IronPython/Runtime/Operations/InstanceOps.cs</filename>
    </modified>
    <modified>
      <diff>@@ -111,8 +111,7 @@ namespace IronPython.Runtime.Operations {
                     result is Extensible&lt;int&gt; || result is Extensible&lt;BigInteger&gt;) {
                     return result;
                 } else {
-                    throw PythonOps.TypeError(&quot;__int__ returned non-Integral (type {0})&quot;,
-                        result is OldInstance ? ((OldInstance)result)._class.__name__ : DynamicHelpers.GetPythonType(result).Name);
+                    throw PythonOps.TypeError(&quot;__int__ returned non-Integral (type {0})&quot;, PythonTypeOps.GetOldName(result));
                 }
             } else if (PythonOps.TryGetBoundAttr(context, o, Symbols.Truncate, out result)) {
                 result = PythonOps.CallWithContext(context, result);
@@ -124,17 +123,14 @@ namespace IronPython.Runtime.Operations {
                 } else if (Converter.TryConvertToBigInteger(result, out bigintRes)) {
                     return bigintRes;
                 } else {
-                    throw PythonOps.TypeError(&quot;__trunc__ returned non-Integral (type {0})&quot;,
-                        result is OldInstance ? ((OldInstance)result)._class.__name__ : DynamicHelpers.GetPythonType(result).Name);
+                    throw PythonOps.TypeError(&quot;__trunc__ returned non-Integral (type {0})&quot;, PythonTypeOps.GetOldName(result));
                 }
             }
 
             if (o is OldInstance) {
-                throw PythonOps.AttributeError(&quot;{0} instance has no attribute '__trunc__'&quot;,
-                    ((OldInstance)o)._class.__name__);
+                throw PythonOps.AttributeError(&quot;{0} instance has no attribute '__trunc__'&quot;, PythonTypeOps.GetOldName((OldInstance)o));
             } else {
-                throw PythonOps.TypeError(&quot;int() argument must be a string or a number, not '{0}'&quot;,
-                    DynamicHelpers.GetPythonType(o).Name);
+                throw PythonOps.TypeError(&quot;int() argument must be a string or a number, not '{0}'&quot;, PythonTypeOps.GetName(o));
             }
         }
 </diff>
      <filename>Merlin/Main/Languages/IronPython/IronPython/Runtime/Operations/IntOps.cs</filename>
    </modified>
    <modified>
      <diff>@@ -172,7 +172,7 @@ namespace IronPython.Runtime.Operations {
         internal static string GetPythonTypeName(object obj) {
             OldInstance oi = obj as OldInstance;
             if (oi != null) return oi._class._name.ToString();
-            else return DynamicHelpers.GetPythonType(obj).Name;
+            else return PythonTypeOps.GetName(obj);
         }
 
         public static string Repr(CodeContext/*!*/ context, object o) {
@@ -225,7 +225,7 @@ namespace IronPython.Runtime.Operations {
             if (ret == null) {
                 Extensible&lt;string&gt; es = value as Extensible&lt;string&gt;;
                 if (es == null) {
-                    throw PythonOps.TypeError(&quot;expected str, got {0} from __str__&quot;, DynamicHelpers.GetPythonType(value).Name);
+                    throw PythonOps.TypeError(&quot;expected str, got {0} from __str__&quot;, PythonTypeOps.GetName(value));
                 }
 
                 ret = es.Value;
@@ -505,7 +505,7 @@ namespace IronPython.Runtime.Operations {
                 }
 
                 if (pt == null || !Converter.TryConvertToIndex(pt[0], out icount)) {
-                    throw TypeError(&quot;can't multiply sequence by non-int of type '{0}'&quot;, DynamicHelpers.GetPythonType(count).Name);
+                    throw TypeError(&quot;can't multiply sequence by non-int of type '{0}'&quot;, PythonTypeOps.GetName(count));
                 }
             }
             return icount;
@@ -736,33 +736,6 @@ namespace IronPython.Runtime.Operations {
             throw PythonOps.TypeErrorForBinaryOp(&quot;power with modulus&quot;, x, y);
         }
 
-        public static ICollection GetCollection(object o) {
-            ICollection ret = o as ICollection;
-            if (ret != null) return ret;
-
-            List&lt;object&gt; al = new List&lt;object&gt;();
-            IEnumerator e = GetEnumerator(o);
-            while (e.MoveNext()) al.Add(e.Current);
-            return al;
-        }
-
-        public static IEnumerator GetEnumerator(object o) {
-            IEnumerator ie;
-            if (!TryGetEnumerator(DefaultContext.Default, o, out ie)) {
-                throw PythonOps.TypeError(&quot;{0} is not enumerable&quot;, PythonTypeOps.GetName(o));
-            }
-            return ie;
-        }
-
-        public static IEnumerator GetEnumeratorForUnpack(CodeContext/*!*/ context, object enumerable) {
-            IEnumerator enumerator;
-            if (!TryGetEnumerator(context, enumerable, out enumerator)) {
-                throw PythonOps.TypeError(&quot;'{0}' object is not iterable&quot;, PythonTypeOps.GetName(enumerable));
-            }
-
-            return enumerator;
-        }
-
         public static long Id(object o) {
             return IdDispenser.GetId(o);
         }
@@ -993,7 +966,7 @@ namespace IronPython.Runtime.Operations {
                     throw PythonOps.AttributeError(&quot;type object '{0}' has no attribute '{1}'&quot;,
                         ((OldClass)o).__name__, SymbolTable.IdToString(name));
                 } else {
-                    throw PythonOps.AttributeError(&quot;'{0}' object has no attribute '{1}'&quot;, DynamicHelpers.GetPythonType(o).Name, SymbolTable.IdToString(name));
+                    throw PythonOps.AttributeError(&quot;'{0}' object has no attribute '{1}'&quot;, PythonTypeOps.GetName(o), SymbolTable.IdToString(name));
                 }
             }
 
@@ -1023,7 +996,7 @@ namespace IronPython.Runtime.Operations {
                 return value;
             }            
 
-            throw PythonOps.AttributeErrorForMissingAttribute(DynamicHelpers.GetPythonType(o).Name, name);
+            throw PythonOps.AttributeErrorForMissingAttribute(PythonTypeOps.GetName(o), name);
         }
 
         public static IList&lt;object&gt; GetAttrNames(CodeContext/*!*/ context, object o) {
@@ -1058,7 +1031,7 @@ namespace IronPython.Runtime.Operations {
         public static void CheckInitializedAttribute(object o, object self, string name) {
             if (o == Uninitialized.Instance) {
                 throw PythonOps.AttributeError(&quot;'{0}' object has no attribute '{1}'&quot;,
-                    DynamicHelpers.GetPythonType(self),
+                    PythonTypeOps.GetName(self),
                     name);
             }
         }
@@ -1806,6 +1779,49 @@ namespace IronPython.Runtime.Operations {
 
         #endregion        
 
+        public static ICollection GetCollection(object o) {
+            ICollection ret = o as ICollection;
+            if (ret != null) return ret;
+
+            List&lt;object&gt; al = new List&lt;object&gt;();
+            IEnumerator e = GetEnumerator(o);
+            while (e.MoveNext()) al.Add(e.Current);
+            return al;
+        }
+
+        public static IEnumerator GetEnumerator(object o) {
+            return GetEnumerator(DefaultContext.Default, o);
+        }
+
+        public static IEnumerator GetEnumerator(CodeContext/*!*/ context, object o) {
+            IEnumerator ie;
+            if (!TryGetEnumerator(context, o, out ie)) {
+                throw PythonOps.TypeError(&quot;{0} is not iterable&quot;, PythonTypeOps.GetName(o));
+            }
+            return ie;
+        }
+
+        // Lack of type restrictions allows this method to return the direct result of __iter__ without
+        // wrapping it. This is the proper behavior for Builtin.iter().
+        public static object GetEnumeratorObject(CodeContext/*!*/ context, object o) {
+            object iterFunc;
+            if (PythonOps.TryGetBoundAttr(context, o, Symbols.Iterator, out iterFunc) &amp;&amp;
+                !Object.ReferenceEquals(iterFunc, NotImplementedType.Value)) {
+                return PythonOps.CallWithContext(context, iterFunc);
+            }
+
+            return GetEnumerator(context, o);
+        }
+
+        public static IEnumerator GetEnumeratorForUnpack(CodeContext/*!*/ context, object enumerable) {
+            IEnumerator enumerator;
+            if (!TryGetEnumerator(context, enumerable, out enumerator)) {
+                throw PythonOps.TypeError(&quot;'{0}' object is not iterable&quot;, PythonTypeOps.GetName(enumerable));
+            }
+
+            return enumerator;
+        }
+
         public static IEnumerator GetEnumeratorForIteration(CodeContext/*!*/ context, object enumerable) {
             IEnumerator enumerator;
             if (!TryGetEnumerator(context, enumerable, out enumerator)) {
@@ -1816,43 +1832,44 @@ namespace IronPython.Runtime.Operations {
         }
 
         public static IEnumerator ThrowTypeErrorForBadIteration(CodeContext context, object enumerable) {
-            throw PythonOps.TypeError(
-                &quot;iteration over non-sequence of type {0}&quot;,
-                PythonOps.Repr(context, DynamicHelpers.GetPythonType(enumerable))
-            );
+            throw PythonOps.TypeError(&quot;iteration over non-sequence of type {0}&quot;, PythonTypeOps.GetName(enumerable));
         }
 
         internal static bool TryGetEnumerator(CodeContext/*!*/ context, object enumerable, out IEnumerator enumerator) {
-            string str = enumerable as string;
-            if (str != null) {
-                enumerator = StringEnumerator(str);
-                return true;
-            }
-
-            IEnumerable enumer = enumerable as IEnumerable;
-            if (enumer != null) {
+            enumerator = null;
+            IEnumerable enumer;
+            if (PythonContext.GetContext(context).TryConvertToIEnumerable(enumerable, out enumer)) {
                 enumerator = enumer.GetEnumerator();
                 return true;
             }
 
-            enumerator = enumerable as IEnumerator;
-            if (enumerator != null) {
-                return true;
-            }
-
-            IEnumerable ie;
-            if (!PythonContext.GetContext(context).TryConvertToIEnumerable(enumerable, out ie)) {
-                return false;
-            }
-
-            enumerator = ie.GetEnumerator();
-            return true;
+            return false;
         }
 
         public static IEnumerator&lt;string&gt; StringEnumerator(string str) {
             return StringOps.StringEnumerator(str);
         }
 
+        public static IEnumerator&lt;Bytes&gt; BytesEnumerator(IList&lt;byte&gt; bytes) {
+            return IListOfByteOps.BytesEnumerator(bytes);
+        }
+
+        public static IEnumerator&lt;int&gt; BytesIntEnumerator(IList&lt;byte&gt; bytes) {
+            return IListOfByteOps.BytesIntEnumerator(bytes);
+        }
+
+        public static IEnumerable StringEnumerable(string str) {
+            return StringOps.StringEnumerable(str);
+        }
+
+        public static IEnumerable BytesEnumerable(IList&lt;byte&gt; bytes) {
+            return IListOfByteOps.BytesEnumerable(bytes);
+        }
+
+        public static IEnumerable BytesIntEnumerable(IList&lt;byte&gt; bytes) {
+            return IListOfByteOps.BytesIntEnumerable(bytes);
+        }
+        
         #region Exception handling
 
         // The semantics here are:
@@ -2148,7 +2165,7 @@ namespace IronPython.Runtime.Operations {
             if (!PythonTypeOps.TryInvokeUnaryOperator(context, dict, Symbols.Keys, out keys)) {
                 throw PythonOps.TypeError(&quot;{0}() argument after ** must be a mapping, not {1}&quot;,
                     funcName,
-                    DynamicHelpers.GetPythonType(dict).Name);
+                    PythonTypeOps.GetName(dict));
             }
 
             PythonDictionary res = new PythonDictionary();
@@ -2163,7 +2180,7 @@ namespace IronPython.Runtime.Operations {
                     if (es == null) {
                         throw PythonOps.TypeError(&quot;{0}() keywords most be strings, not {0}&quot;,
                             funcName,
-                            DynamicHelpers.GetPythonType(dict).Name);
+                            PythonTypeOps.GetName(dict));
                     }
 
                     s = es.Value;
@@ -2954,17 +2971,6 @@ namespace IronPython.Runtime.Operations {
             return new ItemEnumerable(callable, site);
         }
 
-        public static IEnumerator MakePythonEnumerator(object iterator) {
-            IEnumerator enumerator;
-            IEnumerable enumerale = iterator as IEnumerable;
-            if (enumerale != null) {
-                enumerator = enumerale.GetEnumerator();
-            } else {
-                enumerator = new PythonEnumerator(iterator);
-            }
-            return enumerator;
-        }
-
         public static DictionaryKeyEnumerator MakeDictionaryKeyEnumerator(PythonDictionary dict) {
             return new DictionaryKeyEnumerator(dict._storage);
         }
@@ -3421,7 +3427,7 @@ namespace IronPython.Runtime.Operations {
             byte[] ret = new byte[s.Length];
             for (int i = 0; i &lt; s.Length; i++) {
                 if (s[i] &lt; 0x100) ret[i] = (byte)s[i];
-                else throw PythonOps.UnicodeDecodeError(&quot;'ascii' codec can't decode byte {0:X} in position {1}: ordinal not in range&quot;, (int)ret[i], i);
+                else throw PythonOps.UnicodeEncodeError(&quot;'ascii' codec can't decode byte {0:X} in position {1}: ordinal not in range&quot;, (int)ret[i], i);
             }
             return ret;
         }
@@ -3676,7 +3682,7 @@ namespace IronPython.Runtime.Operations {
             return new KeyNotFoundException(string.Format(format, args));
         }
 
-        public static Exception UnicodeEncodeError(string format, params object[] args) {
+        public static Exception UnicodeDecodeError(string format, params object[] args) {
 #if SILVERLIGHT // EncoderFallbackException and DecoderFallbackException
             throw new NotImplementedException();
 #else
@@ -3684,7 +3690,7 @@ namespace IronPython.Runtime.Operations {
 #endif
         }
 
-        public static Exception UnicodeDecodeError(string format, params object[] args) {
+        public static Exception UnicodeEncodeError(string format, params object[] args) {
 #if SILVERLIGHT // EncoderFallbackException and DecoderFallbackException
             throw new NotImplementedException();
 #else
@@ -3829,7 +3835,7 @@ namespace IronPython.Runtime.Operations {
 
         public static Exception TypeErrorForUnboundMethodCall(string methodName, PythonType methodType, object instance) {
             string message = string.Format(&quot;unbound method {0}() must be called with {1} instance as first argument (got {2} instead)&quot;,
-                                           methodName, methodType.Name, DynamicHelpers.GetPythonType(instance).Name);
+                                           methodName, methodType.Name, PythonTypeOps.GetName(instance));
             return TypeError(message);
         }
 
@@ -3857,7 +3863,7 @@ namespace IronPython.Runtime.Operations {
         }
 
         public static Exception TypeErrorForUnhashableObject(object obj) {
-            return TypeErrorForUnhashableType(DynamicHelpers.GetPythonType(obj).Name);
+            return TypeErrorForUnhashableType(PythonTypeOps.GetName(obj));
         }
 
         internal static Exception TypeErrorForIncompatibleObjectLayout(string prefix, PythonType type, Type newType) {
@@ -3885,7 +3891,7 @@ namespace IronPython.Runtime.Operations {
         public static Exception TypeErrorForNonIterableObject(object o) {
             return PythonOps.TypeError(
                 &quot;argument of type '{0}' is not iterable&quot;,
-                DynamicHelpers.GetPythonType(o).Name
+                PythonTypeOps.GetName(o)
             );
         }
 
@@ -3920,7 +3926,7 @@ namespace IronPython.Runtime.Operations {
         /// &lt;param name=&quot;type&quot;&gt;original type of exception requested&lt;/param&gt;
         /// &lt;returns&gt;a TypeEror exception&lt;/returns&gt;
         internal static Exception MakeExceptionTypeError(object type) {
-            return PythonOps.TypeError(&quot;exceptions must be classes or instances, not {0}&quot;, DynamicHelpers.GetPythonType(type).Name);
+            return PythonOps.TypeError(&quot;exceptions must be classes or instances, not {0}&quot;, PythonTypeOps.GetName(type));
         }
 
         public static Exception AttributeErrorForMissingAttribute(string typeName, SymbolId attributeName) {</diff>
      <filename>Merlin/Main/Languages/IronPython/IronPython/Runtime/Operations/PythonOps.cs</filename>
    </modified>
    <modified>
      <diff>@@ -62,6 +62,11 @@ namespace IronPython.Runtime.Operations {
 
                     curType = curType.DeclaringType;
                 }
+
+                FieldInfo modField = type.GetField(&quot;__module__&quot;);
+                if (modField != null &amp;&amp; modField.IsLiteral &amp;&amp; modField.FieldType == typeof(string)) {
+                    return (string)modField.GetRawConstantValue();
+                }
                 return &quot;__builtin__&quot;;
             }
 
@@ -200,10 +205,21 @@ namespace IronPython.Runtime.Operations {
                 (cls != TypeCache.PythonType || argCnt &gt; 1);
         }
 
+        // note: returns &quot;instance&quot; rather than type name if o is an OldInstance
         internal static string GetName(object o) {
             return DynamicHelpers.GetPythonType(o).Name;
         }
 
+        // a version of GetName that also works on old-style classes
+        internal static string GetOldName(object o) {
+            return o is OldInstance ? GetOldName((OldInstance)o) : GetName(o);
+        }
+
+        // a version of GetName that also works on old-style classes
+        internal static string GetOldName(OldInstance instance) {
+            return instance._class.__name__;
+        }
+
         internal static PythonType[] ObjectTypes(object[] args) {
             PythonType[] types = new PythonType[args.Length];
             for (int i = 0; i &lt; args.Length; i++) {</diff>
      <filename>Merlin/Main/Languages/IronPython/IronPython/Runtime/Operations/PythonTypeOps.cs</filename>
    </modified>
    <modified>
      <diff>@@ -53,8 +53,9 @@ namespace IronPython.Runtime.Operations {
 
         [return: MaybeNotImplemented]
         public object __eq__(object other) {
-            if (other is string || other is ExtensibleString)
+            if (other is string || other is ExtensibleString || other is Bytes) {
                 return ScriptingRuntimeHelpers.BooleanToObject(((IValueEquality)this).ValueEquals(other));
+            }
 
             return NotImplementedType.Value;
         }
@@ -82,6 +83,8 @@ namespace IronPython.Runtime.Operations {
             if (es != null) return Value == es.Value;
             string os = other as string;
             if (os != null) return Value == os;
+            Bytes bs = other as Bytes;
+            if (bs != null) return Value == bs.ToString();
 
             return false;
         }
@@ -1276,7 +1279,7 @@ namespace IronPython.Runtime.Operations {
         public static string ConvertFromChar(char c) {
             return ScriptingRuntimeHelpers.CharToString(c);
         }
-
+        
         [SpecialName, ExplicitConversionMethod]
         public static char ConvertToChar(string s) {
             if (s.Length == 1) return s[0];
@@ -1285,7 +1288,8 @@ namespace IronPython.Runtime.Operations {
 
         [SpecialName, ImplicitConversionMethod]
         public static IEnumerable ConvertToIEnumerable(string s) {
-            return StringOps.GetEnumerable(s);
+            // make an enumerator that produces strings instead of chars
+            return new PythonStringEnumerable(s);
         }
 
         internal static int Compare(string self, string obj) {
@@ -1311,11 +1315,6 @@ namespace IronPython.Runtime.Operations {
 
         #region Internal implementation details
 
-        internal static IEnumerable GetEnumerable(string s) {
-            // make an enumerator that produces strings instead of chars
-            return new PythonStringEnumerable(s);
-        }
-
         internal static string Quote(string s) {
 
             bool isUnicode = false;
@@ -1836,6 +1835,16 @@ namespace IronPython.Runtime.Operations {
             public override byte[] GetPreamble() {
                 return _preamble;
             }
+            
+            public override Encoder GetEncoder() {
+                SetEncoderFallback();
+                return _encoding.GetEncoder();
+            }
+
+            public override Decoder GetDecoder() {
+                SetDecoderFallback();
+                return _encoding.GetDecoder();
+            }
 
             public override object Clone() {
                 // need to call base.Clone to be marked as read/write
@@ -2028,30 +2037,80 @@ namespace IronPython.Runtime.Operations {
             return false;
         }
 
-        private class PythonStringEnumerable : IEnumerable {
+        // note: any changes in how this iterator works should also be applied in the
+        //       optimized overloads of Builtins.map()
+        [PythonType(&quot;str_iterator&quot;)]
+        private class PythonStringEnumerable : IEnumerable, IEnumerator&lt;string&gt; {
             private readonly string/*!*/ _s;
+            private int _index;
 
             public PythonStringEnumerable(string s) {
                 Assert.NotNull(s);
 
+                _index = -1;
                 _s = s;
             }
 
             #region IEnumerable Members
 
             public IEnumerator GetEnumerator() {
-                return StringEnumerator(_s);
+                return this;
+            }
+
+            #endregion
+
+            #region IEnumerator&lt;string&gt; Members
+
+            public string Current {
+                get {
+                    if (_index &lt; 0) {
+                        throw PythonOps.SystemError(&quot;Enumeration has not started. Call MoveNext.&quot;);
+                    } else if (_index &gt;= _s.Length) {
+                        throw PythonOps.SystemError(&quot;Enumeration already finished.&quot;);
+                    }
+                    return ScriptingRuntimeHelpers.CharToString(_s[_index]);
+                }
+            }
+
+            #endregion
+
+            #region IDisposable Members
+
+            public void Dispose() { }
+
+            #endregion
+
+            #region IEnumerator Members
+
+            object IEnumerator.Current {
+                get {
+                    return ((IEnumerator&lt;string&gt;)this).Current;
+                }
+            }
+
+            public bool MoveNext() {
+                if (_index &gt;= _s.Length) {
+                    return false;
+                }
+                _index++;
+                return _index != _s.Length;
+            }
+
+            public void Reset() {
+                _index = -1;
             }
 
             #endregion
         }
 
+        internal static IEnumerable StringEnumerable(string str) {
+            return new PythonStringEnumerable(str);
+        }
+
         internal static IEnumerator&lt;string&gt; StringEnumerator(string str) {
-            for (int i = 0; i &lt; str.Length; i++) {
-                yield return ScriptingRuntimeHelpers.CharToString(str[i]);
-            }
+            return new PythonStringEnumerable(str);
         }
-        
+
         #endregion
 
         #region  Unicode Encode/Decode Fallback Support</diff>
      <filename>Merlin/Main/Languages/IronPython/IronPython/Runtime/Operations/StringOps.cs</filename>
    </modified>
    <modified>
      <diff>@@ -191,12 +191,12 @@ namespace IronPython.Runtime {
         private int _index;
 
         public override bool Fallback(char charUnknownHigh, char charUnknownLow, int index) {
-            throw PythonOps.UnicodeDecodeError(&quot;'ascii' codec can't encode character '\\u{0:X}{1:04X}' in position {1}&quot;, (int)charUnknownHigh, (int)charUnknownLow, index);
+            throw PythonOps.UnicodeEncodeError(&quot;'ascii' codec can't encode character '\\u{0:X}{1:04X}' in position {1}&quot;, (int)charUnknownHigh, (int)charUnknownLow, index);
         }
 
         public override bool Fallback(char charUnknown, int index) {
             if (charUnknown &gt; 0xff) {
-                throw PythonOps.UnicodeDecodeError(&quot;'ascii' codec can't encode character '\\u{0:X}' in position {1}&quot;, (int)charUnknown, index);
+                throw PythonOps.UnicodeEncodeError(&quot;'ascii' codec can't encode character '\\u{0:X}' in position {1}&quot;, (int)charUnknown, index);
             }
 
             _buffer.Add(charUnknown);</diff>
      <filename>Merlin/Main/Languages/IronPython/IronPython/Runtime/PythonAsciiEncoding.cs</filename>
    </modified>
    <modified>
      <diff>@@ -685,16 +685,15 @@ namespace IronPython.Runtime {
             StreamReader sr = new StreamReader(stream, PythonAsciiEncoding.SourceEncoding);
             byte[] bomBuffer = new byte[3];
             int bomRead = stream.Read(bomBuffer, 0, 3);
+            int bytesRead = 0;
             bool isUtf8 = false;
-            if (bomRead == 3) {
-                if (bomBuffer[0] == 0xef &amp;&amp; bomBuffer[1] == 0xbb &amp;&amp; bomBuffer[2] == 0xbf) {
-                    isUtf8 = true;
-                } else {
-                    stream.Seek(0, SeekOrigin.Begin);
-                }
+            if (bomRead == 3 &amp;&amp; (bomBuffer[0] == 0xef &amp;&amp; bomBuffer[1] == 0xbb &amp;&amp; bomBuffer[2] == 0xbf)) {
+                isUtf8 = true;
+                bytesRead = 3;
+            } else {
+                stream.Seek(0, SeekOrigin.Begin);
             }
 
-            int bytesRead = 0;
             string line;
             try {
                 line = ReadOneLine(sr, ref bytesRead);</diff>
      <filename>Merlin/Main/Languages/IronPython/IronPython/Runtime/PythonContext.cs</filename>
    </modified>
    <modified>
      <diff>@@ -796,14 +796,23 @@ namespace IronPython.Runtime {
     #region File Manager
 
     internal class PythonFileManager {
-        private HybridMapping&lt;PythonFile&gt; mapping = new HybridMapping&lt;PythonFile&gt;(3);
+        private HybridMapping&lt;PythonFile&gt; fileMapping = new HybridMapping&lt;PythonFile&gt;(3);
+        private HybridMapping&lt;object&gt; objMapping = new HybridMapping&lt;object&gt;(3);
 
         public int AddToStrongMapping(PythonFile pf) {
-            return mapping.StrongAdd(pf);
+            return fileMapping.StrongAdd(pf);
+        }
+
+        public int AddToStrongMapping(object o) {
+            return objMapping.StrongAdd(o);
         }
 
         public void Remove(PythonFile pf) {
-            mapping.RemoveOnObject(pf);
+            fileMapping.RemoveOnObject(pf);
+        }
+
+        public void Remove(object o) {
+            objMapping.RemoveOnObject(o);
         }
 
         public PythonFile GetFileFromId(PythonContext context, int id) {
@@ -819,7 +828,7 @@ namespace IronPython.Runtime {
                     pf = (context.GetSystemStateValue(&quot;__stderr__&quot;) as PythonFile);
                     break;
                 default:
-                    pf = mapping.GetObjectFromId(id);
+                    pf = fileMapping.GetObjectFromId(id);
                     break;
             }
 
@@ -829,6 +838,15 @@ namespace IronPython.Runtime {
             return pf;
         }
 
+        public object GetObjectFromId(PythonContext context, int id) {
+            object o = objMapping.GetObjectFromId(id);
+
+            if (o == null) {
+                throw PythonOps.OSError(&quot;Bad file descriptor&quot;);
+            }
+            return o;
+        }
+
         public int GetIdFromFile(PythonFile pf) {
             if (pf.IsConsole) {
                 for (int i = 0; i &lt; 3; i++) {
@@ -838,10 +856,19 @@ namespace IronPython.Runtime {
                 }
             }
 
-            int res = mapping.GetIdFromObject(pf);
+            int res = fileMapping.GetIdFromObject(pf);
             if (res == -1) {
                 // lazily created weak mapping
-                res = mapping.WeakAdd(pf);
+                res = fileMapping.WeakAdd(pf);
+            }
+            return res;
+        }
+
+        public int GetIdFromObject(object o) {
+            int res = objMapping.GetIdFromObject(o);
+            if (res == -1) {
+                // lazily created weak mapping
+                res = objMapping.WeakAdd(o);
             }
             return res;
         }
@@ -1424,7 +1451,7 @@ namespace IronPython.Runtime {
             }
         }
 
-        public virtual void write(string s) {
+        public virtual void write([BytesConversion]string s) {
             lock (this) {
                 PythonStreamWriter writer = GetWriter();
                 int bytesWritten = writer.Write(s);
@@ -1474,12 +1501,18 @@ namespace IronPython.Runtime {
             while (e.MoveNext()) {
                 string line = e.Current as string;
                 if (line == null) {
-                    PythonBuffer b = e.Current as PythonBuffer;
+                    Bytes b = e.Current as Bytes;
                     if (b != null) {
                         write(b);
                         continue;
                     }
 
+                    PythonBuffer buf = e.Current as PythonBuffer;
+                    if (buf != null) {
+                        write(buf);
+                        continue;
+                    }
+
                     IPythonArray arr = e.Current as IPythonArray;
                     if (arr != null) {
                         write(arr);</diff>
      <filename>Merlin/Main/Languages/IronPython/IronPython/Runtime/PythonFile.cs</filename>
    </modified>
    <modified>
      <diff>@@ -145,7 +145,7 @@ namespace IronPython.Runtime {
             } else if ((arr = o as object[])!=null) {
                 return ArrayOps.CopyArray(arr, arr.Length);
             } else {
-                PerfTrack.NoteEvent(PerfTrack.Categories.OverAllocate, &quot;TupleOA: &quot; + DynamicHelpers.GetPythonType(o).Name);
+                PerfTrack.NoteEvent(PerfTrack.Categories.OverAllocate, &quot;TupleOA: &quot; + PythonTypeOps.GetName(o));
 
                 List&lt;object&gt; l = new List&lt;object&gt;();
                 IEnumerator i = PythonOps.GetEnumerator(o);
@@ -276,11 +276,15 @@ namespace IronPython.Runtime {
 
         #endregion
 
+        public virtual IEnumerator __iter__() {
+            return new TupleEnumerator(this);
+        }
+
         #region IEnumerable Members
-        
+
         [PythonHidden]
         public IEnumerator GetEnumerator() {
-            return new TupleEnumerator(this);
+            return __iter__();
         }
 
         #endregion
@@ -597,7 +601,8 @@ namespace IronPython.Runtime {
     /// &lt;summary&gt;
     /// public class to get optimized
     /// &lt;/summary&gt;
-    public class TupleEnumerator : IEnumerator, IEnumerator&lt;object&gt; {
+    [PythonType(&quot;tupleiterator&quot;)]
+    public sealed class TupleEnumerator : IEnumerable, IEnumerator, IEnumerator&lt;object&gt; {
         private int _curIndex;
         private PythonTuple _tuple;
 
@@ -637,12 +642,15 @@ namespace IronPython.Runtime {
         #region IDisposable Members
 
         public void Dispose() {
-            Dispose(true);
             GC.SuppressFinalize(this);
         }
 
-        protected virtual void Dispose(bool disposing) {
+        #endregion
 
+        #region IEnumerable Members
+
+        public IEnumerator GetEnumerator() {
+            return this;
         }
 
         #endregion</diff>
      <filename>Merlin/Main/Languages/IronPython/IronPython/Runtime/PythonTuple.cs</filename>
    </modified>
    <modified>
      <diff>@@ -197,14 +197,6 @@ namespace IronPython.Runtime {
             }
             return PythonTuple.MakeTuple(type, PythonTuple.MakeTuple(List.FromArrayNoCopy(keys)), null);
         }
-
-        public static IEnumerator&lt;object&gt; GetListEnumerator(CommonDictionaryStorage storage) {
-            List res = new List(storage.Count);
-            foreach (KeyValuePair&lt;object, object&gt; kvp in storage.GetItems()) {
-                res.Add(kvp.Key);
-            }
-            return ((IEnumerable&lt;object&gt;)res).GetEnumerator();
-        }
     }
 
     /// &lt;summary&gt;
@@ -596,16 +588,9 @@ namespace IronPython.Runtime {
 
         #region IEnumerable Members
 
-        IEnumerator IEnumerable.GetEnumerator() {
-            int count = this._items.Count;
-
-            foreach (object o in _items.GetKeys()) {
-                if (count != this._items.Count) {
-                    throw PythonOps.RuntimeError(&quot;set changed during iteration&quot;);
-                }
-
-                yield return o;
-            }
+        [PythonHidden]
+        public IEnumerator GetEnumerator() {
+            return new SetIterator(_items, true);
         }
 
         #endregion
@@ -683,20 +668,11 @@ namespace IronPython.Runtime {
 
         #region IEnumerable&lt;object&gt; Members
 
-        [PythonHidden]
-        public IEnumerator&lt;object&gt; GetEnumerator() {
-            int count = _items.Count;
-
-            foreach (KeyValuePair&lt;object,object&gt; o in _items.GetItems()) {
-                if (count != _items.Count) {
-                    throw PythonOps.RuntimeError(&quot;set changed during iteration&quot;);
-                }
-
-                yield return o.Key;
-            }
+        IEnumerator&lt;object&gt; IEnumerable&lt;object&gt;.GetEnumerator() {
+            return new SetIterator(_items, true);
         }
 
-        #endregion        
+        #endregion
 
         #region ICodeFormattable Members
 
@@ -1052,8 +1028,9 @@ namespace IronPython.Runtime {
 
         #region IEnumerable Members
 
-        IEnumerator IEnumerable.GetEnumerator() {
-            return SetHelpers.GetListEnumerator(_items);
+        [PythonHidden]
+        public IEnumerator GetEnumerator() {
+            return new SetIterator(_items, false);
         }
 
         #endregion
@@ -1167,9 +1144,8 @@ namespace IronPython.Runtime {
 
         #region IEnumerable&lt;object&gt; Members
 
-        [PythonHidden]
-        public IEnumerator&lt;object&gt; GetEnumerator() {
-            return SetHelpers.GetListEnumerator(_items);
+        IEnumerator&lt;object&gt; IEnumerable&lt;object&gt;.GetEnumerator() {
+            return new SetIterator(_items, false);
         }
 
         #endregion
@@ -1204,4 +1180,79 @@ namespace IronPython.Runtime {
         #endregion
     }
 
+    /// &lt;summary&gt;
+    /// Iterator over sets
+    /// &lt;/summary&gt;
+    [PythonType(&quot;setiterator&quot;)]
+    public sealed class SetIterator : IEnumerable, IEnumerable&lt;object&gt;, IEnumerator, IEnumerator&lt;object&gt; {
+        private bool _mutable;
+        private int _count;
+        private CommonDictionaryStorage _items;
+        private IEnumerator&lt;object&gt; _enumerator;
+
+        internal SetIterator(CommonDictionaryStorage items, bool mutable) {
+            _mutable = mutable;
+            _items = items;
+            if (mutable) {
+                lock (items) {
+                    _count = items.Count;
+                    _enumerator = items.GetKeys().GetEnumerator();
+                }
+            } else {
+                _count = items.Count;
+                _enumerator = items.GetKeys().GetEnumerator();
+            }
+        }
+
+        #region IEnumerator&lt;object&gt; Members
+
+        public object Current {
+            get {
+                if (_mutable &amp;&amp; (_count != _items.Count || !_items.Contains(_enumerator.Current))) {
+                    throw PythonOps.RuntimeError(&quot;set changed during iteration&quot;);
+                }
+
+                return _enumerator.Current;
+            }
+        }
+
+        #endregion
+
+        #region IDisposable Members
+
+        public void Dispose() {
+            _enumerator.Dispose();
+        }
+
+        #endregion
+
+        #region IEnumerator Members
+
+
+        public bool MoveNext() {
+            return _enumerator.MoveNext();
+        }
+
+        public void Reset() {
+            _enumerator.Reset();
+        }
+
+        #endregion
+
+        #region IEnumerable Members
+
+        public IEnumerator GetEnumerator() {
+            return this;
+        }
+
+        #endregion
+
+        #region IEnumerable&lt;object&gt; Members
+
+        IEnumerator&lt;object&gt; IEnumerable&lt;object&gt;.GetEnumerator() {
+            return this;
+        }
+
+        #endregion
+    }
 }</diff>
      <filename>Merlin/Main/Languages/IronPython/IronPython/Runtime/Set.cs</filename>
    </modified>
    <modified>
      <diff>@@ -15,10 +15,13 @@
 
 using System;
 using System.Collections;
-using IronPython.Runtime.Operations;
+
 using Microsoft.Scripting;
 using Microsoft.Scripting.Runtime;
 
+using IronPython.Runtime.Operations;
+using IronPython.Runtime.Types;
+
 namespace IronPython.Runtime {
     [PythonType(&quot;slice&quot;)]
     public sealed class Slice : ICodeFormattable, IComparable, IValueEquality, ISlice {
@@ -71,6 +74,17 @@ namespace IronPython.Runtime {
             return self.__cmp__(other) &lt; 0;
         }
 
+        public PythonTuple __reduce__() {
+            return PythonTuple.MakeTuple(
+                DynamicHelpers.GetPythonTypeFromType(typeof(Slice)),
+                PythonTuple.MakeTuple(
+                    _start,
+                    _stop,
+                    _step
+                )
+            );
+        }
+
         #endregion
 
         #region Object overrides</diff>
      <filename>Merlin/Main/Languages/IronPython/IronPython/Runtime/Slice.cs</filename>
    </modified>
    <modified>
      <diff>@@ -399,11 +399,34 @@ type(name, bases, dict) -&gt; creates a new type instance with the given name, base
         }
 
         [SpecialName, PropertyMethod, WrapperDescriptor]
-        public static string Get__module__(CodeContext/*!*/ context, PythonType self) {
+        public static object Get__module__(CodeContext/*!*/ context, PythonType self) {
+            PythonTypeSlot pts;
+            object res;
+            if (self._dict != null &amp;&amp; 
+                self._dict.TryGetValue(Symbols.Module, out pts) &amp;&amp; 
+                pts.TryGetValue(context, self, DynamicHelpers.GetPythonType(self), out res)) {
+                return res;
+            }
             return PythonTypeOps.GetModuleName(context, self.UnderlyingSystemType);
         }
 
         [SpecialName, PropertyMethod, WrapperDescriptor]
+        public static void Set__module__(CodeContext/*!*/ context, PythonType self, object value) {
+            if (self.IsSystemType) {
+                throw PythonOps.TypeError(&quot;can't set {0}.__module__&quot;, self.Name);
+            }
+
+            Debug.Assert(self._dict != null);
+            self._dict[Symbols.Module] = new PythonTypeUserDescriptorSlot(value);
+            self.UpdateVersion();
+        }
+
+        [SpecialName, PropertyMethod, WrapperDescriptor]
+        public static void Delete__module__(CodeContext/*!*/ context, PythonType self) {
+            throw PythonOps.TypeError(&quot;can't delete {0}.__module__&quot;, self.Name);
+        }
+
+        [SpecialName, PropertyMethod, WrapperDescriptor]
         public static PythonTuple Get__mro__(PythonType type) {
             return PythonTypeOps.MroToPython(type.ResolutionOrder);
         }
@@ -427,8 +450,8 @@ type(name, bases, dict) -&gt; creates a new type instance with the given name, base
 
             if (IsSystemType) {
                 if (PythonTypeOps.IsRuntimeAssembly(UnderlyingSystemType.Assembly) || IsPythonType) {
-                    string module = Get__module__(context, this);
-                    if (module != &quot;__builtin__&quot;) {
+                    object module = Get__module__(context, this);
+                    if (!module.Equals(&quot;__builtin__&quot;)) {
                         return string.Format(&quot;&lt;type '{0}.{1}'&gt;&quot;, module, Name);
                     }
                 }</diff>
      <filename>Merlin/Main/Languages/IronPython/IronPython/Runtime/Types/PythonType.cs</filename>
    </modified>
    <modified>
      <diff>@@ -788,22 +788,41 @@ namespace IronPython.Runtime.Types {
         /// Provides a resolution for __iter__
         /// &lt;/summary&gt;
         private static MemberGroup/*!*/ IterResolver(MemberBinder/*!*/ binder, Type/*!*/ type) {
-            // no __iter__ on string, just __getitem__
-            if (type != typeof(string)) {
-                if (typeof(System.Collections.IEnumerable).IsAssignableFrom(type)) {
-                    foreach (Type t in binder.GetContributingTypes(type)) {
-                        MemberInfo[] news = t.GetMember(&quot;__iter__&quot;);
-                        if (news.Length &gt; 0) {
-                            // type has a specific __i__ overload, we'll pick it up later
-                            return MemberGroup.EmptyGroup;
-                        }
-                    }
+            if (type == typeof(string)) {
+                // __iter__ is only exposed in 3.0
+                if (binder.Binder.Context.PythonOptions.Python30) {
+                    return GetInstanceOpsMethod(type, &quot;IterMethodForString&quot;);
+                }
+                return MemberGroup.EmptyGroup;
+            }
 
-                    // no special __iter__, use the default.
-                    return GetInstanceOpsMethod(type, &quot;IterMethod&quot;);
+            if (typeof(Bytes).IsAssignableFrom(type)) {
+                // __iter__ is only exposed in 3.0
+                if (binder.Binder.Context.PythonOptions.Python30) {
+                    return GetInstanceOpsMethod(type, &quot;IterMethodForBytes&quot;);
                 }
+                return MemberGroup.EmptyGroup;
             }
 
+            foreach (Type t in binder.GetContributingTypes(type)) {
+                MemberInfo[] news = t.GetMember(&quot;__iter__&quot;);
+                if (news.Length &gt; 0) {
+                    // type has a specific __iter__ overload, we'll pick it up later
+                    return MemberGroup.EmptyGroup;
+                }
+            }
+
+            // no special __iter__, use the default.
+            if (typeof(System.Collections.Generic.IEnumerable&lt;&gt;).IsAssignableFrom(type)) {
+                return GetInstanceOpsMethod(type, &quot;IterMethodForGenericEnumerable&quot;);
+            } else if (typeof(System.Collections.IEnumerable).IsAssignableFrom(type)) {
+                return GetInstanceOpsMethod(type, &quot;IterMethodForEnumerable&quot;);
+            } else if (typeof(System.Collections.Generic.IEnumerator&lt;&gt;).IsAssignableFrom(type)) {
+                return GetInstanceOpsMethod(type, &quot;IterMethodForGenericEnumerator&quot;);
+            } else if (typeof(System.Collections.IEnumerator).IsAssignableFrom(type)) {
+                return GetInstanceOpsMethod(type, &quot;IterMethodForEnumerator&quot;);
+            }
+            
             return MemberGroup.EmptyGroup;
         }
 
@@ -1180,7 +1199,7 @@ namespace IronPython.Runtime.Types {
 
             public abstract MemberGroup/*!*/ GetMember(Type/*!*/ type, string/*!*/ name);
 
-            protected PythonBinder/*!*/ Binder {
+            public PythonBinder/*!*/ Binder {
                 get {
                     return _binder;
                 }</diff>
      <filename>Merlin/Main/Languages/IronPython/IronPython/Runtime/Types/TypeInfo.cs</filename>
    </modified>
    <modified>
      <diff>@@ -135,59 +135,6 @@ namespace IronPython.Runtime {
 
         #endregion
 
-        class XRangeIterator : IEnumerator, IEnumerator&lt;int&gt; {
-            private XRange _xrange;
-            private int _value;
-            private int _position;
-
-            public XRangeIterator(XRange xrange) {
-                _xrange = xrange;
-                _value = xrange._start - xrange._step; // this could cause overflow, fine
-                _position = 0;
-            }
-
-            public object Current {
-                get {
-                    return ScriptingRuntimeHelpers.Int32ToObject(_value);
-                }
-            }
-
-            public bool MoveNext() {
-                if (_position &gt;= _xrange._length) {
-                    return false;
-                }
-
-                _position++;
-                _value = _value + _xrange._step;
-                return true;
-            }
-
-            public void Reset() {
-                _value = _xrange._start - _xrange._step;
-                _position = 0;
-            }
-
-            #region IEnumerator&lt;int&gt; Members
-
-            int IEnumerator&lt;int&gt;.Current {
-                get { return _value; }
-            }
-
-            #endregion
-
-            #region IDisposable Members
-
-            public void Dispose() {
-                Dispose(true);
-                GC.SuppressFinalize(this);
-            }
-
-            protected virtual void Dispose(bool notFinalizing) {
-            }
-
-            #endregion
-        }
-
         #region ICodeFormattable Members
 
         public string/*!*/ __repr__(CodeContext/*!*/ context) {
@@ -226,4 +173,62 @@ namespace IronPython.Runtime {
 
         #endregion
     }
+
+    [PythonType(&quot;rangeiterator&quot;)]
+    public sealed class XRangeIterator : IEnumerable, IEnumerator, IEnumerator&lt;int&gt; {
+        private XRange _xrange;
+        private int _value;
+        private int _position;
+
+        public XRangeIterator(XRange xrange) {
+            _xrange = xrange;
+            _value = xrange.Start - xrange.Step; // this could cause overflow, fine
+            _position = 0;
+        }
+
+        public object Current {
+            get {
+                return ScriptingRuntimeHelpers.Int32ToObject(_value);
+            }
+        }
+
+        public bool MoveNext() {
+            if (_position &gt;= _xrange.__len__()) {
+                return false;
+            }
+
+            _position++;
+            _value = _value + _xrange.Step;
+            return true;
+        }
+
+        public void Reset() {
+            _value = _xrange.Start - _xrange.Step;
+            _position = 0;
+        }
+
+        #region IEnumerator&lt;int&gt; Members
+
+        int IEnumerator&lt;int&gt;.Current {
+            get { return _value; }
+        }
+
+        #endregion
+
+        #region IDisposable Members
+
+        public void Dispose() {
+            GC.SuppressFinalize(this);
+        }
+
+        #endregion
+
+        #region IEnumerable Members
+
+        public IEnumerator GetEnumerator() {
+            return this;
+        }
+
+        #endregion
+    }
 }</diff>
      <filename>Merlin/Main/Languages/IronPython/IronPython/Runtime/XRange.cs</filename>
    </modified>
    <modified>
      <diff></diff>
      <filename>Merlin/Main/Languages/IronPython/IronPythonConsole/IronPythonConsole.Build.csproj</filename>
    </modified>
    <modified>
      <diff>@@ -22,6 +22,7 @@
     &lt;SignedDir Condition=&quot;'$(SignAssembly)' == 'true'&quot;&gt;Signed&lt;/SignedDir&gt;
     &lt;SignedDir Condition=&quot;$(SignAssembly) != true&quot;&gt;Unsigned&lt;/SignedDir&gt;
     &lt;DelaySign&gt;true&lt;/DelaySign&gt;
+    &lt;PlatformTarget&gt;x86&lt;/PlatformTarget&gt;
   &lt;/PropertyGroup&gt;
   &lt;PropertyGroup Condition=&quot; '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' &quot;&gt;
     &lt;DebugSymbols&gt;true&lt;/DebugSymbols&gt;</diff>
      <filename>Merlin/Main/Languages/IronPython/IronPythonConsole/IronPythonConsole.csproj</filename>
    </modified>
    <modified>
      <diff>@@ -1111,4 +1111,21 @@ namespace IronPythonTest {
             return result;
         }
     }
+
+    public class FamilyOrAssembly {
+        private object _value;
+        
+        protected internal int Method() {
+            return 42;
+        }
+
+        protected internal object Property {
+            get {
+                return _value;
+            }
+            set {
+                _value = value;
+            }
+        }
+    }
 }</diff>
      <filename>Merlin/Main/Languages/IronPython/IronPythonTest/InheritTest.cs</filename>
    </modified>
    <modified>
      <diff></diff>
      <filename>Merlin/Main/Languages/IronPython/IronPythonWindow/IronPythonWindow.Build.csproj</filename>
    </modified>
    <modified>
      <diff>@@ -2,7 +2,7 @@
   &lt;PropertyGroup&gt;
     &lt;Configuration Condition=&quot; '$(Configuration)' == '' &quot;&gt;Debug&lt;/Configuration&gt;
     &lt;Platform Condition=&quot; '$(Platform)' == '' &quot;&gt;AnyCPU&lt;/Platform&gt;
-    &lt;ProductVersion&gt;9.0.21022&lt;/ProductVersion&gt;
+    &lt;ProductVersion&gt;9.0.30729&lt;/ProductVersion&gt;
     &lt;SchemaVersion&gt;2.0&lt;/SchemaVersion&gt;
     &lt;ProjectGuid&gt;{81DA19C7-4FEC-47E7-981B-D9310D549F95}&lt;/ProjectGuid&gt;
     &lt;OutputType&gt;WinExe&lt;/OutputType&gt;
@@ -39,6 +39,7 @@
     &lt;SignAssembly Condition=&quot;'$(SignAssembly)' == '' And Exists('$(AssemblyOriginatorKeyFile)')&quot;&gt;true&lt;/SignAssembly&gt;
     &lt;SignedSym Condition=&quot;'$(SignAssembly)' == 'true'&quot;&gt;SIGNED&lt;/SignedSym&gt;
     &lt;DelaySign&gt;true&lt;/DelaySign&gt;
+    &lt;PlatformTarget&gt;x86&lt;/PlatformTarget&gt;
   &lt;/PropertyGroup&gt;
   &lt;PropertyGroup Condition=&quot; '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' &quot;&gt;
     &lt;DebugSymbols&gt;true&lt;/DebugSymbols&gt;
@@ -110,4 +111,4 @@
   &lt;Target Name=&quot;AfterBuild&quot;&gt;
   &lt;/Target&gt;
   --&gt;
-&lt;/Project&gt;
+&lt;/Project&gt;
\ No newline at end of file</diff>
      <filename>Merlin/Main/Languages/IronPython/IronPythonWindow/IronPythonWindow.csproj</filename>
    </modified>
    <modified>
      <diff>@@ -76,7 +76,7 @@ namespace IronRuby.Tests {
 
             runtimeSetup.DebugMode = _driver.IsDebug;
             runtimeSetup.PrivateBinding = testCase.Options.PrivateBinding;
-            languageSetup.Options[&quot;InterpretedMode&quot;] = _driver.Interpret;
+            languageSetup.Options[&quot;NoAdaptiveCompilation&quot;] = _driver.NoAdaptiveCompilation;
             languageSetup.Options[&quot;Verbosity&quot;] = 2;
             languageSetup.Options[&quot;Compatibility&quot;] = testCase.Options.Compatibility;
 
@@ -101,7 +101,7 @@ namespace IronRuby.Tests {
         private static bool _runTokenizerDriver;
         private static bool _displayList;
         private static bool _partialTrust;
-        private static bool _interpret;
+        private static bool _noAdaptiveCompilation;
         private static bool _runPython = true;
 
         public TestRuntime TestRuntime {
@@ -132,8 +132,8 @@ namespace IronRuby.Tests {
             get { return _partialTrust; }
         }
 
-        public bool Interpret {
-            get { return _interpret; }
+        public bool NoAdaptiveCompilation {
+            get { return _noAdaptiveCompilation; }
         }
 
         public bool RunPython {
@@ -144,7 +144,7 @@ namespace IronRuby.Tests {
             if (args.Contains(&quot;/help&quot;) || args.Contains(&quot;-?&quot;) || args.Contains(&quot;/?&quot;) || args.Contains(&quot;-help&quot;)) {
                 Console.WriteLine(&quot;Verbose                      : /verbose&quot;);
                 Console.WriteLine(&quot;Partial trust                : /partial&quot;);
-                Console.WriteLine(&quot;Interpret                    : /interpret&quot;);
+                Console.WriteLine(&quot;No adaptive compilation      : /noadaptive&quot;);
                 Console.WriteLine(&quot;Save to assemblies           : /save&quot;);
                 Console.WriteLine(&quot;Debug Mode                   : /debug&quot;);
                 Console.WriteLine(&quot;Disable Python interop tests : /py-&quot;);
@@ -185,14 +185,14 @@ namespace IronRuby.Tests {
                 _partialTrust = true;
             }
 
-            if (args.Contains(&quot;-X:Interpret&quot;)) {
-                args.Remove(&quot;-X:Interpret&quot;);
-                _interpret = true;
+            if (args.Contains(&quot;-X:NoAdaptiveCompilation&quot;)) {
+                args.Remove(&quot;-X:NoAdaptiveCompilation&quot;);
+                _noAdaptiveCompilation = true;
             }
 
-            if (args.Contains(&quot;/interpret&quot;)) {
-                args.Remove(&quot;/interpret&quot;);
-                _interpret = true;
+            if (args.Contains(&quot;/noadaptive&quot;)) {
+                args.Remove(&quot;/noadaptive&quot;);
+                _noAdaptiveCompilation = true;
             }
 
             if (args.Contains(&quot;/py-&quot;)) {</diff>
      <filename>Merlin/Main/Languages/Ruby/IronRuby.Tests/Driver.cs</filename>
    </modified>
    <modified>
      <diff>@@ -103,9 +103,7 @@ namespace IronRuby.Tests {
                 Strings9,
                 ToSConversion1,
                 ToSConversion2,
-                ToSConversionClr1,
-                HashClr1,
-                HashClr2,
+                ClrToString1,
                 Inspect1,
                 Inspect2,
 
@@ -397,6 +395,10 @@ namespace IronRuby.Tests {
                 ClrOperators1,
                 ClrOperators2,
                 ClrConversions1,
+                ClrHashEquals1,
+                ClrHashEquals2,
+                ClrHashEquals3,
+                ClrHashEquals4,
                 Scenario_RubyEngine1,
                 Scenario_RubyInteractive1,
                 Scenario_RubyInteractive2,</diff>
      <filename>Merlin/Main/Languages/Ruby/IronRuby.Tests/RubyTests.cs</filename>
    </modified>
    <modified>
      <diff>@@ -18,12 +18,8 @@ using System;
 
 namespace IronRuby.Tests {
     public partial class Tests {
-        private bool PreciseTraces {
-            get { return Runtime.Setup.DebugMode /*|| _driver.Interpret*/; }
-        }
-
         private bool PreciseSinglePassTraces {
-            get { return true; }
+            get { return Runtime.Setup.DebugMode || !_driver.NoAdaptiveCompilation; }
         }
 
         public void Backtrace1() {</diff>
      <filename>Merlin/Main/Languages/Ruby/IronRuby.Tests/Runtime/BacktraceTests.cs</filename>
    </modified>
    <modified>
      <diff>@@ -23,6 +23,7 @@ using IronRuby.Runtime;
 using IronRuby.Builtins;
 using Microsoft.Scripting.Math;
 using System.Runtime.InteropServices;
+using System.Runtime.CompilerServices;
 
 namespace InteropTests.Generics1 {
     public class C {
@@ -1561,6 +1562,192 @@ p E.new.virtual_method
 &quot;);
         }
 
+
+
+        public class ClassWithToStringHashEquals1 {
+            public override string ToString() {
+                return &quot;hello&quot;;
+            }
+
+            public override int GetHashCode() {
+                return 1234;
+            }
+
+            public int Foo() {
+                return 10;
+            }
+
+            public int Field = 11;
+
+            public override bool Equals(object obj) {
+                return obj is int &amp;&amp; (int)obj == 0;
+            }
+        }
+
+        public void ClrToString1() {
+            Engine.Runtime.Globals.SetVariable(&quot;B&quot;, Context.GetClass(typeof(ClassWithToStringHashEquals1)));
+
+            var objs = Engine.Execute&lt;RubyArray&gt;(@&quot;
+class C
+  def to_s
+    '123'
+  end
+end
+
+class D
+end
+
+class E &lt; B
+end
+
+class F &lt; B
+  def to_s
+    'abc'
+  end
+end
+
+[C.new, D.new, E.new, E.new.to_s, F.new]
+&quot;);
+
+            Assert(objs[0].ToString() == &quot;123&quot;);
+
+            string s = objs[1].ToString();
+            Assert(s.StartsWith(&quot;#&lt;D:0x&quot;) &amp;&amp; s.EndsWith(&quot;&gt;&quot;));
+
+            s = objs[2].ToString();
+            Assert(s == &quot;hello&quot;);
+
+            s = objs[3].ToString();
+            Assert(s == &quot;hello&quot;);
+
+            //TODO:
+            //s = objs[4].ToString();
+            //Assert(s == &quot;abc&quot;);
+
+            var range = new Range(1, 2, true);
+            Assert(range.ToString() == &quot;1...2&quot;);
+
+            var regex = new RubyRegex(&quot;hello&quot;, RubyRegexOptions.IgnoreCase | RubyRegexOptions.Multiline);
+            Assert(regex.ToString() == &quot;(?mi-x:hello)&quot;);
+        }
+
+        public void ClrHashEquals1() {
+            Test_HashClr(&quot;get_hash_code&quot;, &quot;equals&quot;);
+        }
+
+        public void ClrHashEquals2() {
+            Test_HashClr(&quot;GetHashCode&quot;, &quot;Equals&quot;);
+        }
+
+        public void ClrHashEquals3() {
+            Test_HashClr(&quot;hash&quot;, &quot;eql?&quot;);
+        }
+
+        private void Test_HashClr(string/*!*/ hashMethodName, string/*!*/ equalsMethodName) {
+            Engine.Runtime.Globals.SetVariable(&quot;B&quot;, Context.GetClass(typeof(ClassWithToStringHashEquals1)));
+
+            var objs = Engine.Execute&lt;RubyArray&gt;(String.Format(@&quot;
+class C
+  def {0}
+    789
+  end
+
+  def {1}(other)
+    other == 1
+  end
+end
+
+class D
+end
+
+class E &lt; B
+end
+
+class F &lt; B
+  def {0}
+    1000
+  end
+
+  def {1}(other)
+    other == 2
+  end
+end
+
+[C.new, D.new, E.new, F.new, E.new.{0}, E.new.{1}(0)]
+&quot;, hashMethodName, equalsMethodName));
+
+            object c = objs[0], d = objs[1], e = objs[2], f = objs[3], eHash = objs[4], eEquals = objs[5];
+
+            int h = c.GetHashCode();
+            Assert(h == 789);
+            Assert(objs[0].Equals(1));
+
+            h = d.GetHashCode();
+            Assert(h == RuntimeHelpers.GetHashCode(objs[1]));
+            Assert(d.Equals(d) &amp;&amp; !d.Equals(1));
+
+            h = e.GetHashCode();
+            Assert(h == 1234);
+            Assert(e.Equals(0));
+
+            h = f.GetHashCode();
+            Assert(h == 1000);
+            Assert(f.Equals(2));
+
+            Assert((int)eHash == 1234);
+            Assert((bool)eEquals);
+        }
+
+        public void ClrHashEquals4() {
+            var e = new RubyObject(Context.ObjectClass);
+            int h;
+
+            Engine.Runtime.Globals.SetVariable(&quot;B&quot;, Context.GetClass(typeof(ClassWithToStringHashEquals1)));
+            Engine.Runtime.Globals.SetVariable(&quot;Empty&quot;, e);
+
+            // removing GetHashCode doesn't cause infinite recursion (Kernel#hash call doesn't dynamically dispatch to GHC):
+            h = Engine.Execute&lt;int&gt;(@&quot;
+class Object
+  remove_method :GetHashCode
+end
+
+Empty.hash
+&quot;);
+            Assert(h == RuntimeHelpers.GetHashCode(e));
+
+            // Z#eql? calls Kernel#== which should not do virtual dynamic dispatch to Equals since that would call eql? again.
+            bool b = Engine.Execute&lt;bool&gt;(@&quot;
+class Z
+  def eql?(other)
+    self == other
+  end
+end
+
+Z.eql?(1)
+&quot;);
+            Assert(!b);
+
+            // detached method groups should be considered user-defined methods:
+            var objs = Engine.Execute&lt;RubyArray&gt;(@&quot;
+class C &lt; B
+  alias hash foo
+end
+
+class D &lt; B
+  define_method(:hash, instance_method(:field))
+end
+
+[C.new, D.new]
+&quot;);
+            object c = objs[0], d = objs[1];
+
+            h = c.GetHashCode();
+            Assert(h == 10);
+            
+            h = d.GetHashCode();
+            Assert(h == 11);
+        }
+
         #endregion
 
         #region Constructors</diff>
      <filename>Merlin/Main/Languages/Ruby/IronRuby.Tests/Runtime/ClrTests.cs</filename>
    </modified>
    <modified>
      <diff>@@ -242,119 +242,7 @@ NULL2
 SUB
 &quot;);
         }
-
-        public class ClassWithToStringHashEquals1 {
-            public override string ToString() {
-                return &quot;hello&quot;;
-            }
-
-            public override int GetHashCode() {
-                return 1234;
-            }
-
-            public override bool Equals(object obj) {
-                return true;
-            }
-        }
-
-        public void ToSConversionClr1() {
-            Engine.Runtime.Globals.SetVariable(&quot;B&quot;, Context.GetClass(typeof(ClassWithToStringHashEquals1)));
-
-            var objs = Engine.Execute&lt;RubyArray&gt;(@&quot;
-class C
-  def to_s
-    '123'
-  end
-end
-
-class D
-end
-
-class E &lt; B
-end
-
-class F &lt; B
-  def to_s
-    'abc'
-  end
-end
-
-[C.new, D.new, E.new, E.new.to_s, F.new]
-&quot;);
-
-            Assert(objs[0].ToString() == &quot;123&quot;);
-
-            string s = objs[1].ToString();
-            Assert(s.StartsWith(&quot;#&lt;D:0x&quot;) &amp;&amp; s.EndsWith(&quot;&gt;&quot;));
-
-            s = objs[2].ToString();
-            Assert(s == &quot;hello&quot;);
-
-            s = objs[3].ToString();
-            Assert(s == &quot;hello&quot;);
-
-            //TODO:
-            //s = objs[4].ToString();
-            //Assert(s == &quot;abc&quot;);
-
-            var range = new Range(1, 2, true);
-            Assert(range.ToString() == &quot;1...2&quot;);
-
-            var regex = new RubyRegex(&quot;hello&quot;, RubyRegexOptions.IgnoreCase | RubyRegexOptions.Multiline);
-            Assert(regex.ToString() == &quot;(?mi-x:hello)&quot;);
-        }
-
-        public void HashClr1() {
-            // TODO: 
-            // Test_HashClr(&quot;get_hash_code&quot;);
-        }
-
-        public void HashClr2() {
-            // TODO:  
-            // Test_HashClr(&quot;hash&quot;);
-        }
-
-        private void Test_HashClr(string/*!*/ methodName) {
-            Engine.Runtime.Globals.SetVariable(&quot;B&quot;, Context.GetClass(typeof(ClassWithToStringHashEquals1)));
-
-            var objs = Engine.Execute&lt;RubyArray&gt;(String.Format(@&quot;
-class C
-  def {0}
-    789
-  end
-end
-
-class D
-end
-
-class E &lt; B
-end
-
-class F &lt; B
-  def {0}
-    1000
-  end
-end
-
-[C.new, D.new, E.new, E.new.{0}, F.new]
-&quot;, methodName));
-
-            int h = objs[0].GetHashCode();
-            Assert(h == 789);
-
-            h = objs[1].GetHashCode();
-            Assert(h == RuntimeHelpers.GetHashCode(objs[1]));
-
-            h = objs[2].GetHashCode();
-            Assert(h == 1234);
-
-            h = (int)objs[3];
-            Assert(h == 1234);
-
-            h = objs[4].GetHashCode();
-            Assert(h == 1000);
-        }
-
+        
         [Options(Compatibility = RubyCompatibility.Ruby18)]
         private void Inspect1() {
             const char sq = '\'';</diff>
      <filename>Merlin/Main/Languages/Ruby/IronRuby.Tests/Runtime/StringTests.cs</filename>
    </modified>
    <modified>
      <diff>@@ -59,9 +59,11 @@ namespace IronRuby.Builtins {
             var site = toAryToInt.GetSite(CompositeConversionAction.Make(toAryToInt.Context, CompositeConversion.ToAryToInt));
             var union = site.Target(site, arrayOrSize);
 
+
             if (union.First != null) {
                 // block ignored
-                return CreateArray(union.First);
+                // TODO: implement copy-on-write
+                return new RubyArray(union.First);
             } else if (block != null) {
                 return CreateArray(block, union.Second);
             } else {
@@ -89,10 +91,6 @@ namespace IronRuby.Builtins {
             }
         }
 
-        private static RubyArray/*!*/ CreateArray(IList/*!*/ other) {
-            return Reinitialize(new RubyArray(other.Count), other);
-        }
-
         private static RubyArray/*!*/ Reinitialize(RubyArray/*!*/ self, IList/*!*/ other) {
             Assert.NotNull(self, other);
             if (other != self) {</diff>
      <filename>Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Builtins/ArrayOps.cs</filename>
    </modified>
    <modified>
      <diff>@@ -994,19 +994,6 @@ namespace IronRuby.Builtins {
 
         #region ==, ===, =~, eql?, equal?, hash
 
-        [RubyMethod(&quot;==&quot;)]
-        [RubyMethod(&quot;eql?&quot;)]
-        public static bool ValueEquals(IRubyObject self, object other) {
-            return object.ReferenceEquals(self, other);
-        }
-
-        [RubyMethod(&quot;==&quot;)]
-        [RubyMethod(&quot;eql?&quot;)]
-        public static bool ValueEquals(object self, object other) {
-            Debug.Assert(self == null || !(self is IRubyObject));
-            return RubyUtils.ValueEquals(self, other);
-        }
-
         [RubyMethod(&quot;=~&quot;)]
         public static bool Match(object self, object other) {
             // Default implementation of match that is overridden in descendents (notably String and Regexp)
@@ -1015,23 +1002,34 @@ namespace IronRuby.Builtins {
 
         // calls == by default
         [RubyMethod(&quot;===&quot;)]
-        public static bool HashEquals(BinaryOpStorage/*!*/ equals, object self, object other) {
+        public static bool CaseEquals(BinaryOpStorage/*!*/ equals, object self, object other) {
             return Protocols.IsEqual(equals, self, other);
         }
 
+        [RubyMethod(&quot;==&quot;)]
+        [RubyMethod(&quot;eql?&quot;)]
+        public static bool ValueEquals([NotNull]IRubyObject/*!*/ self, object other) {
+            return self.BaseEquals(other);
+        }
+
+        [RubyMethod(&quot;==&quot;)]
+        [RubyMethod(&quot;eql?&quot;)]
+        public static bool ValueEquals(object self, object other) {
+            return Object.Equals(self, other);
+        }
+
         [RubyMethod(&quot;hash&quot;)]
-        public static int Hash(IRubyObject self) {
-            return self == null ? RubyUtils.NilObjectId : RuntimeHelpers.GetHashCode(self);
+        public static int Hash([NotNull]IRubyObject/*!*/ self) {
+            return self.BaseGetHashCode();
         }
 
         [RubyMethod(&quot;hash&quot;)]
         public static int Hash(object self) {
-            Debug.Assert(self == null || !(self is IRubyObject));
-            return RubyUtils.GetHashCode(self);
+            return self == null ? RubyUtils.NilObjectId : self.GetHashCode();
         }
 
         [RubyMethod(&quot;equal?&quot;)]
-        public static bool Equal(object self, object other) {
+        public static bool IsEqual(object self, object other) {
             // Comparing object IDs is (potentially) expensive because it forces us
             // to generate InstanceData and a new object ID
             //return GetObjectId(self) == GetObjectId(other);</diff>
      <filename>Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Builtins/KernelOps.cs</filename>
    </modified>
    <modified>
      <diff>@@ -237,31 +237,35 @@ namespace IronRuby.Builtins {
         }
 
         [RubyMethod(&quot;-&quot;)]
-        public static RubyArray/*!*/ Difference(RubyContext/*!*/ context, IList/*!*/ self, [DefaultProtocol, NotNull]IList/*!*/ other) {
-            // MRI follows hashing semantics here, so doesn't actually call eql?/hash for Fixnum/Symbol
-            IEqualityComparer&lt;object&gt; comparer = context.EqualityComparer;
-            RubyArray result = new RubyArray();
+        public static RubyArray/*!*/ Difference(UnaryOpStorage/*!*/ hashStorage, BinaryOpStorage/*!*/ eqlStorage, 
+            RubyContext/*!*/ context, IList/*!*/ self, [DefaultProtocol, NotNull]IList/*!*/ other) {
 
-            // TODO: optimize this
-            foreach (object selfElement in self) {
-                bool found = false;
-                foreach (object otherElement in other) {
-                    bool sameHashcode = comparer.GetHashCode(selfElement) == comparer.GetHashCode(otherElement);
-                    bool isEql = comparer.Equals(selfElement, otherElement);
-                    if (sameHashcode &amp;&amp; isEql) {
-                        found = true;
-                        break;
-                    }
-                }
+            RubyArray result = new RubyArray();
+            
+            // cost: (|self| + |other|) * (hash + eql) + dict
+            var remove = new Dictionary&lt;object, bool&gt;(new EqualityComparer(hashStorage, eqlStorage));
+            foreach (var item in other) {
+                remove[item] = true;
+            }
 
-                if (!found) {
-                    result.Add(selfElement);
+            foreach (var item in self) {
+                if (!remove.ContainsKey(item)) {
+                    result.Add(item);
                 }
             }
 
             return result;
         }
 
+        internal static int IndexOf(CallSite&lt;Func&lt;CallSite, object, object, object&gt;&gt;/*!*/ equalitySite, IList/*!*/ self, object item) {
+            for (int i = 0; i &lt; self.Count; i++) {
+                if (Protocols.IsTrue(equalitySite.Target(equalitySite, item, self[i]))) {
+                    return i;
+                }
+            }
+            return -1;
+        }
+
         #endregion
 
         #region ==, &lt;=&gt;, eql?, hash
@@ -329,13 +333,13 @@ namespace IronRuby.Builtins {
         }
 
         [RubyMethod(&quot;eql?&quot;)]
-        public static bool HashEquals(IList/*!*/ self, object other) {
-            return RubyArray.Equals(self, other);
+        public static bool HashEquals(BinaryOpStorage/*!*/ eqlStorage, IList/*!*/ self, object other) {
+            return RubyArray.Equals(eqlStorage, self, other);
         }
 
         [RubyMethod(&quot;hash&quot;)]
-        public static int GetHashCode(IList/*!*/ self) {
-            return RubyArray.GetHashCode(self);
+        public static int GetHashCode(UnaryOpStorage/*!*/ hashStorage, ConversionStorage&lt;int&gt;/*!*/ fixnumCast, IList/*!*/ self) {
+            return RubyArray.GetHashCode(hashStorage, fixnumCast, self);
         }
 
         #endregion</diff>
      <filename>Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Extensions/IListOps.cs</filename>
    </modified>
    <modified>
      <diff>@@ -2551,7 +2551,7 @@ namespace IronRuby.Builtins {
             );
             
             module.DefineLibraryMethod(&quot;===&quot;, 0x51, 
-                new System.Func&lt;IronRuby.Runtime.BinaryOpStorage, System.Object, System.Object, System.Boolean&gt;(IronRuby.Builtins.KernelOps.HashEquals)
+                new System.Func&lt;IronRuby.Runtime.BinaryOpStorage, System.Object, System.Object, System.Boolean&gt;(IronRuby.Builtins.KernelOps.CaseEquals)
             );
             
             module.DefineLibraryMethod(&quot;abort&quot;, 0x52, 
@@ -2617,7 +2617,7 @@ namespace IronRuby.Builtins {
             );
             
             module.DefineLibraryMethod(&quot;equal?&quot;, 0x51, 
-                new System.Func&lt;System.Object, System.Object, System.Boolean&gt;(IronRuby.Builtins.KernelOps.Equal)
+                new System.Func&lt;System.Object, System.Object, System.Boolean&gt;(IronRuby.Builtins.KernelOps.IsEqual)
             );
             
             module.DefineLibraryMethod(&quot;eval&quot;, 0x52, 
@@ -5135,7 +5135,7 @@ namespace IronRuby.Builtins {
         
         private static void LoadSystem__Collections__IList_Instance(IronRuby.Builtins.RubyModule/*!*/ module) {
             module.DefineLibraryMethod(&quot;-&quot;, 0x51, 
-                new System.Func&lt;IronRuby.Runtime.RubyContext, System.Collections.IList, System.Collections.IList, IronRuby.Builtins.RubyArray&gt;(IronRuby.Builtins.IListOps.Difference)
+                new System.Func&lt;IronRuby.Runtime.UnaryOpStorage, IronRuby.Runtime.BinaryOpStorage, IronRuby.Runtime.RubyContext, System.Collections.IList, System.Collections.IList, IronRuby.Builtins.RubyArray&gt;(IronRuby.Builtins.IListOps.Difference)
             );
             
             module.DefineLibraryMethod(&quot;&amp;&quot;, 0x51, 
@@ -5235,7 +5235,7 @@ namespace IronRuby.Builtins {
             );
             
             module.DefineLibraryMethod(&quot;eql?&quot;, 0x51, 
-                new System.Func&lt;System.Collections.IList, System.Object, System.Boolean&gt;(IronRuby.Builtins.IListOps.HashEquals)
+                new System.Func&lt;IronRuby.Runtime.BinaryOpStorage, System.Collections.IList, System.Object, System.Boolean&gt;(IronRuby.Builtins.IListOps.HashEquals)
             );
             
             module.DefineLibraryMethod(&quot;fetch&quot;, 0x51, 
@@ -5267,7 +5267,7 @@ namespace IronRuby.Builtins {
             );
             
             module.DefineLibraryMethod(&quot;hash&quot;, 0x51, 
-                new System.Func&lt;System.Collections.IList, System.Int32&gt;(IronRuby.Builtins.IListOps.GetHashCode)
+                new System.Func&lt;IronRuby.Runtime.UnaryOpStorage, IronRuby.Runtime.ConversionStorage&lt;System.Int32&gt;, System.Collections.IList, System.Int32&gt;(IronRuby.Builtins.IListOps.GetHashCode)
             );
             
             module.DefineLibraryMethod(&quot;include?&quot;, 0x51, </diff>
      <filename>Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Initializers.Generated.cs</filename>
    </modified>
    <modified>
      <diff>@@ -20,6 +20,7 @@ using System.Diagnostics;
 using IronRuby.Runtime;
 using Microsoft.Scripting;
 using Microsoft.Scripting.Utils;
+using IronRuby.Runtime.Calls;
 
 namespace IronRuby.Builtins {
 
@@ -91,7 +92,7 @@ namespace IronRuby.Builtins {
         [MultiRuntimeAware]
         private static RubyUtils.RecursionTracker _HashTracker = new RubyUtils.RecursionTracker();
 
-        public static int GetHashCode(IList/*!*/ self) {
+        public static int GetHashCode(UnaryOpStorage/*!*/ hashStorage, ConversionStorage&lt;int&gt;/*!*/ fixnumCast, IList/*!*/ self) {
             int hash = self.Count;
             using (IDisposable handle = _HashTracker.TrackObject(self)) {
                 if (handle == null) {
@@ -99,9 +100,10 @@ namespace IronRuby.Builtins {
                     return 0;
                 }
 
-                foreach (object obj in self) {
-                    hash &lt;&lt;= 1;
-                    hash ^= RubyUtils.GetHashCode(obj);
+                var hashSite = hashStorage.GetCallSite(&quot;hash&quot;);
+                var toIntSite = fixnumCast.GetSite(ConvertToFixnumAction.Make(fixnumCast.Context));
+                foreach (object item in self) {
+                    hash = (hash &lt;&lt; 1) ^ toIntSite.Target(toIntSite, hashSite.Target(hashSite, item));
                 }
             }
             return hash;
@@ -110,24 +112,25 @@ namespace IronRuby.Builtins {
         [MultiRuntimeAware]
         private static RubyUtils.RecursionTracker _EqualsTracker = new RubyUtils.RecursionTracker();
 
-        public static bool Equals(IList/*!*/ self, object obj) {
-            if (object.ReferenceEquals(self, obj)) {
+        public static bool Equals(BinaryOpStorage/*!*/ eqlStorage, IList/*!*/ self, object obj) {
+            if (ReferenceEquals(self, obj)) {
                 return true;
             }
 
+            IList other = obj as IList;
+            if (other == null || self.Count != other.Count) {
+                return false;
+            }
+
             using (IDisposable handle = _EqualsTracker.TrackObject(self)) {
                 if (handle == null) {
                     // hashing of recursive array
                     return false;
                 }
 
-                IList other = obj as IList;
-                if (other == null || self.Count != other.Count) {
-                    return false;
-                }
-
-                for (int i = 0; i &lt; self.Count; ++i) {
-                    if (!RubyUtils.ValueEquals(self[i], other[i])) {
+                var site = eqlStorage.GetCallSite(&quot;eql?&quot;);
+                for (int i = 0; i &lt; self.Count; i++) {
+                    if (!Protocols.IsTrue(site.Target(site, self[i], other[i]))) {
                         return false;
                     }
                 }</diff>
      <filename>Merlin/Main/Languages/Ruby/Ruby/Builtins/RubyArray.cs</filename>
    </modified>
    <modified>
      <diff>@@ -115,13 +115,20 @@ namespace IronRuby.Builtins {
             get { return RubyUtils.GetCallSite(ref _stringConversionSite, ConvertToSAction.Make(Context)); } 
         }
 
-        public CallSite&lt;Func&lt;CallSite, object, object, object&gt;&gt;/*!*/ EqlSite {
-            get { return RubyUtils.GetCallSite(ref _eqlSite, Context, &quot;==&quot;, 1); }
+        public CallSite&lt;Func&lt;CallSite, object, object, object&gt;&gt;/*!*/ EqualsSite {
+            get { 
+                return RubyUtils.GetCallSite(ref _eqlSite, Context, &quot;Equals&quot;,
+                    new RubyCallSignature(1, RubyCallFlags.HasImplicitSelf | RubyCallFlags.IsVirtualCall)
+                );
+            }
         }
 
-        public CallSite&lt;Func&lt;CallSite, object, object&gt;&gt;/*!*/ HashSite {
-            get { return RubyUtils.GetCallSite(ref _hashSite, Context, &quot;hash&quot;, 0); }
-
+        internal CallSite&lt;Func&lt;CallSite, object, object&gt;&gt;/*!*/ GetHashCodeSite {
+            get { 
+                return RubyUtils.GetCallSite(ref _hashSite, Context, &quot;GetHashCode&quot;, 
+                    new RubyCallSignature(0, RubyCallFlags.HasImplicitSelf | RubyCallFlags.IsVirtualCall)
+                );
+            }
         }
         
         // RubyClass, RubyClass -&gt; object
@@ -870,7 +877,8 @@ namespace IronRuby.Builtins {
                 return false;
             }
 
-            // if all CLR inherited members are to be returned we are done:
+            // If all CLR inherited members are to be returned we are done.
+            // (creates a detached info; used by Kernel#clr_member)
             if ((bindingFlags &amp; BindingFlags.DeclaredOnly) == 0) {
                 method = MakeGroup(initialMembers, initialVisibleMemberCount, specialNameOnly, true);
                 return true;
@@ -1117,7 +1125,9 @@ namespace IronRuby.Builtins {
         private bool TryGetClrField(Type/*!*/ type, BindingFlags bindingFlags, bool isWrite, string/*!*/ name, out RubyMemberInfo method) {
             FieldInfo fieldInfo = type.GetField(name, bindingFlags);
             if (fieldInfo != null &amp;&amp; IsVisible(fieldInfo) &amp;&amp; (!isWrite || IsWriteable(fieldInfo))) {
-                method = new RubyFieldInfo(fieldInfo, RubyMemberFlags.Public, this, isWrite);
+                // creates detached info if only declared members are requested (used by Kernel#clr_member):
+                bool createDetached = (bindingFlags &amp; BindingFlags.DeclaredOnly) != 0;
+                method = new RubyFieldInfo(fieldInfo, RubyMemberFlags.Public, this, isWrite, createDetached);
                 return true;
             }
 
@@ -1136,7 +1146,9 @@ namespace IronRuby.Builtins {
 
             EventInfo eventInfo = type.GetEvent(name, bindingFlags);
             if (eventInfo != null) {
-                method = new RubyEventInfo((EventTracker)MemberTracker.FromMemberInfo(eventInfo), RubyMemberFlags.Public, this);
+                // creates detached info if only declared members are requested (used by Kernel#clr_member):
+                bool createDetached = (bindingFlags &amp; BindingFlags.DeclaredOnly) != 0;
+                method = new RubyEventInfo((EventTracker)MemberTracker.FromMemberInfo(eventInfo), RubyMemberFlags.Public, this, createDetached);
                 return true;
             }
 </diff>
      <filename>Merlin/Main/Languages/Ruby/Ruby/Builtins/RubyClass.cs</filename>
    </modified>
    <modified>
      <diff>@@ -690,6 +690,14 @@ namespace IronRuby.Builtins {
             set { GetInstanceData().Tainted = value; }
         }
 
+        public int BaseGetHashCode() {
+            return base.GetHashCode();
+        }
+
+        public bool BaseEquals(object other) {
+            return base.Equals(other);
+        }
+
         #endregion
 
         #region Factories (thread-safe)
@@ -1212,10 +1220,12 @@ namespace IronRuby.Builtins {
                 // Alias preserves visibility and declaring module even though the alias is declared in a different module (e.g. subclass) =&gt;
                 // we can share method info (in fact, sharing is sound with Method#== semantics - it returns true on aliased methods).
                 // 
-                // We need to copy overload group since otherwise it might mess up caching if the alias is defined in a sub-module and 
+                // CLR members: 
+                // Detaches the member from its underlying type (by creating a copy).
+                // Note: We need to copy overload group since otherwise it might mess up caching if the alias is defined in a sub-module and 
                 // overloads of the same name that are not included in the overload group are inherited to this module.
                 // EnumerateMethods also relies on overload groups only representing cached CLR members.
-                if (method is RubyOverloadGroupInfo) {
+                if (!method.IsRubyMember) {
                     SetMethodNoEventNoLock(Context, newName, method.Copy(method.Flags, method.DeclaringModule));
                 } else {
                     SetMethodNoEventNoLock(Context, newName, method);
@@ -1227,7 +1237,8 @@ namespace IronRuby.Builtins {
 
         // Module#define_method:
         public void SetDefinedMethodNoEventNoLock(RubyContext/*!*/ callerContext, string/*!*/ name, RubyMemberInfo/*!*/ method, RubyMethodVisibility visibility) {
-            // copy method, Method#== returns false on defined methods and redefining the original method doesn't affect the new one:
+            // CLR members: Detaches the member from its underlying type (by creating a copy).
+            // Note: Method#== returns false on defined methods and redefining the original method doesn't affect the new one:
             SetMethodNoEventNoLock(callerContext, name, method.Copy((RubyMemberFlags)visibility, this));
         }
 
@@ -1238,6 +1249,7 @@ namespace IronRuby.Builtins {
             RubyMemberInfo existing;
             bool skipHidden = false;
             if (TryGetMethod(name, ref skipHidden, out existing)) {
+                // CLR members: Detaches the member from its underlying type (by creating a copy).
                 SetMethodNoEventNoLock(callerContext, name, method.Copy((RubyMemberFlags)visibility, this));
             } else {
                 SetMethodNoEventNoLock(callerContext, name, new SuperForwarderInfo((RubyMemberFlags)visibility, method.DeclaringModule, name));
@@ -1246,6 +1258,7 @@ namespace IronRuby.Builtins {
 
         // Module#module_function:
         public void SetModuleFunctionNoEventNoLock(RubyContext/*!*/ callerContext, string/*!*/ name, RubyMemberInfo/*!*/ method) {
+            // CLR members: Detaches the member from its underlying type (by creating a copy).
             // TODO: check for CLR instance members, it should be an error to call module_function on them:
             SingletonClass.SetMethodNoEventNoLock(callerContext, name, method.Copy(RubyMemberFlags.Public, SingletonClass));
         }
@@ -1401,6 +1414,10 @@ namespace IronRuby.Builtins {
                         SetMethodNoEventNoLock(Context, name, RubyMemberInfo.HiddenMethod);
                     }
                     return true;
+                } else if (TryGetClrMember(name, false, out method)) {
+                    Debug.Assert(!method.IsRemovable);
+                    SetMethodNoEventNoLock(Context, name, RubyMemberInfo.HiddenMethod);
+                    return true;
                 } else {
                     return false;
                 }
@@ -1617,14 +1634,31 @@ namespace IronRuby.Builtins {
                 return true;
             }
 
-            string mangled;
-            if (virtualLookup &amp;&amp; (mangled = RubyUtils.MangleName(name)) != name &amp;&amp; TryGetDefinedMethod(mangled, ref skipHidden, out method)) {
-                return true;
+            if (virtualLookup) {
+                string mangled;
+                if ((mangled = RubyUtils.MangleName(name)) != name &amp;&amp; TryGetDefinedMethod(mangled, ref skipHidden, out method)
+                    &amp;&amp; method.IsRubyMember) {
+                    return true;
+                }
+
+                // Special mappings:
+                // Do not map to Kernel#hash/eql? to prevent recursion in case Object.GetHashCode/Equals is removed.
+                if (this != Context.KernelModule) {
+                    if (name == &quot;GetHashCode&quot; &amp;&amp; TryGetDefinedMethod(&quot;hash&quot;, out method) &amp;&amp; method.IsRubyMember) {
+                        return true;
+                    } else if (name == &quot;Equals&quot; &amp;&amp; TryGetDefinedMethod(&quot;eql?&quot;, out method) &amp;&amp; method.IsRubyMember) {
+                        return true;
+                    }
+                }
             }
 
+            return !skipHidden &amp;&amp; TryGetClrMember(name, virtualLookup, out method);
+        }
+
+        private bool TryGetClrMember(string/*!*/ name, bool virtualLookup, out RubyMemberInfo method) {
             // Skip hidden CLR overloads.
             // Skip lookup on types that are not visible or interfaces.
-            if (!skipHidden &amp;&amp; _typeTracker != null &amp;&amp; !_typeTracker.Type.IsInterface) {
+            if (_typeTracker != null &amp;&amp; !_typeTracker.Type.IsInterface) {
                 // Note: Do not allow mangling for CLR virtual lookups - we want to match the overridden name exactly as is, 
                 // so that it corresponds to the base method call the override stub performs.
                 bool tryUnmangle = !virtualLookup &amp;&amp; (_restrictions &amp; ModuleRestrictions.NoNameMangling) == 0;
@@ -1635,6 +1669,7 @@ namespace IronRuby.Builtins {
                 }
             }
 
+            method = null;
             return false;
         }
 
@@ -1649,9 +1684,9 @@ namespace IronRuby.Builtins {
             InitializeMethodsNoLock();
 
             foreach (KeyValuePair&lt;string, RubyMemberInfo&gt; method in _methods) {
-                // Exclude overload groups as they only represent cached CLR method calls and these methods are enumerated below.
+                // Exclude attached CLR members as they only represent cached CLR method calls and these methods are enumerated below.
                 // Include undefined and CLR hidden members - the action uses them to hide the names.
-                if (!(method.Value is RubyOverloadGroupInfo)) {
+                if (method.Value.IsRubyMember) {
                     if (action(this, method.Key, method.Value)) {
                         return true;
                     }</diff>
      <filename>Merlin/Main/Languages/Ruby/Ruby/Builtins/RubyModule.cs</filename>
    </modified>
    <modified>
      <diff>@@ -51,24 +51,38 @@ namespace IronRuby.Builtins {
             return site.Target(site, this).ToString();
         }
 
-        public override bool Equals(object obj) {
-            if (object.ReferenceEquals(this, obj)) {
+        public override bool Equals(object other) {
+            if (ReferenceEquals(this, other)) {
                 // Handle this directly here. Otherwise it can cause infinite recurion when running
                 // script code below as the DLR code needs to call Equals for templating of rules
                 return true;
             }
+            
+            var site = _immediateClass.EqualsSite;
+            object equalsResult = site.Target(site, this, other);
+            if (equalsResult == RubyOps.ForwardToBase) {
+                return base.Equals(other);
+            }
+
+            return RubyOps.IsTrue(equalsResult);
+        }
 
-            var site = _immediateClass.EqlSite;
-            return Protocols.IsTrue(site.Target(site, this, obj));
+        public bool BaseEquals(object other) {
+            return base.Equals(other);
         }
 
         public override int GetHashCode() {
-            var site = _immediateClass.HashSite;
-            object hash = site.Target(site, this);
-            if (!((hash is int)  || (hash is Microsoft.Scripting.Math.BigInteger))) {
-                throw RubyExceptions.CreateUnexpectedTypeError(_immediateClass.Context, &quot;hash&quot;, &quot;Integer&quot;);
+            var site = _immediateClass.GetHashCodeSite;
+            object hashResult = site.Target(site, this);
+            if (ReferenceEquals(hashResult, RubyOps.ForwardToBase)) {
+                return base.GetHashCode();
             }
-            return hash.GetHashCode();
+
+            return Protocols.ToHashCode(hashResult);
+        }
+
+        public int BaseGetHashCode() {
+            return base.GetHashCode();
         }
 
         public MutableString/*!*/ ToMutableString() {</diff>
      <filename>Merlin/Main/Languages/Ruby/Ruby/Builtins/RubyObject.cs</filename>
    </modified>
    <modified>
      <diff>@@ -70,6 +70,14 @@ namespace IronRuby.Builtins {
             public void Freeze() {
                 GetInstanceData().Freeze();
             }
+
+            public int BaseGetHashCode() {
+                return base.GetHashCode();
+            }
+
+            public bool BaseEquals(object other) {
+                return base.Equals(other);
+            }
         }
     }
 #endif
@@ -77,9 +85,19 @@ namespace IronRuby.Builtins {
     public partial class Hash {
         public sealed partial class Subclass : Hash, IRubyObject {
             private RubyInstanceData _instanceData;
+            private RubyClass/*!*/ _immediateClass;
             
             [Emitted]
-            public RubyClass/*!*/ ImmediateClass { get; set; }
+            public RubyClass/*!*/ ImmediateClass {
+                get {
+                    return _immediateClass;
+                }
+                set {
+                    // once a singleton immediate class is set it can't be changed:
+                    Debug.Assert((_immediateClass == null || !_immediateClass.IsSingletonClass) &amp;&amp; value != null);
+                    _immediateClass = value;
+                }
+            }
 
             public RubyInstanceData/*!*/ GetInstanceData() {
                 return RubyOps.GetInstanceData(ref _instanceData);
@@ -101,14 +119,32 @@ namespace IronRuby.Builtins {
             public void Freeze() {
                 GetInstanceData().Freeze();
             }
+
+            public int BaseGetHashCode() {
+                return base.GetHashCode();
+            }
+
+            public bool BaseEquals(object other) {
+                return base.Equals(other);
+            }
         }
     }
     public partial class MatchData {
         public sealed partial class Subclass : MatchData, IRubyObject {
             private RubyInstanceData _instanceData;
+            private RubyClass/*!*/ _immediateClass;
             
             [Emitted]
-            public RubyClass/*!*/ ImmediateClass { get; set; }
+            public RubyClass/*!*/ ImmediateClass {
+                get {
+                    return _immediateClass;
+                }
+                set {
+                    // once a singleton immediate class is set it can't be changed:
+                    Debug.Assert((_immediateClass == null || !_immediateClass.IsSingletonClass) &amp;&amp; value != null);
+                    _immediateClass = value;
+                }
+            }
 
             public RubyInstanceData/*!*/ GetInstanceData() {
                 return RubyOps.GetInstanceData(ref _instanceData);
@@ -130,14 +166,32 @@ namespace IronRuby.Builtins {
             public void Freeze() {
                 GetInstanceData().Freeze();
             }
+
+            public int BaseGetHashCode() {
+                return base.GetHashCode();
+            }
+
+            public bool BaseEquals(object other) {
+                return base.Equals(other);
+            }
         }
     }
     public partial class Proc {
         public sealed partial class Subclass : Proc, IRubyObject {
             private RubyInstanceData _instanceData;
+            private RubyClass/*!*/ _immediateClass;
             
             [Emitted]
-            public RubyClass/*!*/ ImmediateClass { get; set; }
+            public RubyClass/*!*/ ImmediateClass {
+                get {
+                    return _immediateClass;
+                }
+                set {
+                    // once a singleton immediate class is set it can't be changed:
+                    Debug.Assert((_immediateClass == null || !_immediateClass.IsSingletonClass) &amp;&amp; value != null);
+                    _immediateClass = value;
+                }
+            }
 
             public RubyInstanceData/*!*/ GetInstanceData() {
                 return RubyOps.GetInstanceData(ref _instanceData);
@@ -159,14 +213,32 @@ namespace IronRuby.Builtins {
             public void Freeze() {
                 GetInstanceData().Freeze();
             }
+
+            public int BaseGetHashCode() {
+                return base.GetHashCode();
+            }
+
+            public bool BaseEquals(object other) {
+                return base.Equals(other);
+            }
         }
     }
     public partial class Range {
         public sealed partial class Subclass : Range, IRubyObject {
             private RubyInstanceData _instanceData;
+            private RubyClass/*!*/ _immediateClass;
             
             [Emitted]
-            public RubyClass/*!*/ ImmediateClass { get; set; }
+            public RubyClass/*!*/ ImmediateClass {
+                get {
+                    return _immediateClass;
+                }
+                set {
+                    // once a singleton immediate class is set it can't be changed:
+                    Debug.Assert((_immediateClass == null || !_immediateClass.IsSingletonClass) &amp;&amp; value != null);
+                    _immediateClass = value;
+                }
+            }
 
             public RubyInstanceData/*!*/ GetInstanceData() {
                 return RubyOps.GetInstanceData(ref _instanceData);
@@ -188,14 +260,32 @@ namespace IronRuby.Builtins {
             public void Freeze() {
                 GetInstanceData().Freeze();
             }
+
+            public int BaseGetHashCode() {
+                return base.GetHashCode();
+            }
+
+            public bool BaseEquals(object other) {
+                return base.Equals(other);
+            }
         }
     }
     public partial class RubyRegex {
         public sealed partial class Subclass : RubyRegex, IRubyObject {
             private RubyInstanceData _instanceData;
+            private RubyClass/*!*/ _immediateClass;
             
             [Emitted]
-            public RubyClass/*!*/ ImmediateClass { get; set; }
+            public RubyClass/*!*/ ImmediateClass {
+                get {
+                    return _immediateClass;
+                }
+                set {
+                    // once a singleton immediate class is set it can't be changed:
+                    Debug.Assert((_immediateClass == null || !_immediateClass.IsSingletonClass) &amp;&amp; value != null);
+                    _immediateClass = value;
+                }
+            }
 
             public RubyInstanceData/*!*/ GetInstanceData() {
                 return RubyOps.GetInstanceData(ref _instanceData);
@@ -217,6 +307,14 @@ namespace IronRuby.Builtins {
             public void Freeze() {
                 GetInstanceData().Freeze();
             }
+
+            public int BaseGetHashCode() {
+                return base.GetHashCode();
+            }
+
+            public bool BaseEquals(object other) {
+                return base.Equals(other);
+            }
         }
     }
 #endregion
@@ -235,6 +333,14 @@ namespace IronRuby.Builtins {
             public RubyInstanceData TryGetInstanceData() {
                 return _instanceData;
             }
+
+            public int BaseGetHashCode() {
+                return base.GetHashCode();
+            }
+
+            public bool BaseEquals(object other) {
+                return base.Equals(other);
+            }
         }
     }
 }</diff>
      <filename>Merlin/Main/Languages/Ruby/Ruby/Builtins/Subclasses.Generated.cs</filename>
    </modified>
    <modified>
      <diff>@@ -344,6 +344,21 @@ namespace IronRuby.Compiler.Generation {
             il.EmitLoadArg(1);
             il.EmitCall(Methods.SetObjectTaint);
             il.Emit(OpCodes.Ret);
+
+            // TODO: can we merge this with #base#GetHashCode/Equals?
+
+            // int IRubyObject.BaseGetHashCode() { return base.GetHashCode; }
+            il = DefineMethodOverride(_tb, Methods.IRubyObject_BaseGetHashCode);
+            il.EmitLoadArg(0);
+            il.EmitCall(_tb.BaseType.GetMethod(&quot;GetHashCode&quot;, Type.EmptyTypes));
+            il.Emit(OpCodes.Ret);
+
+            // int IRubyObject.BaseEquals(object other) { return base.Equals(other); }
+            il = DefineMethodOverride(_tb, Methods.IRubyObject_BaseEquals);
+            il.EmitLoadArg(0);
+            il.EmitLoadArg(1);
+            il.EmitCall(_tb.BaseType.GetMethod(&quot;Equals&quot;, new[] { typeof(object) }));
+            il.Emit(OpCodes.Ret);
         }
 
         private void DefineSerializer() {
@@ -382,63 +397,6 @@ namespace IronRuby.Compiler.Generation {
 #endif
         }
 
-        // we need to get the right execution context
-#if OBSOLETE
-        private static void EmitOverrideEquals(TypeGen typeGen) {
-            Type baseType = typeGen.TypeBuilder.BaseType;
-            MethodInfo baseMethod = baseType.GetMethod(&quot;Equals&quot;, new Type[] { typeof(object) });
-            Compiler cg = typeGen.DefineMethodOverride(baseMethod);
-
-            // Check if an &quot;eql?&quot; method exists on this class
-            cg.EmitType(typeGen.TypeBuilder);
-            cg.EmitString(&quot;eql?&quot;);
-            cg.EmitCall(typeof(RubyOps).GetMethod(&quot;ResolveDeclaredInstanceMethod&quot;));
-            Label callBase = cg.DefineLabel();
-            cg.Emit(OpCodes.Brfalse_S, callBase);
-
-            // If so, call it
-            cg.EmitThis();
-            cg.EmitArgGet(0);
-            cg.EmitCall(typeof(RubyOps).GetMethod(&quot;CallEql&quot;));
-            cg.EmitReturn();
-
-            // Otherwise, call base class
-            cg.MarkLabel(callBase);
-            cg.EmitThis();
-            cg.EmitArgGet(0);
-            cg.Emit(OpCodes.Call, baseMethod); // base call must be non-virtual
-            cg.EmitReturn();
-
-            cg.Finish();
-        }
-
-        private static void EmitOverrideGetHashCode(TypeGen typeGen) {
-            Type baseType = typeGen.TypeBuilder.BaseType;
-            MethodInfo baseMethod = baseType.GetMethod(&quot;GetHashCode&quot;, Type.EmptyTypes);
-            Compiler cg = typeGen.DefineMethodOverride(baseMethod);
-
-            // Check if a &quot;hash&quot; method exists on this class
-            cg.EmitType(typeGen.TypeBuilder);
-            cg.EmitString(&quot;hash&quot;);
-            cg.EmitCall(typeof(RubyOps).GetMethod(&quot;ResolveDeclaredInstanceMethod&quot;));
-            Label callBase = cg.DefineLabel();
-            cg.Emit(OpCodes.Brfalse_S, callBase);
-
-            // If so, call it
-            cg.EmitThis();
-            cg.EmitCall(typeof(RubyOps).GetMethod(&quot;CallHash&quot;));
-            cg.EmitReturn();
-
-            // Otherwise, call base class
-            cg.MarkLabel(callBase);
-            cg.EmitThis();
-            cg.Emit(OpCodes.Call, baseMethod); // base call must be non-virtual
-            cg.EmitReturn();
-
-            cg.Finish();
-        }
-#endif
-
         private void DefineDynamicObjectImplementation() {
             _tb.AddInterfaceImplementation(typeof(IDynamicMetaObjectProvider));
 </diff>
      <filename>Merlin/Main/Languages/Ruby/Ruby/Compiler/Generation/RubyTypeBuilder.cs</filename>
    </modified>
    <modified>
      <diff>@@ -253,6 +253,10 @@ namespace IronRuby.Compiler {
         private static MethodInfo _InitializeScope;
         public static MethodInfo/*!*/ InitializeScopeNoLocals { get { return _InitializeScopeNoLocals ?? (_InitializeScopeNoLocals = GetMethod(typeof(RubyOps), &quot;InitializeScopeNoLocals&quot;)); } }
         private static MethodInfo _InitializeScopeNoLocals;
+        public static MethodInfo/*!*/ IRubyObject_BaseEquals { get { return _IRubyObject_BaseEquals ?? (_IRubyObject_BaseEquals = GetMethod(typeof(IRubyObject), &quot;BaseEquals&quot;)); } }
+        private static MethodInfo _IRubyObject_BaseEquals;
+        public static MethodInfo/*!*/ IRubyObject_BaseGetHashCode { get { return _IRubyObject_BaseGetHashCode ?? (_IRubyObject_BaseGetHashCode = GetMethod(typeof(IRubyObject), &quot;BaseGetHashCode&quot;)); } }
+        private static MethodInfo _IRubyObject_BaseGetHashCode;
         public static MethodInfo/*!*/ IRubyObject_get_ImmediateClass { get { return _IRubyObject_get_ImmediateClass ?? (_IRubyObject_get_ImmediateClass = GetMethod(typeof(IRubyObject), &quot;get_ImmediateClass&quot;)); } }
         private static MethodInfo _IRubyObject_get_ImmediateClass;
         public static MethodInfo/*!*/ IRubyObject_GetInstanceData { get { return _IRubyObject_GetInstanceData ?? (_IRubyObject_GetInstanceData = GetMethod(typeof(IRubyObject), &quot;GetInstanceData&quot;)); } }</diff>
      <filename>Merlin/Main/Languages/Ruby/Ruby/Compiler/ReflectionCache.Generated.cs</filename>
    </modified>
    <modified>
      <diff>@@ -36,10 +36,6 @@ namespace IronRuby.Runtime.Calls {
             _instanceVariableName = variableName;
         }
 
-        internal override bool IsRemovable {
-            get { return true; }
-        }
-
         internal override bool IsDataMember {
             get { return true; }
         }</diff>
      <filename>Merlin/Main/Languages/Ruby/Ruby/Runtime/Calls/RubyAccessorInfo.cs</filename>
    </modified>
    <modified>
      <diff>@@ -39,10 +39,6 @@ namespace IronRuby.Runtime.Calls {
             return new RubyCustomMethodInfo(_ruleGenerator, flags, module);
         }
 
-        internal override bool IsRemovable {
-            get { return true; }
-        }
-
         public override MemberInfo/*!*/[]/*!*/ GetMembers() {
             return new MemberInfo[] { _ruleGenerator.Method };
         }</diff>
      <filename>Merlin/Main/Languages/Ruby/Ruby/Runtime/Calls/RubyCustomMethodInfo.cs</filename>
    </modified>
    <modified>
      <diff>@@ -30,16 +30,20 @@ namespace IronRuby.Runtime.Calls {
     public sealed class RubyEventInfo : RubyMemberInfo {
         private readonly EventTracker/*!*/ _tracker;
 
+        // True if the member is defined in Ruby (e.g. via alias) - such definition &quot;detaches&quot; it from the underlying type.
+        private readonly bool _isDetached;
+
         public EventTracker/*!*/ Tracker { get { return _tracker; } }
 
-        public RubyEventInfo(EventTracker/*!*/ tracker, RubyMemberFlags flags, RubyModule/*!*/ declaringModule)
+        public RubyEventInfo(EventTracker/*!*/ tracker, RubyMemberFlags flags, RubyModule/*!*/ declaringModule, bool isDetached)
             : base(flags, declaringModule) {
             Assert.NotNull(tracker, declaringModule);
             _tracker = tracker;
+            _isDetached = isDetached;
         }
 
         protected internal override RubyMemberInfo/*!*/ Copy(RubyMemberFlags flags, RubyModule/*!*/ module) {
-            return new RubyEventInfo(_tracker, flags, module);
+            return new RubyEventInfo(_tracker, flags, module, true);
         }
 
         internal override bool IsDataMember {
@@ -47,7 +51,7 @@ namespace IronRuby.Runtime.Calls {
         }
 
         internal override bool IsRubyMember {
-            get { return false; }
+            get { return _isDetached; }
         }
 
         public override MemberInfo/*!*/[]/*!*/ GetMembers() {</diff>
      <filename>Merlin/Main/Languages/Ruby/Ruby/Runtime/Calls/RubyEventInfo.cs</filename>
    </modified>
    <modified>
      <diff>@@ -30,19 +30,23 @@ namespace IronRuby.Runtime.Calls {
         private readonly FieldInfo/*!*/ _fieldInfo;
         private readonly bool _isSetter;
 
-        public RubyFieldInfo(FieldInfo/*!*/ fieldInfo, RubyMemberFlags flags, RubyModule/*!*/ declaringModule, bool isSetter)
+        // True if the member is defined in Ruby (e.g. via alias) - such definition &quot;detaches&quot; it from the underlying type.
+        private readonly bool _isDetached;
+
+        public RubyFieldInfo(FieldInfo/*!*/ fieldInfo, RubyMemberFlags flags, RubyModule/*!*/ declaringModule, bool isSetter, bool isDetached)
             : base(flags, declaringModule) {
             Assert.NotNull(fieldInfo, declaringModule);
             _fieldInfo = fieldInfo;
             _isSetter = isSetter;
+            _isDetached = isDetached;
         }
 
         protected internal override RubyMemberInfo/*!*/ Copy(RubyMemberFlags flags, RubyModule/*!*/ module) {
-            return new RubyFieldInfo(_fieldInfo, flags, module, _isSetter);
+            return new RubyFieldInfo(_fieldInfo, flags, module, _isSetter, true);
         }
 
         internal override bool IsRubyMember {
-            get { return false; }
+            get { return _isDetached; }
         }
 
         internal override bool IsDataMember {</diff>
      <filename>Merlin/Main/Languages/Ruby/Ruby/Runtime/Calls/RubyFieldInfo.cs</filename>
    </modified>
    <modified>
      <diff>@@ -45,10 +45,6 @@ namespace IronRuby.Runtime.Calls {
             get { return _definitionName; }
         }
 
-        internal override bool IsRemovable {
-            get { return true; }
-        }
-
         public override MemberInfo/*!*/[]/*!*/ GetMembers() {
             return new MemberInfo[] { _lambda.Dispatcher.Method.Method };
         }</diff>
      <filename>Merlin/Main/Languages/Ruby/Ruby/Runtime/Calls/RubyLambdaMethodInfo.cs</filename>
    </modified>
    <modified>
      <diff>@@ -58,10 +58,6 @@ namespace IronRuby.Runtime.Calls {
             : base(methods, info.Flags, info.DeclaringModule) {
         }
 
-        internal override bool IsRemovable {
-            get { return true; }
-        }
-
         internal Delegate/*!*/[]/*!*/ Overloads {
             get { return _overloads; }
         }</diff>
      <filename>Merlin/Main/Languages/Ruby/Ruby/Runtime/Calls/RubyLibraryMethodInfo.cs</filename>
    </modified>
    <modified>
      <diff>@@ -112,11 +112,11 @@ namespace IronRuby.Runtime.Calls {
         }
 
         /// &lt;summary&gt;
-        /// Whether the member can be permanently removed (CLR members can't).
+        /// True if the member can be permanently removed (attached CLR members can't).
         /// If the member cannot be removed we hide it.
         /// &lt;/summary&gt;
-        internal virtual bool IsRemovable {
-            get { return IsSuperForwarder; }
+        internal bool IsRemovable {
+            get { return IsRubyMember &amp;&amp; !IsHidden &amp;&amp; !IsUndefined &amp;&amp; !IsInteropMember; }
         }
 
         internal RubyMemberFlags Flags {</diff>
      <filename>Merlin/Main/Languages/Ruby/Ruby/Runtime/Calls/RubyMemberInfo.cs</filename>
    </modified>
    <modified>
      <diff>@@ -51,8 +51,13 @@ namespace IronRuby.Runtime.Calls {
         public abstract Expression CreateExpression();
 
         public override T BindDelegate&lt;T&gt;(System.Runtime.CompilerServices.CallSite&lt;T&gt; site, object[] args) {
-            InterpretedDispatcher dispatcher = MethodDispatcher.CreateInterpreted(typeof(T), args.Length);
+            RubyContext context = _context ?? ((Signature.HasScope) ? ((RubyScope)args[0]).RubyContext : (RubyContext)args[0]);
 
+            if (context.Options.NoAdaptiveCompilation) {
+                return base.BindDelegate&lt;T&gt;(site, args);
+            }
+
+            InterpretedDispatcher dispatcher = MethodDispatcher.CreateInterpreted(typeof(T), args.Length);
             if (dispatcher == null) {
                 // call site has too many arguments:
                 PerfTrack.NoteEvent(PerfTrack.Categories.Binding, &quot;Ruby: ! No dispatcher for &quot; + Signature.ToString());</diff>
      <filename>Merlin/Main/Languages/Ruby/Ruby/Runtime/Calls/RubyMetaBinder.cs</filename>
    </modified>
    <modified>
      <diff>@@ -49,14 +49,12 @@ namespace IronRuby.Runtime.Calls {
             _isStatic = info._isStatic;
             _hasVirtuals = info._hasVirtuals;
             _staticDispatchMethods = info._staticDispatchMethods;
-            // Note: overloadOwners and maxCachedOverloadLevel are cleared whenever the group is copied.
         }
 
         // copy ctor
         private RubyMethodGroupInfo(RubyMethodGroupInfo/*!*/ info, MethodBase/*!*/[] methods)
             : base(methods, info.Flags, info.DeclaringModule) {
             _isStatic = info._isStatic;
-            // Note: overloadOwners and maxCachedOverloadLevel are cleared whenever the group is copied.
         }
 
         protected internal override RubyMemberInfo/*!*/ Copy(RubyMemberFlags flags, RubyModule/*!*/ module) {
@@ -71,10 +69,6 @@ namespace IronRuby.Runtime.Calls {
             get { return _isStatic ? SelfCallConvention.NoSelf : SelfCallConvention.SelfIsInstance; }
         }
 
-        internal override bool IsRubyMember {
-            get { return false; }
-        }
-
         internal bool IsStatic {
             get { return _isStatic; }
         }</diff>
      <filename>Merlin/Main/Languages/Ruby/Ruby/Runtime/Calls/RubyMethodGroupInfo.cs</filename>
    </modified>
    <modified>
      <diff>@@ -53,10 +53,6 @@ namespace IronRuby.Runtime.Calls {
             return new RubyMethodInfo(_body, _declaringScope, module, flags);
         }
         
-        internal override bool IsRemovable {
-            get { return true; }
-        }
-
         public override RubyMemberInfo TrySelectOverload(Type/*!*/[]/*!*/ parameterTypes) {
             return parameterTypes.Length &gt;= MandatoryParamCount 
                 &amp;&amp; (HasUnsplatParameter || parameterTypes.Length &lt;= MandatoryParamCount + OptionalParamCount)</diff>
      <filename>Merlin/Main/Languages/Ruby/Ruby/Runtime/Calls/RubyMethodInfo.cs</filename>
    </modified>
    <modified>
      <diff>@@ -41,6 +41,10 @@ namespace IronRuby.Runtime.Calls {
             _overloadOwners = overloadOwners;
         }
 
+        internal override bool IsRubyMember {
+            get { return false; }
+        }
+
         internal RubyOverloadGroupInfo[] OverloadOwners {
             get { return _overloadOwners; }
         }</diff>
      <filename>Merlin/Main/Languages/Ruby/Ruby/Runtime/Calls/RubyOverloadGroupInfo.cs</filename>
    </modified>
    <modified>
      <diff>@@ -27,33 +27,46 @@ namespace IronRuby.Runtime {
     // (including instances of arbitrary .NET types via singleton methods)
     // TODO: optimize this by caching hash values?
     public class EqualityComparer : IEqualityComparer&lt;object&gt; {
-        private readonly RubyContext/*!*/ _context;
-
         private readonly CallSite&lt;Func&lt;CallSite, object, object&gt;&gt;/*!*/ _hashSite;
         private readonly CallSite&lt;Func&lt;CallSite, object, object, object&gt;&gt;/*!*/ _eqlSite;
 
         // friend: RubyContext
-        internal EqualityComparer(RubyContext/*!*/ context) {
-            Assert.NotNull(context);
-            _context = context;
-            _hashSite = CallSite&lt;Func&lt;CallSite, object, object&gt;&gt;.Create(
-                RubyCallAction.Make(context, &quot;hash&quot;, RubyCallSignature.WithImplicitSelf(0))
-             );
-            _eqlSite = CallSite&lt;Func&lt;CallSite, object, object, object&gt;&gt;.Create(
-                RubyCallAction.Make(context, &quot;eql?&quot;, RubyCallSignature.WithImplicitSelf(1))
-            );
+        internal EqualityComparer(RubyContext/*!*/ context)
+            : this(
+                CallSite&lt;Func&lt;CallSite, object, object&gt;&gt;.Create(RubyCallAction.Make(context, &quot;hash&quot;, RubyCallSignature.WithImplicitSelf(0))),
+                CallSite&lt;Func&lt;CallSite, object, object, object&gt;&gt;.Create(RubyCallAction.Make(context, &quot;eql?&quot;, RubyCallSignature.WithImplicitSelf(1)))
+            ) {
+        }
+
+        public EqualityComparer(UnaryOpStorage/*!*/ hashStorage, BinaryOpStorage/*!*/ eqlStorage) 
+            : this(hashStorage.GetCallSite(&quot;hash&quot;), eqlStorage.GetCallSite(&quot;eql?&quot;)) {
+        }
+
+        public EqualityComparer(CallSite&lt;Func&lt;CallSite, object, object&gt;&gt;/*!*/ hashSite, CallSite&lt;Func&lt;CallSite, object, object, object&gt;&gt;/*!*/ eqlSite) {
+            ContractUtils.RequiresNotNull(hashSite, &quot;hashSite&quot;);
+            ContractUtils.RequiresNotNull(eqlSite, &quot;eqlSite&quot;);
+            _hashSite = hashSite;
+            _eqlSite = eqlSite;
         }
 
         bool IEqualityComparer&lt;object&gt;.Equals(object x, object y) {
-            return x == y || RubyOps.IsTrue(_eqlSite.Target(_eqlSite, x, y));
+            if (x == y) {
+                return true;
+            }
+
+            if (x is int) {
+                return y is int &amp;&amp; (int)x == (int)y;
+            }
+
+            return RubyOps.IsTrue(_eqlSite.Target(_eqlSite, x, y));
         }
 
         int IEqualityComparer&lt;object&gt;.GetHashCode(object obj) {
-            object result = _hashSite.Target(_hashSite, obj);
-            if (result is int) {
-                return (int)result;
+            if (obj is int) {
+                return (int)obj;
             }
-            return result.GetHashCode();
+
+            return Protocols.ToHashCode(_hashSite.Target(_hashSite, obj));
         }
     }
 }</diff>
      <filename>Merlin/Main/Languages/Ruby/Ruby/Runtime/EqualityComparer.cs</filename>
    </modified>
    <modified>
      <diff>@@ -32,5 +32,13 @@ namespace IronRuby.Runtime {
         // Returns the instance object data.
         [Emitted]
         RubyInstanceData/*!*/ GetInstanceData();
+
+        // Calls GetHashCode via static virtual dispatch, not virtual dynamic dispatch.
+        [Emitted]
+        int BaseGetHashCode();
+
+        // Calls Equals via static virtual dispatch, not virtual dynamic dispatch.
+        [Emitted]
+        bool BaseEquals(object other);
     }
 }</diff>
      <filename>Merlin/Main/Languages/Ruby/Ruby/Runtime/IRubyObject.cs</filename>
    </modified>
    <modified>
      <diff>@@ -261,6 +261,20 @@ namespace IronRuby.Runtime {
             site.Target(site, target, value);
         }
 
+        public static int ToHashCode(object hashResult) {
+            if (hashResult is int) {
+                return (int)hashResult;
+            }
+
+            // MRI calls %(number) on the resulting object if it is not Fixnum and takes internal hash code of the result.
+            // It seems to be an implementation detail that we don't need to follow exactly.
+            if (hashResult is BigInteger) {
+                return hashResult.GetHashCode();
+            }
+
+            return hashResult == null ? RubyUtils.NilObjectId : RuntimeHelpers.GetHashCode(hashResult);
+        }
+
         #endregion
 
         #region Coercion</diff>
      <filename>Merlin/Main/Languages/Ruby/Ruby/Runtime/Protocols.cs</filename>
    </modified>
    <modified>
      <diff>@@ -1429,7 +1429,7 @@ namespace IronRuby.Runtime {
                 // TODO: optimize this (we can have a hashtable of singletons per class: Weak(object) =&gt; Struct { ImmediateClass, InstanceVariables, Flags }):
                 &amp;&amp; !(context.TryGetClrTypeInstanceData(target, out data) &amp;&amp; (immediate = data.ImmediateClass) != null &amp;&amp; immediate.IsSingletonClass);
         }
-        
+
         #endregion
 
         #region Conversions
@@ -1620,32 +1620,7 @@ namespace IronRuby.Runtime {
         }
 
         #endregion
-
-        #region Called by GetHashCode/Equals methods in generated .NET classes
-
-        // we need to get the right execution context here
-#if OBSOLETE
-        [Emitted]
-        public static bool ResolveDeclaredInstanceMethod(Type myType, string name) {
-            RubyModule module = RubyUtils.GetExecutionContext(null).GetOrCreateClass(myType);
-            return module.ResolveDeclaredMethod(SymbolTable.StringToId(name)) != null;
-        }
-
-        [Emitted]
-        public static int CallHash(object obj) {
-            // TODO: do not use default context:
-            return _HashSharedSite.Invoke(RubyContext._DefaultContext, obj);
-        }
-
-        [Emitted]
-        public static bool CallEql(object lhs, object rhs) {
-            // TODO: do not use default context:
-            return _EqlSharedSite.Invoke(RubyContext._DefaultContext, lhs, rhs);
-        }
-#endif
-
-        #endregion
-
+        
         #region Instance variable support
 
         [Emitted]</diff>
      <filename>Merlin/Main/Languages/Ruby/Ruby/Runtime/RubyOps.cs</filename>
    </modified>
    <modified>
      <diff>@@ -147,8 +147,13 @@ tutorial &quot;IronRuby tutorial&quot; do
                 change from &quot;&gt;&gt;&gt;&quot; to &quot;...&quot; to indicate to the user that more lines are expected before the 
                 input will be evaluated.
               },
-              :code =&gt; &quot;if 2 &lt; 3\n  puts 1\nelse\n  puts 2\nend&quot;
-              ) { |interaction| interaction.output.chomp == '1' }
+              :code =&gt; %{
+                if 2 &lt; 3
+                  puts &quot;Ofcourse&quot;
+                else
+                  puts &quot;No way!&quot;
+                end}.strip_margin
+              ) { |interaction| interaction.output =~ /ofcourse/i }
         end
         
         chapter &quot;Built-in modules and interactive exploration&quot; do
@@ -532,13 +537,13 @@ tutorial &quot;IronRuby tutorial&quot; do
     section &quot;Advanced IronRuby - Windows Forms&quot; do
 
         introduction %{
-            Note that if you develop Windows applications interactively using the &lt;tt&gt;ir.exe&lt;/tt&gt; from the
-            &lt;b&gt;Command Prompt&lt;/b&gt;, IronRuby must be initialized specially for that purpose. &lt;tt&gt;ir.exe&lt;/tt&gt;
+            Note that if you develop Windows applications interactively using &lt;tt&gt;ir.exe&lt;/tt&gt; or +iirb+ from
+            the &lt;b&gt;Command Prompt&lt;/b&gt; console, IronRuby must be initialized specially for that purpose. &lt;tt&gt;ir.exe&lt;/tt&gt;
             blocks the main thread so that it can read user input. While this thread awaits text input, the 
             Windows application being dynamically created from the console needs to run on a separate thread
-            so that it can process Windows messages. Also, all interactive commands that interact with UI 
-            need to be executed on the message pump thread. &lt;tt&gt;wpf.rb&lt;/tt&gt; includes a helper method to deal 
-            with this. If you are using a console interactive session, do the following:
+            so that it can process Windows messages. Further, WPF requires that all commands that interact
+            with UI controls need to be executed on the message pump thread. &lt;tt&gt;wpf.rb&lt;/tt&gt; includes a helper 
+            method to deal with this. If you are using a _console_ interactive session, do the following:
             
                 require &quot;wpf.rb&quot;
                 Wpf.interact
@@ -553,11 +558,11 @@ tutorial &quot;IronRuby tutorial&quot; do
                     First, we need to load &lt;tt&gt;System.Windows.Forms.dll&lt;/tt&gt;. Note that it is recommended to
                     use the full assembly name in larger programs as such:
                     
-                        load_assembly(&quot;System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089&quot;)                    
+                        load_assembly &quot;System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089&quot;
                     
                     However, for interactive use, we will use the short form.
                 },
-                :code =&gt; &quot;load_assembly('System.Windows.Forms')&quot;
+                :code =&gt; &quot;load_assembly 'System.Windows.Forms'&quot;
 
             task :body =&gt; %{
                     Import the contents of the &lt;tt&gt;System::Windows::Forms&lt;/tt&gt; namespaces into the global 
@@ -590,7 +595,7 @@ tutorial &quot;IronRuby tutorial&quot; do
                     event handler for the +click+ event and click on the form to receive the event. 
                 },
                 :setup =&gt; Proc.new { |bind|
-                    load_assembly('System.Windows.Forms')
+                    load_assembly 'System.Windows.Forms'
                     include System::Windows::Forms
                     eval %{
                         f = Form.new unless defined? f and f.class == Form</diff>
      <filename>Merlin/Main/Languages/Ruby/Samples/Tutorial/Tutorials/ironruby_tutorial.rb</filename>
    </modified>
    <modified>
      <diff>@@ -5,10 +5,11 @@
     xmlns:mc=&quot;http://schemas.openxmlformats.org/markup-compatibility/2006&quot;
     mc:Ignorable=&quot;d&quot;
 	xmlns:local=&quot;clr-namespace:Tutorial&quot;
+	xmlns:Custom=&quot;http://schemas.microsoft.com/wpf/2008/toolkit&quot;
 	x:Class=&quot;Tutorial.MainWindow&quot;
 	x:Name=&quot;Window&quot;
 	Title=&quot;IronRuby Tutorial&quot;
-	Width=&quot;640&quot; Margin=&quot;0,0,0,12372&quot; Height=&quot;510&quot;&gt;
+	Width=&quot;640&quot; Margin=&quot;0,0,0,12372&quot; Height=&quot;700&quot;&gt;
 	&lt;Window.Resources&gt;
 		&lt;Storyboard x:Key=&quot;tutorial_nav_OnMouseEnter&quot; AutoReverse=&quot;False&quot;&gt;
 			&lt;DoubleAnimationUsingKeyFrames BeginTime=&quot;00:00:00&quot; Storyboard.TargetName=&quot;tutorial_nav&quot; Storyboard.TargetProperty=&quot;(UIElement.RenderTransform).(TransformGroup.Children)[3].(TranslateTransform.X)&quot;&gt;
@@ -17,7 +18,7 @@
 		&lt;/Storyboard&gt;
 		&lt;Storyboard x:Key=&quot;tutorial_nav_OnMouseLeave&quot;&gt;
 			&lt;DoubleAnimationUsingKeyFrames BeginTime=&quot;00:00:00&quot; Storyboard.TargetName=&quot;tutorial_nav&quot; Storyboard.TargetProperty=&quot;(UIElement.RenderTransform).(TransformGroup.Children)[3].(TranslateTransform.X)&quot;&gt;
-				&lt;SplineDoubleKeyFrame KeyTime=&quot;00:00:00.2000000&quot; Value=&quot;170&quot; KeySpline=&quot;0.5,0,0.5,1&quot;/&gt;
+				&lt;SplineDoubleKeyFrame KeyTime=&quot;00:00:00.2000000&quot; Value=&quot;275&quot; KeySpline=&quot;0.5,0,0.5,1&quot;/&gt;
 			&lt;/DoubleAnimationUsingKeyFrames&gt;
 		&lt;/Storyboard&gt;
 		&lt;Storyboard x:Key=&quot;action_MouseEnter&quot;&gt;
@@ -83,7 +84,14 @@
 			&lt;/Border&gt;
 		&lt;/Grid&gt;
 		&lt;Grid x:Name=&quot;Page&quot;&gt;
-			&lt;Border x:Name=&quot;header&quot; BorderBrush=&quot;Black&quot; BorderThickness=&quot;0,0,0,1&quot; Padding=&quot;8,10,8,0&quot; Background=&quot;#FFEFEFEF&quot; Panel.ZIndex=&quot;1&quot; Margin=&quot;0&quot; VerticalAlignment=&quot;Top&quot;&gt;
+			&lt;Border x:Name=&quot;header&quot; BorderBrush=&quot;Black&quot; BorderThickness=&quot;0&quot; Padding=&quot;8,10,8,20&quot; Margin=&quot;0&quot; VerticalAlignment=&quot;Top&quot; Panel.ZIndex=&quot;1&quot;&gt;
+				&lt;Border.Background&gt;
+					&lt;LinearGradientBrush EndPoint=&quot;0.5,1&quot; StartPoint=&quot;0.5,0&quot;&gt;
+						&lt;GradientStop Color=&quot;#55000000&quot; Offset=&quot;0.777&quot;/&gt;
+						&lt;GradientStop Offset=&quot;1&quot;/&gt;
+						&lt;GradientStop Color=&quot;#FFEFEFEF&quot; Offset=&quot;0.773&quot;/&gt;
+					&lt;/LinearGradientBrush&gt;
+				&lt;/Border.Background&gt;
 				&lt;TextBlock x:Name=&quot;header_name&quot; HorizontalAlignment=&quot;Left&quot; FontSize=&quot;32&quot; Text=&quot;Pick a tutorial&quot; TextWrapping=&quot;Wrap&quot; Margin=&quot;0,0,0,-8&quot;/&gt;
 			&lt;/Border&gt;
 			&lt;Border x:Name=&quot;header_navigation&quot; VerticalAlignment=&quot;Top&quot; BorderBrush=&quot;#FF424242&quot; BorderThickness=&quot;1&quot; Panel.ZIndex=&quot;2&quot; Margin=&quot;5,0&quot; d:LayoutOverrides=&quot;Width&quot; Background=&quot;#FF424242&quot; CornerRadius=&quot;0,0,10,10&quot; RenderTransformOrigin=&quot;0.5,0.5&quot;&gt;
@@ -106,9 +114,9 @@
 					&lt;/TextBlock&gt;
 				&lt;/StackPanel&gt;
 			&lt;/Border&gt;
-			&lt;Grid x:Name=&quot;body&quot; Margin=&quot;0,45,0,0&quot;&gt;
+			&lt;Grid x:Name=&quot;body&quot; Margin=&quot;0,50,0,0&quot; Background=&quot;{x:Null}&quot;&gt;
 				&lt;ScrollViewer x:Name=&quot;tutorial_scroll&quot; Margin=&quot;0,0,30,0&quot; Padding=&quot;0&quot; VerticalScrollBarVisibility=&quot;Auto&quot;&gt;
-					&lt;local:TutorialPage Margin=&quot;0&quot;/&gt;
+					&lt;local:TutorialPage Margin=&quot;0&quot; Background=&quot;{x:Null}&quot; Padding=&quot;0&quot;/&gt;
 				&lt;/ScrollViewer&gt;
 				&lt;ScrollViewer x:Name=&quot;main_scroll&quot; Margin=&quot;0&quot; Padding=&quot;8,0,8,16&quot; VerticalScrollBarVisibility=&quot;Auto&quot; Visibility=&quot;Collapsed&quot;&gt;
 					&lt;StackPanel x:Name=&quot;main&quot; VerticalAlignment=&quot;Top&quot; Background=&quot;White&quot; Margin=&quot;0&quot;&gt;
@@ -117,7 +125,7 @@
 					&lt;/StackPanel&gt;
 				&lt;/ScrollViewer&gt;
 			&lt;/Grid&gt;
-			&lt;Border x:Name=&quot;tutorial_nav&quot; HorizontalAlignment=&quot;Right&quot; Width=&quot;200&quot; Background=&quot;White&quot; BorderBrush=&quot;#FF7B7B7B&quot; BorderThickness=&quot;5,2,0,2&quot; CornerRadius=&quot;10,0,0,10&quot; Padding=&quot;2,2,0,2&quot; Margin=&quot;0,30,0,10&quot; Panel.ZIndex=&quot;3&quot; RenderTransformOrigin=&quot;0.5,0.5&quot;&gt;
+			&lt;Border x:Name=&quot;tutorial_nav&quot; HorizontalAlignment=&quot;Right&quot; Width=&quot;300&quot; Background=&quot;White&quot; BorderBrush=&quot;#FF7B7B7B&quot; BorderThickness=&quot;5,2,0,2&quot; CornerRadius=&quot;10,0,0,10&quot; Padding=&quot;2,2,0,2&quot; Margin=&quot;0,30,0,10&quot; Panel.ZIndex=&quot;3&quot; RenderTransformOrigin=&quot;0.5,0.5&quot;&gt;
 				&lt;Border.Resources&gt;
 					&lt;!-- Chapter TEMPLATE --&gt;
 					&lt;DataTemplate x:Key=&quot;ChapterTemplate&quot;&gt;
@@ -138,7 +146,7 @@
 						&lt;ScaleTransform/&gt;
 						&lt;SkewTransform/&gt;
 						&lt;RotateTransform/&gt;
-						&lt;TranslateTransform X=&quot;170&quot;/&gt;
+						&lt;TranslateTransform X=&quot;275&quot;/&gt;
 					&lt;/TransformGroup&gt;
 				&lt;/Border.RenderTransform&gt;
 				&lt;Grid&gt;
@@ -148,11 +156,26 @@
 								&lt;ScaleTransform/&gt;
 								&lt;SkewTransform/&gt;
 								&lt;RotateTransform Angle=&quot;-90&quot;/&gt;
-								&lt;TranslateTransform X=&quot;-55&quot;/&gt;
+								&lt;TranslateTransform X=&quot;-58&quot;/&gt;
 							&lt;/TransformGroup&gt;
 						&lt;/TextBlock.RenderTransform&gt;
 					&lt;/TextBlock&gt;
-					&lt;TreeView x:Name=&quot;chapters&quot; BorderBrush=&quot;{x:Null}&quot; FontSize=&quot;16&quot; HorizontalAlignment=&quot;Right&quot; Margin=&quot;0&quot; Height=&quot;444&quot; RenderTransformOrigin=&quot;0.5,0.5&quot; Width=&quot;170&quot; Padding=&quot;0&quot; BorderThickness=&quot;0&quot; VerticalAlignment=&quot;Top&quot;/&gt;
+					&lt;TreeView x:Name=&quot;chapters&quot; BorderBrush=&quot;{x:Null}&quot; FontSize=&quot;13.333&quot; Margin=&quot;20,0,0,0&quot; RenderTransformOrigin=&quot;0.5,0.5&quot; Padding=&quot;0&quot; BorderThickness=&quot;0&quot; d:LayoutOverrides=&quot;Width&quot; Background=&quot;{x:Null}&quot; HorizontalContentAlignment=&quot;Stretch&quot; VerticalContentAlignment=&quot;Stretch&quot; ScrollViewer.HorizontalScrollBarVisibility=&quot;Auto&quot; MaxWidth=&quot;293&quot;&gt;
+						&lt;TreeView.ItemContainerStyle&gt;
+							&lt;Style&gt;
+								&lt;Setter Property=&quot;TreeViewItem.IsExpanded&quot; Value=&quot;True&quot;/&gt;
+
+								&lt;Style.Triggers&gt;
+
+									&lt;DataTrigger Binding=&quot;{Binding Type}&quot; Value=&quot;menu&quot;&gt;
+										&lt;Setter Property=&quot;TreeViewItem.IsSelected&quot; Value=&quot;True&quot;/&gt;
+									&lt;/DataTrigger&gt;
+
+								&lt;/Style.Triggers&gt;
+
+							&lt;/Style&gt;
+						&lt;/TreeView.ItemContainerStyle&gt;
+					&lt;/TreeView&gt;
 
 				&lt;/Grid&gt;
 </diff>
      <filename>Merlin/Main/Languages/Ruby/Samples/Tutorial/design/Tutorial/MainWindow.xaml</filename>
    </modified>
    <modified>
      <diff>@@ -5,30 +5,17 @@
 	xmlns:mc=&quot;http://schemas.openxmlformats.org/markup-compatibility/2006&quot;
 	mc:Ignorable=&quot;d&quot;
 	x:Class=&quot;Tutorial.TutorialControl&quot;
-	d:DesignWidth=&quot;591&quot; d:DesignHeight=&quot;71.373&quot; Margin=&quot;0&quot;&gt;
+	d:DesignWidth=&quot;591&quot; d:DesignHeight=&quot;97.373&quot; Margin=&quot;0&quot;&gt;
 	&lt;UserControl.Resources&gt;
 		&lt;Storyboard x:Key=&quot;tutorial_id_OnMouseEnter&quot;&gt;
 			&lt;ColorAnimationUsingKeyFrames BeginTime=&quot;00:00:00&quot; Storyboard.TargetName=&quot;tutorial_id&quot; Storyboard.TargetProperty=&quot;(Border.BorderBrush).(SolidColorBrush.Color)&quot;&gt;
 				&lt;SplineColorKeyFrame KeyTime=&quot;00:00:00.0560000&quot; Value=&quot;#FFFFFF4C&quot;/&gt;
 			&lt;/ColorAnimationUsingKeyFrames&gt;
-			&lt;ObjectAnimationUsingKeyFrames BeginTime=&quot;00:00:00&quot; Storyboard.TargetName=&quot;tutorial_desc_id&quot; Storyboard.TargetProperty=&quot;(UIElement.Visibility)&quot; Duration=&quot;00:00:00.0010000&quot;&gt;
-				&lt;DiscreteObjectKeyFrame KeyTime=&quot;00:00:00&quot; Value=&quot;{x:Static Visibility.Visible}&quot;/&gt;
-			&lt;/ObjectAnimationUsingKeyFrames&gt;
-			&lt;ThicknessAnimationUsingKeyFrames BeginTime=&quot;00:00:00&quot; Storyboard.TargetName=&quot;tutorial_desc_id&quot; Storyboard.TargetProperty=&quot;(FrameworkElement.Margin)&quot;&gt;
-				&lt;SplineThicknessKeyFrame KeyTime=&quot;00:00:00&quot; Value=&quot;32,-27,8,8&quot;/&gt;
-				&lt;SplineThicknessKeyFrame KeyTime=&quot;00:00:00.0540000&quot; Value=&quot;32,0,8,8&quot; KeySpline=&quot;0.5,0,0.5,1&quot;/&gt;
-			&lt;/ThicknessAnimationUsingKeyFrames&gt;
 		&lt;/Storyboard&gt;
 		&lt;Storyboard x:Key=&quot;tutorial_id_OnMouseLeave&quot;&gt;
 			&lt;ColorAnimationUsingKeyFrames BeginTime=&quot;00:00:00&quot; Storyboard.TargetName=&quot;tutorial_id&quot; Storyboard.TargetProperty=&quot;(Border.BorderBrush).(SolidColorBrush.Color)&quot;&gt;
 				&lt;SplineColorKeyFrame KeyTime=&quot;00:00:00.0610000&quot; Value=&quot;#FFC8C8C8&quot;/&gt;
 			&lt;/ColorAnimationUsingKeyFrames&gt;
-			&lt;ThicknessAnimationUsingKeyFrames BeginTime=&quot;00:00:00&quot; Storyboard.TargetName=&quot;tutorial_desc_id&quot; Storyboard.TargetProperty=&quot;(FrameworkElement.Margin)&quot;&gt;
-				&lt;SplineThicknessKeyFrame KeyTime=&quot;00:00:00.0600000&quot; Value=&quot;32,-27,8,8&quot;/&gt;
-			&lt;/ThicknessAnimationUsingKeyFrames&gt;
-			&lt;ObjectAnimationUsingKeyFrames BeginTime=&quot;00:00:00&quot; Storyboard.TargetName=&quot;tutorial_desc_id&quot; Storyboard.TargetProperty=&quot;(UIElement.Visibility)&quot;&gt;
-				&lt;DiscreteObjectKeyFrame KeyTime=&quot;00:00:00.0600000&quot; Value=&quot;{x:Static Visibility.Collapsed}&quot;/&gt;
-			&lt;/ObjectAnimationUsingKeyFrames&gt;
 		&lt;/Storyboard&gt;
 	&lt;/UserControl.Resources&gt;
 	&lt;UserControl.Triggers&gt;
@@ -44,7 +31,7 @@
 		&lt;Border x:Name=&quot;tutorial_id&quot; BorderBrush=&quot;#FFC8C8C8&quot; BorderThickness=&quot;5&quot; CornerRadius=&quot;10&quot; Padding=&quot;0&quot; Margin=&quot;0&quot; Background=&quot;White&quot; OpacityMask=&quot;{x:Null}&quot; d:LayoutOverrides=&quot;Width&quot; Cursor=&quot;Hand&quot;&gt;
 			&lt;StackPanel Margin=&quot;0&quot;&gt;
 				&lt;TextBlock x:Name=&quot;tutorial_title_id&quot; Margin=&quot;8&quot; VerticalAlignment=&quot;Bottom&quot; FontSize=&quot;21.333&quot; Padding=&quot;0&quot; TextWrapping=&quot;Wrap&quot; Background=&quot;White&quot; Panel.ZIndex=&quot;1&quot; Cursor=&quot;Hand&quot;&gt;&lt;Run Text=&quot;Example tu&quot;/&gt;&lt;Run Text=&quot;torial&quot;/&gt;&lt;/TextBlock&gt;
-				&lt;RichTextBox x:Name=&quot;tutorial_desc_id&quot; Focusable=&quot;False&quot; IsReadOnly=&quot;True&quot; IsUndoEnabled=&quot;False&quot; BorderThickness=&quot;0&quot; HorizontalAlignment=&quot;Left&quot; FontSize=&quot;13.333&quot; Padding=&quot;0&quot; Margin=&quot;32,0,8,8&quot; Background=&quot;{x:Null}&quot; BorderBrush=&quot;{x:Null}&quot; Visibility=&quot;Collapsed&quot; RenderTransformOrigin=&quot;0.5,0.5&quot; Cursor=&quot;Hand&quot;&gt;
+				&lt;RichTextBox x:Name=&quot;tutorial_desc_id&quot; Focusable=&quot;False&quot; IsReadOnly=&quot;True&quot; IsUndoEnabled=&quot;False&quot; BorderThickness=&quot;0&quot; HorizontalAlignment=&quot;Left&quot; FontSize=&quot;13.333&quot; Padding=&quot;0&quot; Margin=&quot;32,0,8,8&quot; Background=&quot;{x:Null}&quot; BorderBrush=&quot;{x:Null}&quot; RenderTransformOrigin=&quot;0.5,0.5&quot; Cursor=&quot;Hand&quot;&gt;
 					&lt;RichTextBox.RenderTransform&gt;
 						&lt;TransformGroup&gt;
 							&lt;ScaleTransform/&gt;</diff>
      <filename>Merlin/Main/Languages/Ruby/Samples/Tutorial/design/Tutorial/TutorialControl.xaml</filename>
    </modified>
    <modified>
      <diff>@@ -10,7 +10,12 @@
 	d:DesignWidth=&quot;624&quot; d:DesignHeight=&quot;450&quot; Background=&quot;White&quot;&gt;
 
 	&lt;StackPanel x:Name=&quot;tutorial_page&quot; VerticalAlignment=&quot;Top&quot; Margin=&quot;0,8,0,0&quot;&gt;
-        &lt;RichTextBox x:Name=&quot;exercise&quot; Focusable=&quot;False&quot; IsReadOnly=&quot;True&quot; IsUndoEnabled=&quot;False&quot; BorderThickness=&quot;0&quot; HorizontalAlignment=&quot;Left&quot; FontSize=&quot;13.333&quot; Padding=&quot;4,8&quot;&gt;
+        &lt;RichTextBox x:Name=&quot;pre_exercise&quot; Focusable=&quot;False&quot; IsReadOnly=&quot;True&quot; IsUndoEnabled=&quot;False&quot; BorderThickness=&quot;0&quot; HorizontalAlignment=&quot;Left&quot; FontSize=&quot;13.333&quot; Padding=&quot;4,8&quot; Visibility=&quot;Collapsed&quot;&gt;
+			&lt;FlowDocument&gt;
+				&lt;Paragraph&gt;&lt;Run Text=&quot;This section blah blah blah ...&quot;/&gt;&lt;/Paragraph&gt;
+			&lt;/FlowDocument&gt;
+		&lt;/RichTextBox&gt;
+        &lt;RichTextBox x:Name=&quot;exercise&quot; Focusable=&quot;False&quot; IsReadOnly=&quot;True&quot; IsUndoEnabled=&quot;False&quot; BorderThickness=&quot;0&quot; HorizontalAlignment=&quot;Left&quot; FontSize=&quot;13.333&quot; Padding=&quot;4,8&quot; Background=&quot;{x:Null}&quot;&gt;
         	&lt;FlowDocument&gt;
         		&lt;Paragraph&gt;&lt;Run Text=&quot;This section blah blah blah ...&quot;/&gt;&lt;/Paragraph&gt;
         	&lt;/FlowDocument&gt;</diff>
      <filename>Merlin/Main/Languages/Ruby/Samples/Tutorial/design/Tutorial/TutorialPage.xaml</filename>
    </modified>
    <modified>
      <diff>@@ -110,7 +110,11 @@ module Tutorial
 
         def to_s
             @name
-        end    
+        end
+
+        def first_chapter
+          @chapters.first rescue nil
+        end
     end
 
     class Tutorial
@@ -133,6 +137,14 @@ module Tutorial
         def to_s
             @name
         end
+
+        def first_chapter
+          first_section.first_chapter rescue nil
+        end
+
+        def first_section
+          @sections.first rescue nil
+        end
     end
     
     @@tutorials = {} unless class_variable_defined? :@@tutorials
@@ -415,4 +427,4 @@ class String
     match = $1
     gsub(/^#{match}/, &quot;&quot;)
   end
-end
\ No newline at end of file
+end</diff>
      <filename>Merlin/Main/Languages/Ruby/Samples/Tutorial/tutorial.rb</filename>
    </modified>
    <modified>
      <diff>@@ -40,7 +40,12 @@ class System::Windows::FrameworkElement
 
   def set_or_collapse(property, value)
     obj = send(property)
-    obj &amp;&amp; value ? yield(obj, value) : obj.collapse!
+    if obj &amp;&amp; value
+      yield obj, value
+      obj.show!
+    else
+      obj.collapse!
+    end
   end
 end
 
@@ -168,6 +173,21 @@ module Wpf
     end
   end
 
+  # If you constructed your treeview with XAML, you should
+  # use this XAML snippet instead to auto-expand items:
+  #
+  # &lt;TreeView.ItemContainerStyle&gt;
+  #   &lt;Style&gt;
+  #     &lt;Setter Property=&quot;TreeViewItem.IsExpanded&quot; Value=&quot;True&quot;/&gt;
+  #     &lt;Style.Triggers&gt;
+  #       &lt;DataTrigger Binding=&quot;{Binding Type}&quot; Value=&quot;menu&quot;&gt;
+  #         &lt;Setter Property=&quot;TreeViewItem.IsSelected&quot; Value=&quot;True&quot;/&gt;
+  #       &lt;/DataTrigger&gt;
+  #     &lt;/Style.Triggers&gt;
+  #   &lt;/Style&gt;
+  # &lt;/TreeView.ItemContainerStyle&gt;
+  #
+  # If your treeview was constructed with code, use this method
   def self.select_tree_view_item(tree_view, item)
     return false unless self and item
 
@@ -380,3 +400,4 @@ module Wpf
     end
   end
 end
+</diff>
      <filename>Merlin/Main/Languages/Ruby/Samples/Tutorial/wpf.rb</filename>
    </modified>
    <modified>
      <diff>@@ -69,7 +69,20 @@ module WpfTutorial
   end
 
   class Tutorial
-    attr_reader :tasks, :task, :chapter, :current_tutorial
+    attr_reader :tasks, :task, :chapter, :current_tutorial 
+
+    # TODO: Figure out how to remove this condition:
+    # 
+    # When the &quot;next_chapter&quot; button is focused and the enter-button is pressed,
+    # somewhere along that process the &quot;repl_input&quot; TextBox gets focus, but 
+    # then the &quot;repl_input.key_up&quot; fires from the previous enter-button press,
+    # causing two extra lines in the repl history.
+    #
+    # This flag shunts the first key_up event, and then is set back to false. 
+    # This ignores all first-keypresses that are &quot;enter&quot;, hackily removing the
+    # issue, since &quot;enter&quot; should never really be the first key pressed. 
+    # Definitely not a a perfect solution.
+    attr_accessor :handling_next_chapter
 
     def initialize(t)
       @current_tutorial ||= ::Tutorial.get_tutorial(t)
@@ -90,22 +103,21 @@ module WpfTutorial
       reset
       Window.show_tutorial
 
-      @window.set_or_collapse(:exercise, @current_tutorial.introduction) do |obj, value|
-        obj.document = FlowDocument.from_simple_markup(value)
-      end
       @window.chapters.items_source = @current_tutorial.sections
+      @window.chapters.mouse_left_button_up do |t, e|
+        select_section_or_chapter t.selected_item
+      end
 
       @window.next_chapter.click do |t, e|
+        @handling_next_chapter = true
         select_section_or_chapter @chapter.next_item if @chapter
       end
-      @window.chapters.mouse_left_button_up do |t, e|
-        select_section_or_chapter t.selected_item
-      end
+
+      select_chapter(@current_tutorial.first_chapter, @current_tutorial.first_section)
     end
 
     def select_section_or_chapter(item)
       return unless item
-      Wpf::select_tree_view_item @window.chapters, item
       case item
       when ::Tutorial::Section: select_section item
       when ::Tutorial::Chapter: select_chapter item
@@ -114,11 +126,19 @@ module WpfTutorial
       end
     end
 
-    def select_chapter(chapter)
+    def select_chapter(chapter, section = nil)
+      if section
+        @window.set_or_collapse(:pre_exercise, section.introduction) do |obj, value|
+          obj.document = FlowDocument.from_simple_markup value
+        end
+      else
+        @window.pre_exercise.collapse!
+      end
       @chapter = chapter
       @window.set_or_collapse(:exercise, @chapter.introduction) do |obj, value|
         obj.document = FlowDocument.from_simple_markup value
       end
+
       @window.tutorial_body.children.clear
       @tasks = @chapter.tasks.clone
       select_next_task
@@ -129,13 +149,13 @@ module WpfTutorial
       @window.set_or_collapse(:exercise, section.introduction) do |obj, value|
         obj.document = FlowDocument.from_simple_markup value
       end
+      @window.pre_exercise.collapse!
     end
 
     def select_next_task
       unless @tasks.empty?
-        @window.next_step
-
         @task = @tasks.shift
+        @window.next_step
         if @task.description
           fd = FlowDocument.from_simple_markup @task.description
           fd &lt;&lt; &quot;Full path: #{@task.source_files.tr('/', '\\')}&quot; if @task.source_files
@@ -167,6 +187,7 @@ module WpfTutorial
           @window.set_or_collapse(:complete_body, @chapter.summary.body) do |obj, value|
             obj.document = FlowDocument.from_simple_markup value
           end if @chapter.summary
+          @window.next_chapter.focus
         else
           if @current_tutorial.summary &amp;&amp; @current_tutorial.summary.body
             @window.exercise.document = FlowDocument.from_simple_markup(@current_tutorial.summary.body)
@@ -365,14 +386,14 @@ module WpfTutorial
       @window.repl_history.text = ''
 
       @window.repl_input.show!
-      @window.repl_input.focus
       Window.repl.set_prompt
       Window.repl.context.reset_input
+
       # TODO - Should use TextChanged here
       @window.repl_input.key_up do |target, event_args|
-        if event_args.key == Key.enter
+        if event_args.key == Key.enter &amp;&amp; !Window.tutorial.handling_next_chapter
           Window.tutorial.process_result Window.repl.on_repl_input
-        elsif event_args.Key == Key.System and @task        
+        elsif event_args.Key == Key.System
           # This allows hitting Alt-Enter to automatically enter the code
           # It is useful during manual testing of a tutorial's content
           if @task.code.respond_to? :to_ary
@@ -385,8 +406,11 @@ module WpfTutorial
             Window.tutorial.process_result Window.repl.on_repl_input
           end
         end
+        Window.tutorial.handling_next_chapter = false
       end
+
       @window.repl_input_arrow.show!
+      @window.repl_input.focus
     end
 
     private
@@ -444,7 +468,6 @@ module WpfTutorial
     def print(s, new_line = true)
       history.text += s
       history.text += &quot;\n&quot; if new_line
-      history.scroll_to_line(history.line_count - 1)
     end
 
     def set_prompt p = &quot;&gt;&gt;&gt;&quot;</diff>
      <filename>Merlin/Main/Languages/Ruby/Samples/Tutorial/wpf_tutorial.rb</filename>
    </modified>
    <modified>
      <diff>@@ -6,19 +6,19 @@ describe &quot;Equality&quot; do
     module EqualitySpecs
       class RubyClassWithEql
         def initialize(result=nil) @result = result end
-        def ==(other) if @result then @result else other == :ruby_marker end end
+        def eql?(other) if @result then @result else other == :ruby_marker end end
       end
 
       class RubyClassWithoutEql
-        def ==(other) raise &quot;== should not be called&quot; end
+        def eql?(other) raise &quot;eql? should not be called&quot; end
       end
 
       class RubyDerivedClass &lt; EmptyClass
-        def ==(other) other == :ruby_marker end
+        def eql?(other) other == :ruby_marker end
       end
 
       class RubyClassWithEqlAndEquals
-        def ==(other) other == :ruby_marker end
+        def eql?(other) other == :ruby_marker end
         def Equals(other) other == :clr_marker end
       end
       
@@ -29,7 +29,7 @@ describe &quot;Equality&quot; do
       end
 
       class EqualityCheckerSubtypeWithEql  &lt; Equatable
-        def ==(other) other == :ruby_marker end
+        def eql?(other) other == :ruby_marker end
       end
     end
   end
@@ -45,17 +45,17 @@ describe &quot;Equality&quot; do
     }
   EOL
   
-  it &quot;maps Object#== to System.Object.Equals for Ruby classes&quot; do
+  it &quot;maps Object#eql? to System.Object.Equals for Ruby classes&quot; do
     o = EqualitySpecs::RubyClassWithEql.new
     EqualityChecker.equals(o, :ruby_marker).should be_true
   end
 
-  it &quot;maps Object#== to System.Object.Equals for Ruby classes that derive from CLR types&quot; do    
+  it &quot;maps Object#eql? to System.Object.Equals for Ruby classes that derive from CLR types&quot; do    
     o = EqualitySpecs::RubyDerivedClass.new
     EqualityChecker.equals(o, :ruby_marker).should be_true
   end
 
-  it &quot;allows Object#== to return any type&quot; do
+  it &quot;allows Object#eql? to return any type&quot; do
     EqualityChecker.equals(EqualitySpecs::RubyClassWithEql.new(&quot;hello&quot;), 123).should be_true
     EqualityChecker.equals(EqualitySpecs::RubyClassWithEql.new(321), 123).should be_true
 
@@ -74,54 +74,54 @@ describe &quot;Equality&quot; do
     h1 = { o =&gt; o }
     h2 = { o =&gt; o }
     class &lt;&lt; o
-      def ==() raise &quot;== should not be called&quot; end
+      def eql?() raise &quot;eql? should not be called&quot; end
     end
     EqualityChecker.equals(h1, h2).should be_false
   end
 
-  it &quot;maps System.Object.Equals to Object#== for CLR objects&quot; do
+  it &quot;maps System.Object.Equals to Object#eql? for CLR objects&quot; do
     o = EmptyClass.new
     o2 = EmptyClass.new
-    (o == o).should == EqualityChecker.equals(o, o)
-    (o == nil).should == EqualityChecker.equals(o, nil)
-    (o == o2).should == EqualityChecker.equals(o, o2)
+    (o.eql? o).should == EqualityChecker.equals(o, o)
+    (o.eql? nil).should == EqualityChecker.equals(o, nil)
+    (o.eql? o2).should == EqualityChecker.equals(o, o2)
   end
 
-  it &quot;maps System.Object.Equals to Object#== for Ruby sub-classes&quot; do
+  it &quot;maps System.Object.Equals to Object#eql? for Ruby sub-classes&quot; do
     EqualityChecker.equals(EqualitySpecs::EqualityCheckerSubtype.new, &quot;ClrMarker&quot;.to_clr_string).should be_true
     (EqualitySpecs::EqualityCheckerSubtype.new == &quot;ClrMarker&quot;.to_clr_string).should be_true
   end
   
-  it &quot;maps System.Object.Equals to Object#== for Ruby sub-classes with #==&quot; do
+  it &quot;maps System.Object.Equals to Object#eql? for Ruby sub-classes with #eql?&quot; do
     EqualityChecker.equals(EqualitySpecs::EqualityCheckerSubtypeWithEql.new, &quot;ClrMarker&quot;.to_clr_string).should be_false
     EqualityChecker.equals(EqualitySpecs::EqualityCheckerSubtypeWithEql.new, :ruby_marker).should be_true
   end
   
-  it &quot;does not map System.Object.Equals to Object#== for monkey-patched CLR objects&quot; do
+  it &quot;does not map System.Object.Equals to Object#eql? for monkey-patched CLR objects&quot; do
     # Virtual methods cannot be overriden via monkey-patching. Therefore the Equals virtual call from EqualityChecker is routed to the default implementation on System.Object.
     o = EmptyClass.new
     class &lt;&lt; o
-      def ==(other)
+      def eql?(other)
         flunk
       end
     end
     EqualityChecker.equals(o, EmptyClass.new).should be_false
   end
 
-  it &quot;maps System.Object.Equals to Object#== for Object&quot; do
-    # Object.new returns RubyObject whose Equals is overridden to call == dynamically.
+  it &quot;maps System.Object.Equals to Object#eql? for Object&quot; do
+    # Object.new returns RubyObject whose Equals is overridden to call eql? dynamically.
     o = Object.new
     class &lt;&lt; o
-      def ==(other)
+      def eql?(other)
         true
       end
     end
     EqualityChecker.equals(o, Object.new).should be_true
   end
   
-  it &quot;allows both Object#== and System.Object.Equals to be overriden separately&quot; do
+  it &quot;allows both Object#eql? and System.Object.Equals to be overriden separately&quot; do
     o = EqualitySpecs::RubyClassWithEqlAndEquals.new
-    (o == :ruby_marker).should be_true
+    (o.eql? :ruby_marker).should be_true
     EqualityChecker.equals(o, :clr_marker).should be_true
   end
 end</diff>
      <filename>Merlin/Main/Languages/Ruby/Tests/Interop/net/bcl/equality/equality_spec.rb</filename>
    </modified>
    <modified>
      <diff>@@ -18,7 +18,7 @@ describe &quot;Hashing&quot; do
       end
 
       class ToIntClass
-        def to_int() 123 end
+        def to_int() 123 end        
       end
 
       class RubyClassWithHashAndGetHashCode
@@ -60,9 +60,10 @@ describe &quot;Hashing&quot; do
     Hasher.get_hash_code(o).class.should == Fixnum
   end
 
-  it &quot;requires Object#hash to return an Integer&quot; do
-    o = HashingSpecs::RubyClassWithHash.new(HashingSpecs::ToIntClass.new)
-    lambda { Hasher.get_hash_code(o) }.should raise_error(TypeError)
+  it &quot;returns a reference based hash code of an object returned from Object#hash if it is not a Fixnum or Bignum&quot; do
+    hashResult = HashingSpecs::ToIntClass.new
+    o = HashingSpecs::RubyClassWithHash.new(hashResult)
+    Hasher.get_hash_code(o).should == System::Runtime::CompilerServices::RuntimeHelpers.get_hash_code(hashResult)
   end
 
   it &quot;uses reference hashing for Array&quot; do</diff>
      <filename>Merlin/Main/Languages/Ruby/Tests/Interop/net/bcl/equality/hashing_spec.rb</filename>
    </modified>
    <modified>
      <diff>@@ -10,7 +10,7 @@ def error?(msg = &quot;At least 1 of the dev unit tests failed&quot;)
   end
 end
 
-flags = [&quot;&quot;, &quot;/partial&quot;, &quot;/interpret&quot;, &quot;/partial /interpret&quot;]
+flags = [&quot;&quot;, &quot;/partial&quot;, &quot;/noadaptive&quot;, &quot;/partial /noadaptive&quot;]
 
 ENV['ROWAN_BIN'] ||= &quot;#{ENV['MERLIN_ROOT']}\\bin\\debug&quot;
 </diff>
      <filename>Merlin/Main/Languages/Ruby/Tests/Scripts/irtest.rb</filename>
    </modified>
  </modified>
  <removed type="array">
    <removed>
      <filename>Merlin/External.LCA_RESTRICTED/Languages/IronRuby/mspec/ironruby-tags/core/array/eql_tags.txt</filename>
    </removed>
    <removed>
      <filename>Merlin/External.LCA_RESTRICTED/Languages/IronRuby/mspec/ironruby-tags/core/array/hash_tags.txt</filename>
    </removed>
    <removed>
      <filename>Merlin/Main/Languages/IronPython/IronPython.Modules/codecs.cs</filename>
    </removed>
  </removed>
  <parents type="array">
    <parent>
      <id>2b73aba8bde0e6cf2ee0e579d6dabee57836708a</id>
    </parent>
  </parents>
  <author>
    <name>Jim Deville</name>
    <email>jdeville@microsoft.com</email>
  </author>
  <url>http://github.com/ironruby/ironruby/commit/48d2bedfa0986a8ae906928a2006a3a82d2cd935</url>
  <id>48d2bedfa0986a8ae906928a2006a3a82d2cd935</id>
  <committed-date>2009-06-22T12:44:53-07:00</committed-date>
  <authored-date>2009-06-22T12:44:53-07:00</authored-date>
  <message>Syncing to head of TFS</message>
  <tree>093cef3494be1c98e567f4021212d7ad876a7c01</tree>
  <committer>
    <name>Jim Deville</name>
    <email>jdeville@microsoft.com</email>
  </committer>
</commit>
