add: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Experimental/Regex/Slice.rb
File: Slice.rb
===================================================================
--- [no source file]
+++ Shelved Change: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Experimental/Regex/Slice.rb;RangeFixes
@@ -1,0 +1,15 @@
+class R < Range
+  def exclude_end?
+    p "foooo"
+    true
+  end
+end
+
+/(a)(b)(c)(d)(e)?(f)?(g)?(h)?/ =~ "abcd"
+p $1, $2, $3, $4, $5, $6, $7, $8, $9, $10
+p $+
+p $~[R.new(1,-1)]
+
+
+x = [1,2,3,4,5,6]
+p x[R.new(1,-1)]
\ No newline at end of file
===================================================================
edit: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Builtins/MatchDataOps.cs;C443395
File: MatchDataOps.cs
===================================================================
--- $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Builtins/MatchDataOps.cs;C443395  (server)    5/24/2008 6:23 PM
+++ Shelved Change: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Builtins/MatchDataOps.cs;RangeFixes
@@ -17,6 +17,7 @@
 using Microsoft.Scripting.Actions;
 using Microsoft.Scripting.Runtime;
 using Ruby.Runtime;
+using System.Text.RegularExpressions;
 
 namespace Ruby.Builtins {
     [RubyClass("MatchData", Extends = typeof(MatchData), Inherits = typeof(Object))]
@@ -47,14 +48,17 @@
 
         [RubyMethod("[]")]
         public static RubyArray GetGroup(CodeContext/*!*/ context, MatchData/*!*/ self, int start, int length) {
-            start = IListOps.NormalizeIndex(self.Groups.Count, start);
-            if (length < 0 || start < 0 || start > self.Groups.Count)
+            if (!IListOps.NormalizeRange(self.Groups.Count, ref start, ref length)) {
                 return null;
+            }
 
-            int end = start + length > self.Groups.Count ? self.Groups.Count : start + length;
             RubyArray result = new RubyArray();
-            for (int i = start; i < end; ++i)
-                result.Add(Kernel.FlowTaint(context, self, MutableString.Create(self.Groups[i].Value)));
+            for (int i = 0; i < length; i++) {
+                Group group = self.Groups[start + i];
+                MutableString value = group.Success ? MutableString.Create(group.Value) : null;
+                result.Add(Kernel.FlowTaint(context, self, value));
+            }
+
             return result;
         }
 
@@ -65,10 +69,11 @@
 
         [RubyMethod("[]")]
         public static RubyArray GetGroup(CodeContext/*!*/ context, MatchData/*!*/ self, Range range) {
-            int begin = Protocols.CastToFixnum(context, range.Begin);
-            int end = Protocols.CastToFixnum(context, range.End);
-            int length = range.ExcludeEnd ? end - begin : end - begin + 1;
-            return GetGroup(context, self, begin, length);
+            int begin, count;
+            if (!IListOps.NormalizeRange(context, self.Groups.Count, range, out begin, out count)) {
+                return null;
+            }
+            return GetGroup(context, self, begin, count);
         }
 
         private static void AssertValidGroup(MatchData/*!*/ self, int group) {
===================================================================
edit: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Builtins/MutableStringOps.cs;C448462
File: MutableStringOps.cs
===================================================================
--- $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Builtins/MutableStringOps.cs;C448462  (server)    5/24/2008 2:28 PM
+++ Shelved Change: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Builtins/MutableStringOps.cs;RangeFixes
@@ -2767,6 +2767,10 @@
         // This method uses the tokenizer to auto-detect the base type -- happens when agument to to_i is 0
         private static object ParseInteger(CodeContext/*!*/ context, string/*!*/ str) {
             bool isNegative = false;
+            if (str.Length == 0) {
+                return RuntimeHelpers.Int32ToObject(0);
+            }
+
             str = ParseSign(str, ref isNegative);
 
             Tokenizer tokenizer = new Tokenizer(false, ErrorSink.Null);
===================================================================
edit: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Extensions/IListOps.cs;C443395
File: IListOps.cs
===================================================================
--- $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Extensions/IListOps.cs;C443395  (server)    5/24/2008 6:19 PM
+++ Shelved Change: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Extensions/IListOps.cs;RangeFixes
@@ -47,6 +47,36 @@
             return index < 0 ? index + count : index;
         }
 
+        internal static bool NormalizeRange(int listCount, ref int start, ref int count) {
+            start = NormalizeIndex(listCount, start);
+            if (start < 0 || start > listCount || count < 0) {
+                return false;
+            }
+
+            if (count != 0) {
+                count = start + count > listCount ? listCount - start : count;
+            }
+
+            return true;
+        }
+
+        internal static bool NormalizeRange(CodeContext/*!*/ context, int listCount, Range/*!*/ range, out int begin, out int count) {
+            begin = Protocols.CastToFixnum(context, RubySites.RangeBegin(context, range));
+            int end = Protocols.CastToFixnum(context, RubySites.RangeEnd(context, range));
+
+            begin = NormalizeIndex(listCount, begin);
+
+            if (begin < 0 || begin > listCount) {
+                count = 0;
+                return false;
+            }
+
+            end = NormalizeIndex(listCount, end);
+
+            count = range.ExcludeEnd ? end - begin : end - begin + 1;
+            return true;
+        }
+
         private static bool InRangeNormalized(IList/*!*/ list, ref int index) {
             if (index < 0) {
                 index = index + list.Count;
@@ -268,16 +298,10 @@
         [RubyMethod("[]")]
         [RubyMethod("slice")]
         public static IList GetElements(CodeContext/*!*/ context, IList/*!*/ list, int index, int count) {
-            index = NormalizeIndex(list, index);
-            if (index < 0 || index > list.Count || count < 0) {
+            if (!NormalizeRange(list.Count, ref index, ref count)) {
                 return null;
             }
 
-            if (count == 0) {
-                return CreateResultArray(context, list);
-            }
-
-            count = index + count > list.Count ? list.Count - index : count;
             return GetResultRange(context, list, index, count);
         }
 
@@ -302,18 +326,12 @@
         [RubyMethod("[]")]
         [RubyMethod("slice")]
         public static IList GetElement(CodeContext/*!*/ context, IList array, Range range) {
-            int begin = Protocols.CastToFixnum(context, RubySites.RangeBegin(context, range));
-            int end = Protocols.CastToFixnum(context, RubySites.RangeEnd(context, range));
-
-            begin = NormalizeIndex(array, begin);
-
-            if (begin < 0 || begin > array.Count)
+            int start, count;
+            if (!NormalizeRange(context, array.Count, range, out start, out count)) {
                 return null;
-
-            end = NormalizeIndex(array, end);
-
-            int count = RubySites.RangeExcludeEnd(context, range) ? end - begin : end - begin + 1;
-            return count < 0 ? CreateResultArray(context, array) : GetElements(context, array, begin, count);
+            }            
+            
+            return count < 0 ? CreateResultArray(context, array) : GetElements(context, array, start, count);
         }
 
         #endregion
===================================================================
