Index: libcfa/src/containers/string_res.cfa
===================================================================
--- libcfa/src/containers/string_res.cfa	(revision 4b3b35268036d5be3e8438aaad76482a170b2560)
+++ libcfa/src/containers/string_res.cfa	(revision 804bf6779b6e4f0147f60446d70db7ced6f81ec8)
@@ -48,5 +48,5 @@
 static inline void reduce( VbyteHeap &, int );			// reduce the size of the byte area
 
-static inline void ?{}( VbyteHeap &, int = 1000 );
+static inline void ?{}( VbyteHeap &, size_t = 1000 );
 static inline void ^?{}( VbyteHeap & );
 static inline void ByteCopy( char *, int, int, char *, int, int ); // copy a block of bytes from one location in the heap to another
@@ -62,5 +62,5 @@
 // Allocate the storage for the variable sized area and intialize the heap variables.
 
-static inline void ?{}( VbyteHeap & this, int Size ) with(this) {
+static inline void ?{}( VbyteHeap & this, size_t Size ) with(this) {
 #ifdef VbyteDebug
     serr | "enter:VbyteHeap::VbyteHeap, this:" | &this | " Size:" | Size;
@@ -149,5 +149,5 @@
     (older){ ambient_string_sharectx };
     if ( mode == NEW_SHARING ) {
-        (activeHeap){ new( 1000 ) };
+        (activeHeap){ new( (size_t) 1000 ) };
     } else {
         verify( mode == NO_SHARING );
@@ -217,6 +217,11 @@
 // Empty constructor
 void ?{}(string_res &s) with(s) {
-    assert( ambient_string_sharectx->activeHeap && "Need to implement private contexts" );
-    (Handle){ * ambient_string_sharectx->activeHeap };
+    if( ambient_string_sharectx->activeHeap ) {
+        (Handle){ * ambient_string_sharectx->activeHeap };
+        (shareEditSet_owns_ulink){ false };
+    } else {
+        (Handle){ * new( (size_t) 10 ) };  // TODO: can I lazily avoid allocating for empty string
+        (shareEditSet_owns_ulink){ true };
+    }
     s.shareEditSet_prev = &s;
     s.shareEditSet_next = &s;
@@ -224,6 +229,11 @@
 
 static inline void eagerCopyCtorHelper(string_res &s, const char* rhs, size_t rhslnth) with(s) {
-    assert( ambient_string_sharectx->activeHeap && "Need to implement private contexts" );
-    (Handle){ * ambient_string_sharectx->activeHeap };
+    if( ambient_string_sharectx->activeHeap ) {
+        (Handle){ * ambient_string_sharectx->activeHeap };
+        (shareEditSet_owns_ulink){ false };
+    } else {
+        (Handle){ * new( rhslnth ) };
+        (shareEditSet_owns_ulink){ true };
+    }
     Handle.s = VbyteAlloc(*Handle.ulink, rhslnth);
     Handle.lnth = rhslnth;
@@ -248,6 +258,4 @@
 void ?{}(string_res &s, const string_res & s2, StrResInitMode mode, size_t start, size_t end ) {
 
-    assert( ambient_string_sharectx->activeHeap && "Need to implement private contexts" );
-
     verify( start <= end && end <= s2.Handle.lnth );
 
@@ -258,4 +266,5 @@
         s.Handle.lnth = end - start;
         s.Handle.ulink = ambient_string_sharectx->activeHeap;
+        (s.shareEditSet_owns_ulink){ false };
         AddThisAfter(s.Handle, s2.Handle );			// insert this handle after rhs handle
         // ^ bug?  skip others at early point in string
@@ -396,4 +405,5 @@
             Handle.s = VbyteAlloc(*Handle.ulink, rhslnth);
             Handle.lnth = rhslnth;
+            (s.shareEditSet_owns_ulink){ false };
             for ( int i = 0; i < rhslnth; i += 1 ) {		// copy characters
                 Handle.s[i] = rhs[i];
@@ -464,4 +474,8 @@
     // s.shareEditSet_next = &s;
     // s.shareEditSet_prev = &s;
+
+    if (shareEditSet_owns_ulink && s.shareEditSet_next == &s) { // last one out
+        delete( s.Handle.ulink );
+    }
 }
 
Index: libcfa/src/containers/string_res.hfa
===================================================================
--- libcfa/src/containers/string_res.hfa	(revision 4b3b35268036d5be3e8438aaad76482a170b2560)
+++ libcfa/src/containers/string_res.hfa	(revision 804bf6779b6e4f0147f60446d70db7ced6f81ec8)
@@ -43,4 +43,5 @@
 struct string_res {
     HandleNode Handle; // chars, start, end, global neighbours
+    bool shareEditSet_owns_ulink;
     string_res * shareEditSet_prev;
     string_res * shareEditSet_next;
Index: tests/collections/.expect/string-ctx-manage.txt
===================================================================
--- tests/collections/.expect/string-ctx-manage.txt	(revision 4b3b35268036d5be3e8438aaad76482a170b2560)
+++ tests/collections/.expect/string-ctx-manage.txt	(revision 804bf6779b6e4f0147f60446d70db7ced6f81ec8)
@@ -3,3 +3,4 @@
 hi
 bye
+hi
 done
Index: tests/collections/string-ctx-manage.cfa
===================================================================
--- tests/collections/string-ctx-manage.cfa	(revision 4b3b35268036d5be3e8438aaad76482a170b2560)
+++ tests/collections/string-ctx-manage.cfa	(revision 804bf6779b6e4f0147f60446d70db7ced6f81ec8)
@@ -24,5 +24,5 @@
     sout | y; // hi
 
-    x = "bye";                                                     //.... Bookmark 9/30 shallow:  surprisingly this step failed
+    x = "bye";
     y = x; // y was already in different context => eager copy
     assert( y.inner->Handle.s != x.inner->Handle.s);
@@ -30,21 +30,26 @@
 }
 
-void failSoloAlloc() {
+void soloAlloc() {
     string x = "hi";
     string_sharectx c = { NO_SHARING };
+    
+    string y = x; // y allocates into private pad, implying eager copy
+    assert( y.inner->Handle.s != x.inner->Handle.s);
+    sout | y; // hi
 
-    // want: allocation into private pad, with forced eager copy into it
-    // got: assertion failure, "Need to implement private contexts"
-    string y = x;
+    // -- following hits "need to implement actual growth"
+    //    and it passes if I modify string_res.cfa to oversize the owned heaps
+
+    // x = "bye";
+    // y = x; // into private y => eager copy
+    // assert( y.inner->Handle.s != x.inner->Handle.s);
+    // sout | y; // bye
 }
 
-volatile bool showFail = false;
 
 int main() {
     baseline();
     eagerCopy();
-    if (showFail) {
-        failSoloAlloc();
-    }
+    soloAlloc();
     printf("done\n");
 }
