diff --git a/shotgun/lib/string.c b/shotgun/lib/string.c
index 5a15df6..08a5b6a 100644
--- a/shotgun/lib/string.c
+++ b/shotgun/lib/string.c
@@ -184,6 +184,31 @@ double string_to_double(STATE, OBJECT self) {
   return value;
 }

+OBJECT string_cstr_overwrite(STATE, OBJECT self, char *str, int len) {
+  OBJECT nd, cur;
+  int tmp;
+  char *ba;
+
+  xassert(STRING_P(self));
+  string_unshare(state, self);
+
+  cur = string_get_data(self);
+  tmp = bytearray_bytes(state, cur);
+  if(len+1 > tmp) {
+    int extra = len * 0.01;
+    if(extra < 10) extra = 10;
+    nd = bytearray_new_dirty(state, len + extra);
+    ba = bytearray_byte_address(state, nd);
+    string_set_data(self, nd);
+  } else {
+    ba = bytearray_byte_address(state, cur);
+  }
+  memcpy(ba, str, len);
+  ba[len] = 0;
+  string_set_bytes(self, I2N(len));
+  return self;
+}
+
 static OBJECT tr_replace(STATE, OBJECT string, int bytes, unsigned char *str,
                          unsigned char *data, int size, int steps) {
   if(size > bytes || RTEST(string_get_shared(string))) {
diff --git a/shotgun/lib/string.h b/shotgun/lib/string.h
index 5483fb7..5cb44a6 100644
--- a/shotgun/lib/string.h
+++ b/shotgun/lib/string.h
@@ -35,6 +35,7 @@ unsigned int string_hash_str(unsigned char *bp, unsigned int sz);
 OBJECT string_newfrombstr(STATE, bstring output);
 int string_equal_p(STATE, OBJECT self, OBJECT other);
 OBJECT string_tr_expand(STATE, OBJECT string, OBJECT limit);
+OBJECT string_cstr_overwrite(STATE, OBJECT self, char *str, int len);

 #define string_unshare(state, cur) \
 if(string_get_shared(cur) == Qtrue) { string_set_data(cur, bytearray_dup(state, string_get_data(cur))); string_set_shared(cur, Qnil); }
diff --git a/shotgun/lib/subtend/handle.c b/shotgun/lib/subtend/handle.c
index a061c3f..d2f21c6 100644
--- a/shotgun/lib/subtend/handle.c
+++ b/shotgun/lib/subtend/handle.c
@@ -1,4 +1,13 @@
 #include "shotgun/lib/shotgun.h"
+#include "shotgun/lib/string.h"
+
+/* Copied from ruby.h to avoid including it here. */
+struct RString {
+  char *ptr;
+  int len;
+};
+
+typedef struct RString RString;

 rni_handle_table *handle_table_new() {
   rni_handle_table *tbl;
@@ -18,6 +27,7 @@ rni_handle *handle_allocate() {
   h->flags = 0;
   h->handle_id = 0;
   h->table_idx = 0;
+  h->data = 0;

   return h;
 }
@@ -35,6 +45,7 @@ rni_handle *handle_new(rni_handle_table *tbl, OBJECT obj) {
   e = ALLOC(rni_ht_entry);
   e->handle_id = h->handle_id;
   e->object = obj;
+  e->rh = h;

   /* Put the entry in the table. */
   tbl->entries[h->table_idx] = e;
@@ -109,6 +120,38 @@ rni_handle *handle_detached_array(rni_handle_table *tbl, int len) {

 */

+/* Check if the handle has RStruct data in it. 
+   If it does we have to copy RStruct data back to the object. */
+void check_rstruct_data(STATE, rni_handle *h, OBJECT o) {
+  if(!h->data) {
+    return;
+  }
+  if (STRING_P(o)) {
+    RString *rs = (RString *)h->data;
+    string_cstr_overwrite(state, o, rs->ptr, rs->len);
+    XFREE(rs);
+    h->data = 0;
+  } else if (ARRAY_P(o)) {
+    //TODO: overwrite array in object
+  }
+}
+
+/* Check all created handles looking for RStruct data on them. */
+void check_rstruct_data_in_handles(STATE, rni_handle_table *tbl) {
+  rni_ht_entry *e;
+  rni_handle *h;
+  int i;
+
+  for(i = 0; i < tbl->total; ++i) {
+    e = tbl->entries[i];
+    if(!e) {
+      continue;
+    }
+    h = e->rh;
+    check_rstruct_data(state, h, e->object);
+  }
+}
+
 OBJECT handle_to_object(STATE, rni_handle_table *tbl, rni_handle *h) {
   rni_ht_entry *e;

@@ -141,6 +184,8 @@ OBJECT handle_to_object(STATE, rni_handle_table *tbl, rni_handle *h) {
     return Qnil;
   }

+  check_rstruct_data(state, h, e->object);
+
   return e->object;
 }

diff --git a/shotgun/lib/subtend/handle.h b/shotgun/lib/subtend/handle.h
index 30a0e48..638d4bf 100644
--- a/shotgun/lib/subtend/handle.h
+++ b/shotgun/lib/subtend/handle.h
@@ -9,6 +9,7 @@ typedef struct rni_handle rni_handle;

 struct rni_ht_entry {
   int handle_id;
+  rni_handle *rh;
   OBJECT object;
 };

@@ -41,4 +42,5 @@ void handle_delete(rni_handle *h);
 OBJECT handle_to_object(STATE, rni_handle_table *tbl, rni_handle *h);
 void handle_make_global(rni_handle *h);
 void handle_clear_global(rni_handle *h);
+void check_rstruct_data_in_handles(STATE, rni_handle_table *tbl);

diff --git a/shotgun/lib/subtend/nmc.c b/shotgun/lib/subtend/nmc.c
index c0f7e97..2e8d1e0 100644
--- a/shotgun/lib/subtend/nmc.c
+++ b/shotgun/lib/subtend/nmc.c
@@ -253,7 +253,9 @@ void _nmc_start() {
       abort();
     }
   }
-  
+
+  check_rstruct_data_in_handles(state, global_context->state->handle_tbl);
+
   /*
   if(args) XFREE(args);
   if(va) XFREE(va);
diff --git a/shotgun/lib/subtend/ruby.c b/shotgun/lib/subtend/ruby.c
index e4746a8..3e925eb 100644
--- a/shotgun/lib/subtend/ruby.c
+++ b/shotgun/lib/subtend/ruby.c
@@ -620,6 +620,20 @@ void rb_string_value(VALUE *val) {
   *val = rb_obj_as_string(*val);
 }

+RString* RSTRING(VALUE arg) {
+  RString *ret;
+  CTX;
+
+  ret = (RString *)AS_HNDL(arg)->data;
+  if(!ret) {
+    ret = ALLOC(RString);
+    ret->ptr = rbx_string_as_cstr(ctx->state, HNDL(arg));
+    ret->len = strlen(ret->ptr);
+    AS_HNDL(arg)->data = (void *)ret;
+  }
+  return ret;
+}
+
 VALUE rb_inspect(VALUE obj) {
   return rb_funcall(obj, rb_intern("inspect"), 0, 0);
 }
diff --git a/shotgun/lib/subtend/ruby.h b/shotgun/lib/subtend/ruby.h
index a848145..5529ffe 100644
--- a/shotgun/lib/subtend/ruby.h
+++ b/shotgun/lib/subtend/ruby.h
@@ -195,6 +195,15 @@ void rb_string_value(VALUE *obj);
 /* HACK ? */
 #define STR2CSTR StringValuePtr

+struct RString {
+  char *ptr;
+  int len;
+};
+
+typedef struct RString RString;
+
+RString* RSTRING(VALUE obj);
+
 VALUE rb_inspect(VALUE obj);

 /* Hash */
diff --git a/spec/subtend/ext/subtend_string.c b/spec/subtend/ext/subtend_string.c
index c713735..e9d3ee2 100644
--- a/spec/subtend/ext/subtend_string.c
+++ b/spec/subtend/ext/subtend_string.c
@@ -62,6 +62,38 @@ VALUE ss_str_substr(VALUE self, VALUE str, VALUE beg, VALUE len) {
   return rb_str_substr(str, FIX2INT(beg), FIX2INT(len));
 }

+VALUE ss_rstring_see(VALUE self, VALUE str) {
+  return rb_str_new2(RSTRING(str)->ptr);
+}
+
+VALUE ss_rstring_assign_foo(VALUE self, VALUE str) {
+  RSTRING(str)->len = 3;
+  RSTRING(str)->ptr = ALLOC_N(char, 4);
+  memcpy(RSTRING(str)->ptr, "foo", 4);
+  return Qnil;
+}
+
+VALUE ss_rstring_assign_global_foobar(VALUE self) {
+  VALUE var = rb_gv_get("$global_rstring_test");
+  RSTRING(var)->len = 6;
+  RSTRING(var)->ptr = ALLOC_N(char, 7);
+  memcpy(RSTRING(var)->ptr, "foobar", 7);
+  return Qnil;
+}
+
+VALUE ss_rstring_set_len(VALUE self, VALUE str, VALUE len) {
+  RSTRING(str)->len = NUM2INT(len);
+  return Qnil;
+}
+
+VALUE ss_rstring_assign_foo_and_upcase(VALUE self, VALUE str) {
+  RSTRING(str)->len = 3;
+  RSTRING(str)->ptr = ALLOC_N(char, 4);
+  memcpy(RSTRING(str)->ptr, "foo", 4);
+  rb_funcall(str, rb_intern("upcase!"), 0, 0);
+  return Qnil;
+}
+
 void Init_subtend_string() {
   VALUE cls;
   cls = rb_define_class("SubtendString", rb_cObject);
@@ -79,4 +111,9 @@ void Init_subtend_string() {
   rb_define_method(cls, "rb_str2inum", ss_str2inum, 2);
   rb_define_method(cls, "rb_cstr2inum", ss_cstr2inum, 1);
   rb_define_method(cls, "rb_str_substr", ss_str_substr, 3);
+  rb_define_method(cls, "rb_rstring_see", ss_rstring_see, 1);
+  rb_define_method(cls, "rb_rstring_assign_foo", ss_rstring_assign_foo, 1);
+  rb_define_method(cls, "rb_rstring_assign_global_foobar", ss_rstring_assign_global_foobar, 0);
+  rb_define_method(cls, "rb_rstring_set_len", ss_rstring_set_len, 2);
+  rb_define_method(cls, "rb_rstring_assign_foo_and_upcase", ss_rstring_assign_foo_and_upcase, 1);
 }
diff --git a/spec/subtend/string_spec.rb b/spec/subtend/string_spec.rb
index be2865f..8d6d818 100644
--- a/spec/subtend/string_spec.rb
+++ b/spec/subtend/string_spec.rb
@@ -77,4 +77,28 @@ describe "SubtendString" do
     end
   end

+  it "RSTRING(str)->ptr should return the string on the object" do
+    @s.rb_rstring_see("foo").should == "foo"
+  end
+
+  it "Changing RSTRING(str)->ptr should change the string" do
+    t = "a"
+    @s.rb_rstring_assign_foo(t)
+    t.should == "foo"
+    $global_rstring_test = "b"
+    @s.rb_rstring_assign_global_foobar()
+    $global_rstring_test.should == "foobar"
+  end
+
+  it "Reducing RSTRING(str)->len should cut the string" do
+    t = "12345"
+    @s.rb_rstring_set_len(t, 3)
+    t.should == "123"
+  end
+
+  it "Changing RSTRING(str)->ptr and calling upcase! should change the string and upcase it" do
+    t = ""
+    @s.rb_rstring_assign_foo_and_upcase(t)
+    t.should == "FOO"
+  end
 end