Index: libcfa/src/containers/string.cfa
===================================================================
--- libcfa/src/containers/string.cfa	(revision 0f781fb89ac90634a87242ab226c285456c417bf)
+++ libcfa/src/containers/string.cfa	(revision 4b3b35268036d5be3e8438aaad76482a170b2560)
@@ -92,5 +92,5 @@
 }
 
-string ?=?(string & this, string other) {
+string & ?=?(string & this, string & other) { //// <---- straw man change
     (*this.inner) = (*other.inner);
     return this;
Index: libcfa/src/containers/string.hfa
===================================================================
--- libcfa/src/containers/string.hfa	(revision 0f781fb89ac90634a87242ab226c285456c417bf)
+++ libcfa/src/containers/string.hfa	(revision 4b3b35268036d5be3e8438aaad76482a170b2560)
@@ -41,6 +41,6 @@
 void ?=?(string &s, const string &other);
 void ?=?(string &s, char other);
-string ?=?(string &s, string other);  // string tolerates memcpys; still saw calls to autogen 
-
+string & ?=?(string &s, string &other);  // surprising ret seems to help avoid calls to autogen
+//string ?=?( string &, string ) = void;
 void ^?{}(string &s);
 
Index: libcfa/src/containers/string_res.cfa
===================================================================
--- libcfa/src/containers/string_res.cfa	(revision 0f781fb89ac90634a87242ab226c285456c417bf)
+++ libcfa/src/containers/string_res.cfa	(revision 4b3b35268036d5be3e8438aaad76482a170b2560)
@@ -223,6 +223,5 @@
 }
 
-// Constructor from a raw buffer and size
-void ?{}(string_res &s, const char* rhs, size_t rhslnth) with(s) {
+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 };
@@ -236,4 +235,9 @@
 }
 
+// Constructor from a raw buffer and size
+void ?{}(string_res &s, const char* rhs, size_t rhslnth) with(s) {
+    eagerCopyCtorHelper(s, rhs, rhslnth);
+}
+
 // String literal constructor
 void ?{}(string_res &s, const char* rhs) {
@@ -245,67 +249,45 @@
 
     assert( ambient_string_sharectx->activeHeap && "Need to implement private contexts" );
-    assert( s2.Handle.ulink == ambient_string_sharectx->activeHeap && "need to implement context crossing");
 
     verify( start <= end && end <= s2.Handle.lnth );
 
-    (s.Handle){};
-    s.Handle.s = s2.Handle.s + start;
-    s.Handle.lnth = end - start;
-    s.Handle.ulink = ambient_string_sharectx->activeHeap;
-    AddThisAfter(s.Handle, s2.Handle );			// insert this handle after rhs handle
-    // ^ bug?  skip others at early point in string
+    if (s2.Handle.ulink == ambient_string_sharectx->activeHeap) {
+        // same heap: allow overlap
+        (s.Handle){};
+        s.Handle.s = s2.Handle.s + start;
+        s.Handle.lnth = end - start;
+        s.Handle.ulink = ambient_string_sharectx->activeHeap;
+        AddThisAfter(s.Handle, s2.Handle );			// insert this handle after rhs handle
+        // ^ bug?  skip others at early point in string
     
-    if (mode == COPY_VALUE) {
-        // make s alone in its shareEditSet
-        s.shareEditSet_prev = &s;
-        s.shareEditSet_next = &s;
+        if (mode == COPY_VALUE) {
+            // make s alone in its shareEditSet
+            s.shareEditSet_prev = &s;
+            s.shareEditSet_next = &s;
+        } else {
+            verify( mode == SHARE_EDITS );
+
+            // s2 is logically const but not implementation const
+            string_res & s2mod = (string_res &) s2;
+
+            // insert s after s2 on shareEditSet
+            s.shareEditSet_next = s2mod.shareEditSet_next;
+            s.shareEditSet_prev = &s2mod;
+            s.shareEditSet_next->shareEditSet_prev = &s;
+            s.shareEditSet_prev->shareEditSet_next = &s;
+        }
     } else {
-        verify( mode == SHARE_EDITS );
-
-        // s2 is logically const but not implementation const
-        string_res & s2mod = (string_res &) s2;
-
-        // insert s after s2 on shareEditSet
-        s.shareEditSet_next = s2mod.shareEditSet_next;
-        s.shareEditSet_prev = &s2mod;
-        s.shareEditSet_next->shareEditSet_prev = &s;
-        s.shareEditSet_prev->shareEditSet_next = &s;
-    }
-}
-
-void assign(string_res &this, const char* buffer, size_t bsize) {
-
-    // traverse the incumbent share-edit set (SES) to recover the range of a base string to which `this` belongs
-    string_res * shareEditSetStartPeer = & this;
-    string_res * shareEditSetEndPeer = & this;
-    for (string_res * editPeer = this.shareEditSet_next; editPeer != &this; editPeer = editPeer->shareEditSet_next) {
-        if ( editPeer->Handle.s < shareEditSetStartPeer->Handle.s ) {
-            shareEditSetStartPeer = editPeer;
-        }
-        if ( shareEditSetEndPeer->Handle.s + shareEditSetEndPeer->Handle.lnth < editPeer->Handle.s + editPeer->Handle.lnth) {
-            shareEditSetEndPeer = editPeer;
-        }
-    }
-
-    // full string is from start of shareEditSetStartPeer thru end of shareEditSetEndPeer
-    // `this` occurs in the middle of it, to be replaced
-    // build up the new text in `pasting`
-
-    string_res pasting = {
-        shareEditSetStartPeer->Handle.s,                   // start of SES
-        this.Handle.s - shareEditSetStartPeer->Handle.s }; // length of SES, before this
-    append( pasting,
-        buffer,                                            // start of replacement for this
-        bsize );                                           // length of replacement for this
-    append( pasting,
-        this.Handle.s + this.Handle.lnth,                  // start of SES after this
-        shareEditSetEndPeer->Handle.s + shareEditSetEndPeer->Handle.lnth -
-        (this.Handle.s + this.Handle.lnth) );              // length of SES, after this
-
-    // The above string building can trigger compaction.
-    // The reference points (that are arguments of the string building) may move during that building.
-    // From this point on, they are stable.
-    // So now, capture their values for use in the overlap cases, below.
-    // Do not factor these definitions with the arguments used above.
+        // crossing heaps: eager copy
+        assert( mode == COPY_VALUE && "need to solidify context-crossing rules for requesting shared edits");
+        eagerCopyCtorHelper(s, s2.Handle.s + start, end - start);
+        verify(s.shareEditSet_prev == &s);
+        verify(s.shareEditSet_next == &s);
+    }
+}
+
+static void assignEditSet(string_res & this, string_res * shareEditSetStartPeer, string_res * shareEditSetEndPeer,
+    char * resultSesStart,
+    size_t resultSesLnth,
+    HandleNode * resultPadPosition, size_t bsize ) {
 
     char * beforeBegin = shareEditSetStartPeer->Handle.s;
@@ -317,10 +299,10 @@
     size_t oldLnth = this.Handle.lnth;
 
-    this.Handle.s = pasting.Handle.s + beforeLen;
+    this.Handle.s = resultSesStart + beforeLen;
     this.Handle.lnth = bsize;
-    MoveThisAfter( this.Handle, pasting.Handle );
+    MoveThisAfter( this.Handle, *resultPadPosition );
 
     // adjust all substring string and handle locations, and check if any substring strings are outside the new base string
-    char *limit = pasting.Handle.s + pasting.Handle.lnth;
+    char *limit = resultSesStart + resultSesLnth;
     for (string_res * p = this.shareEditSet_next; p != &this; p = p->shareEditSet_next) {
         verify (p->Handle.s >= beforeBegin);
@@ -353,5 +335,5 @@
             // take start as start-anchored
             size_t startOffsetFromStart = p->Handle.s - beforeBegin;
-            p->Handle.s = pasting.Handle.s + startOffsetFromStart;
+            p->Handle.s = resultSesStart + startOffsetFromStart;
         } else {
             verify ( p->Handle.s < afterBegin );
@@ -371,6 +353,85 @@
             }
         }
-        MoveThisAfter( p->Handle, pasting.Handle );	// move substring handle to maintain sorted order by string position
-    }
+        MoveThisAfter( p->Handle, *resultPadPosition );	// move substring handle to maintain sorted order by string position
+    }
+}
+
+static void assign_(string_res &this, const char* buffer, size_t bsize, const string_res & valSrc) {
+
+    // traverse the incumbent share-edit set (SES) to recover the range of a base string to which `this` belongs
+    string_res * shareEditSetStartPeer = & this;
+    string_res * shareEditSetEndPeer = & this;
+    for (string_res * editPeer = this.shareEditSet_next; editPeer != &this; editPeer = editPeer->shareEditSet_next) {
+        if ( editPeer->Handle.s < shareEditSetStartPeer->Handle.s ) {
+            shareEditSetStartPeer = editPeer;
+        }
+        if ( shareEditSetEndPeer->Handle.s + shareEditSetEndPeer->Handle.lnth < editPeer->Handle.s + editPeer->Handle.lnth) {
+            shareEditSetEndPeer = editPeer;
+        }
+    }
+
+    verify( shareEditSetEndPeer->Handle.s >= shareEditSetStartPeer->Handle.s );
+    size_t editSetLength = shareEditSetEndPeer->Handle.s + shareEditSetEndPeer->Handle.lnth - shareEditSetStartPeer->Handle.s;
+    verify( editSetLength >= this.Handle.lnth );
+
+
+    if ( this.Handle.lnth == editSetLength                // the entire run of the share-edit set is being overwritten: SES's result will only use characters from the source string
+        && & valSrc                                       // sourcing from a managed string
+        && valSrc.Handle.ulink == this.Handle.ulink  ) {  // sourcing from same heap
+
+        assignEditSet(this, shareEditSetStartPeer, shareEditSetEndPeer, 
+            valSrc.Handle.s,
+            valSrc.Handle.lnth,
+            &((string_res&)valSrc).Handle, bsize);
+        
+    } else {
+
+        // full string is from start of shareEditSetStartPeer thru end of shareEditSetEndPeer
+        // `this` occurs in the middle of it, to be replaced
+        // build up the new text in `pasting`
+
+        // super private string ctor: ignore ambient context
+        void ?{}( string_res &s, VbyteHeap & heap, const char* rhs, size_t rhslnth ) with(s) {
+            (Handle){ heap };
+            Handle.s = VbyteAlloc(*Handle.ulink, rhslnth);
+            Handle.lnth = rhslnth;
+            for ( int i = 0; i < rhslnth; i += 1 ) {		// copy characters
+                Handle.s[i] = rhs[i];
+            } // for
+            s.shareEditSet_prev = &s;
+            s.shareEditSet_next = &s;
+        }
+
+        // we are only overwriting a proper substring of some string: need to mash characters from old and new together
+        // OR we are importing characters: need to copy eagerly
+        string_res pasting = {
+            * this.Handle.ulink,                               // maintain same heap, regardless of context
+            shareEditSetStartPeer->Handle.s,                   // start of SES
+            this.Handle.s - shareEditSetStartPeer->Handle.s }; // length of SES, before this
+        append( pasting,
+            buffer,                                            // start of replacement for this
+            bsize );                                           // length of replacement for this
+        append( pasting,
+            this.Handle.s + this.Handle.lnth,                  // start of SES after this
+            shareEditSetEndPeer->Handle.s + shareEditSetEndPeer->Handle.lnth -
+            (this.Handle.s + this.Handle.lnth) );              // length of SES, after this
+
+        // The above string building can trigger compaction.
+        // The reference points (that are arguments of the string building) may move during that building.
+        // From this point on, they are stable.
+
+        assignEditSet(this, shareEditSetStartPeer, shareEditSetEndPeer, 
+            pasting.Handle.s,
+            pasting.Handle.lnth,
+            &pasting.Handle, bsize);
+    }
+
+    // So now, capture their values for use in the overlap cases, below.
+    // Do not factor these definitions with the arguments used in string building above.
+
+}
+
+void assign(string_res &this, const char* buffer, size_t bsize) {
+    assign_(this, buffer, bsize, *0p);
 }
 
@@ -385,5 +446,5 @@
 // Copy assignment operator
 void ?=?(string_res & this, const string_res & rhs) with( this ) {
-    assign(this, rhs.Handle.s, rhs.Handle.lnth);
+    assign_(this, rhs.Handle.s, rhs.Handle.lnth, rhs);
 }
 
