diff --git a/src/org/jruby/RubyHash.java b/src/org/jruby/RubyHash.java
index f2f85f3..57b59f5 100644
--- a/src/org/jruby/RubyHash.java
+++ b/src/org/jruby/RubyHash.java
@@ -731,6 +731,10 @@ public class RubyHash extends RubyObject implements Map {
      */
     @JRubyMethod(name = "rehash")
     public RubyHash rehash() {
+        // Make sure that the rehash is not called within an Iterator.
+        if (iteratorBlock != null && getRuntime().getCurrentContext().isWithinBlock(iteratorBlock))
+            throw getRuntime().newRuntimeError("rehash occurred during iteration");
+
         modify();
         final RubyHashEntry[] oldTable = table;
         final RubyHashEntry[] newTable = new RubyHashEntry[oldTable.length];
@@ -1006,6 +1010,8 @@ public class RubyHash extends RubyObject implements Map {
      */
     @JRubyMethod(name = "each", frame = true)
     public RubyHash each(final ThreadContext context, final Block block) {
+        iteratorBlock = block;
+
         if (block.arity() == Arity.TWO_ARGUMENTS) {
             visitAll(new Visitor() {
                 public void visit(IRubyObject key, IRubyObject value) {
@@ -1022,6 +1028,7 @@ public class RubyHash extends RubyObject implements Map {
             });
         }
 
+        iteratorBlock = null;
         return this;
     }
 
@@ -1035,6 +1042,8 @@ public class RubyHash extends RubyObject implements Map {
      */
     @JRubyMethod(name = "each_pair", frame = true)
     public RubyHash each_pair(final ThreadContext context, final Block block) {
+        iteratorBlock = block;
+
         final Ruby runtime = getRuntime();
 
         visitAll(new Visitor() {
@@ -1044,6 +1053,7 @@ public class RubyHash extends RubyObject implements Map {
             }
         });
 
+        iteratorBlock = null;
         return this;	
     }
 
@@ -1057,12 +1067,15 @@ public class RubyHash extends RubyObject implements Map {
      */
     @JRubyMethod(name = "each_value", frame = true)
     public RubyHash each_value(final ThreadContext context, final Block block) {
+        iteratorBlock = block;
+
         visitAll(new Visitor() {
             public void visit(IRubyObject key, IRubyObject value) {
                 block.yield(context, value);
             }
         });
 
+        iteratorBlock = null;
         return this;
     }
 
@@ -1081,7 +1094,6 @@ public class RubyHash extends RubyObject implements Map {
                 block.yield(context, key);
             }
         });
-
         return this;
     }
 
@@ -1090,12 +1102,16 @@ public class RubyHash extends RubyObject implements Map {
         return block.isGiven() ? each_key(context, block) : enumeratorize(context.getRuntime(), this, "each_key");
     }
 
+    // Block used for each iterator.
+    private Block iteratorBlock = null;
+
     /** rb_hash_sort
      *
      */
     @JRubyMethod(name = "sort", frame = true)
     public IRubyObject sort(ThreadContext context, Block block) {
-        return to_a().sort_bang(context, block);
+        IRubyObject result = to_a().sort_bang(context, block);
+        return result;
     }
 
     /** rb_hash_index
@@ -1259,6 +1275,7 @@ public class RubyHash extends RubyObject implements Map {
      */
     @JRubyMethod(name = "select", frame = true)
     public IRubyObject select(final ThreadContext context, final Block block) {
+        iteratorBlock = block;
         final Ruby runtime = getRuntime();
         final RubyArray result = runtime.newArray();
 
@@ -1270,6 +1287,7 @@ public class RubyHash extends RubyObject implements Map {
             }
         });
 
+        iteratorBlock = null;
         return result;
     }
 
@@ -1278,6 +1296,7 @@ public class RubyHash extends RubyObject implements Map {
         final Ruby runtime = context.getRuntime();
         if (!block.isGiven()) return enumeratorize(runtime, this, "select");
 
+        iteratorBlock = block;
         final RubyHash result = newHash(runtime);
 
         visitAll(new Visitor() {
@@ -1288,6 +1307,7 @@ public class RubyHash extends RubyObject implements Map {
             }
         });
 
+        iteratorBlock = null;
         return result;        
     }
 
@@ -1296,6 +1316,7 @@ public class RubyHash extends RubyObject implements Map {
      */
     @JRubyMethod(name = "delete_if", frame = true)
     public RubyHash delete_if(final ThreadContext context, final Block block) {
+        iteratorBlock = block;
         modify();
 
         final Ruby runtime = getRuntime();
@@ -1308,6 +1329,7 @@ public class RubyHash extends RubyObject implements Map {
             }
         });
 
+        iteratorBlock = null;
         return this;
     }
 
diff --git a/src/org/jruby/runtime/ThreadContext.java b/src/org/jruby/runtime/ThreadContext.java
index 961273d..4bf80d2 100644
--- a/src/org/jruby/runtime/ThreadContext.java
+++ b/src/org/jruby/runtime/ThreadContext.java
@@ -425,7 +425,15 @@ public final class ThreadContext {
         }
         return frames;
     }
-    
+
+    public boolean isWithinBlock(Block block) {
+        for(int i=0; i<getFrameCount(); i++) {
+            if (block == frameStack[i].getBlock())
+                return true;
+        }
+        return false;
+    }
+
     public String getFrameName() {
         return getCurrentFrame().getName();
     }
