diff --git a/src/lib/rope.rs b/src/lib/rope.rs
index 1b18978aa41..215434c8c7f 100644
--- a/src/lib/rope.rs
+++ b/src/lib/rope.rs
@@ -95,6 +95,7 @@ Safety notes:
  */
 fn of_substr(str: @str, byte_offset: uint, byte_len: uint) -> rope {
     if byte_len == 0u { ret node::empty; }
+    if byte_offset + byte_len  > str::byte_len(*str) { fail; }
     ret node::content(node::of_substr(str, byte_offset, byte_len));
 }
 
@@ -702,18 +703,50 @@ mod node {
     }
 
     /*
+    Function: of_substr
+
     Adopt a slice of a string as a node.
 
     If the slice is longer than `max_leaf_char_len`, it is logically split
     between as many leaves as necessary. Regardless, the string itself
     is not copied.
 
-    @param byte_start The byte offset where the slice of `str` starts.
-    @param byte_len   The number of bytes from `str` to use.
+    Parameters:
+    byte_start - The byte offset where the slice of `str` starts.
+    byte_len   - The number of bytes from `str` to use.
+
+    Safety note:
+    - Behavior is undefined if `byte_start` or `byte_len` do not represent
+     valid positions in `str`
      */
     fn of_substr(str: @str, byte_start: uint, byte_len: uint) -> @node {
-        assert (byte_len > 0u);
-        let char_len = str::char_len_range(*str, byte_start, byte_len);
+        ret of_substr_unsafer(str, byte_start, byte_len,
+                  str::char_len_range(*str, byte_start, byte_len));
+    }
+
+    /*
+    Function: of_substr_unsafer
+
+    Adopt a slice of a string as a node.
+
+    If the slice is longer than `max_leaf_char_len`, it is logically split
+    between as many leaves as necessary. Regardless, the string itself
+    is not copied.
+
+    byte_start - The byte offset where the slice of `str` starts.
+    byte_len   - The number of bytes from `str` to use.
+    char_len   - The number of chars in `str` in the interval
+          [byte_start, byte_start+byte_len(
+
+    Safety note:
+    - Behavior is undefined if `byte_start` or `byte_len` do not represent
+     valid positions in `str`
+    - Behavior is undefined if `char_len` does not accurately represent the
+     number of chars between byte_start and byte_start+byte_len
+    */
+    fn of_substr_unsafer(str: @str, byte_start: uint, byte_len: uint,
+                          char_len: uint) -> @node {
+        assert(byte_start + byte_len <= str::byte_len(*str));
         let candidate = @leaf({
                 byte_offset: byte_start,
                 byte_len:    byte_len,
@@ -784,6 +817,15 @@ mod node {
     }
 
 
+    /*
+    Function: tree_from_forest_destructive
+
+    Concatenate a forest of nodes into one tree.
+
+    Parameters:
+    forest - The forest. This vector is progressively rewritten during
+    execution and should be discarded as meaningless afterwards.
+    */
     fn tree_from_forest_destructive(forest: [mutable @node]) -> @node {
         let i = 0u;
         let len = vec::len(forest);
@@ -796,17 +838,26 @@ mod node {
                 let right_len= char_len(right);
                 let left_height= height(left);
                 let right_height=height(right);
-                if left_len + right_len > hint_max_leaf_char_len
-                    //TODO: Improve strategy
-                    || left_height  >= hint_max_node_height
-                    || right_height >= hint_max_node_height {
+                if left_len + right_len > hint_max_leaf_char_len {
                     if left_len <= hint_max_leaf_char_len {
                         left = flatten(left);
+                        left_height = height(left);
                     }
                     if right_len <= hint_max_leaf_char_len {
                         right = flatten(right);
+                        right_height = height(right);
                     }
                 }
+                if left_height >= hint_max_node_height {
+                    left = of_substr_unsafer(@serialize_node(left),
+                                             0u,byte_len(left),
+                                             left_len);
+                }
+                if right_height >= hint_max_node_height {
+                    right = of_substr_unsafer(@serialize_node(right),
+                                             0u,byte_len(right),
+                                             right_len);
+                }
                 forest[i/2u] = concat2(left, right);
                 i += 2u;
             }