Index: libcfa/src/collections/string.cfa
===================================================================
--- libcfa/src/collections/string.cfa	(revision 06280adaadd325290fe5bd8958152ae76cb84100)
+++ libcfa/src/collections/string.cfa	(revision e891349fb7fcd052e543e9f994ba7bdc3f0ddad6)
@@ -103,4 +103,11 @@
 }
 
+void assign(string & s, const string & c, size_t n) {
+    assign(*s.inner, *c.inner, n);
+}
+void assign(string & s, const char * c, size_t n) {
+    assign(*s.inner, c, n);
+}
+
 
 ////////////////////////////////////////////////////////
@@ -205,6 +212,14 @@
 }
 
+void append(string & s, const string & s2, size_t maxlen) {
+    append( (*s.inner), (*s2.inner), maxlen );
+}
+
 void ?+=?(string & s, const char * c) {
     (*s.inner) += c;
+}
+
+void append(string & s, const char * buffer, size_t bsize) {
+    append( (*s.inner), buffer, bsize );
 }
 
Index: libcfa/src/collections/string.hfa
===================================================================
--- libcfa/src/collections/string.hfa	(revision 06280adaadd325290fe5bd8958152ae76cb84100)
+++ libcfa/src/collections/string.hfa	(revision e891349fb7fcd052e543e9f994ba7bdc3f0ddad6)
@@ -36,16 +36,21 @@
 void ?{}(string & s, string & s2);
 
-void ?{}(string & s, const char);
+void ?{}(string & s, char);
 void ?{}(string & s, const char * c); // copy from string literal (NULL-terminated)
 void ?{}(string & s, const char * c, size_t size); // copy specific length from buffer
 
 void ?=?(string & s, const char * c); // copy assignment from literal
-static inline string & strcpy(string & s, const char * c) { s = c; return s; }
-static inline string & strncpy(string & s, const char * c, size_t n) { s = c; return s; }
 void ?=?(string & s, const string & c);
-static inline string & strcpy(string & s, const string c) { s = c; return s; }
 void ?=?(string & s, char c);
 string & ?=?(string & s, string & c);  // surprising ret seems to help avoid calls to autogen
+void assign(string & s, const string & c, size_t n);
+void assign(string & s, const char * c, size_t n);
 //string ?=?( string &, string ) = void;
+
+static inline string & strcpy(string & s, const char * c) { s = c; return s; }
+static inline string & strncpy(string & s, const char * c, size_t n) { assign( s, c, n); return s; }
+static inline string & strcpy(string & s, const string & c) { s = c; return s; }
+static inline string & strncpy(string & s, const string & c, size_t n) { assign(s, c, n); return s; }
+
 void ^?{}(string & s);
 
@@ -104,11 +109,17 @@
 void ?+=?(string & s, char c); // append a character
 void ?+=?(string & s, const string & s2); // append-concatenate to first string
-static inline string & strcat(string & s, const string & s2) { s += s2; return s; }
-void ?+=?(string & s, const char * s2); // append-concatenate to first string
-static inline string & strcat(string & s, const char * c) { s += c; return s; }
+void append(string & s, const string & s2, size_t maxlen);  // append-concatenate to first string, up to maxlen
+void ?+=?(string & s, const char * s2); // append-concatenate NULL-terminated string to first string
+void append(string & s, const char * buffer, size_t bsize);  // append-concatenate given range to first string
+
 string ?+?(const string & s, char c); // add a character to a copy of the string
 string ?+?(const string & s, const string & s2); // copy and concatenate both strings
-string ?+?(const char * s1, const char * s2); // concatenate both strings
+string ?+?(const char * s1, const char * s2); // copy and concatenate both strings
 string ?+?(const string & s, const char * c); // copy and concatenate with NULL-terminated string
+
+static inline string & strcat(string & s, const string & s2) { s += s2; return s; }
+static inline string & strcat(string & s, const char * c) { s += c; return s; }
+static inline string & strncat(string & s, const string & s2, size_t maxlen) { append(s, s2, maxlen); return s; }
+static inline string & strncat(string & s, const char * buffer, size_t bsize) { append(s, buffer, bsize); return s; }
 
 // Repetition
Index: libcfa/src/collections/string_res.cfa
===================================================================
--- libcfa/src/collections/string_res.cfa	(revision 06280adaadd325290fe5bd8958152ae76cb84100)
+++ libcfa/src/collections/string_res.cfa	(revision e891349fb7fcd052e543e9f994ba7bdc3f0ddad6)
@@ -563,4 +563,8 @@
 }
 
+string_res & assign(string_res & s, const string_res & src, size_t maxlen) {
+    return assign_(s, src.Handle.s, min(src.Handle.lnth, maxlen), *0p);
+}
+
 string_res & assign(string_res & s, const char * buffer, size_t bsize) {
     return assign_(s, buffer, bsize, *0p);
@@ -637,8 +641,14 @@
 }
 
+void append(string_res & str1, const string_res & str2, size_t maxlen) {
+    append( str1, str2.Handle.s, min(str2.Handle.lnth, maxlen) );
+}
+
 void ?+=?(string_res & s, char c) {
     append( s, & c, 1 );
 }
-
+void ?+=?(string_res & s, const char * c) {
+    append( s, c, strlen(c) );
+}
 
 ///////////////////////////////////////////////////////////////////
Index: libcfa/src/collections/string_res.hfa
===================================================================
--- libcfa/src/collections/string_res.hfa	(revision 06280adaadd325290fe5bd8958152ae76cb84100)
+++ libcfa/src/collections/string_res.hfa	(revision e891349fb7fcd052e543e9f994ba7bdc3f0ddad6)
@@ -88,4 +88,5 @@
 }
 
+string_res & assign(string_res & s, const string_res & src, size_t maxlen); // copy specific length from other string
 string_res & assign(string_res & s, const char * buffer, size_t bsize); // copy specific length from buffer
 static inline string_res & ?=?(string_res & s, const char * c) {  // copy from string literal (NULL-terminated)
@@ -129,10 +130,14 @@
 
 // Concatenation
+void ?+=?(string_res & s, const string_res & s2);
+void ?+=?(string_res & s, char c);
+void append(string_res & s, const string_res & s2, size_t maxlen);
+void ?+=?(string_res & s, const char * c);
 void append(string_res & s, const char * buffer, size_t bsize);
-void ?+=?(string_res & s, char c); // append a character
-void ?+=?(string_res & s, const string_res & s2); // append-concatenate to first string
-static inline void ?+=?(string_res & s, const char * c) {
-    append( s, c, strlen(c) );
-}
+
+static inline string_res & strcat(string_res & s, const string_res & s2) { s += s2; return s; }
+static inline string_res & strcat(string_res & s, const char * c) { s += c; return s; }
+static inline string_res & strncat(string_res & s, const string_res & s2, size_t maxlen) { append(s, s2, maxlen); return s; }
+static inline string_res & strncat(string_res & s, const char * buffer, size_t bsize) { append(s, buffer, bsize); return s; }
 
 // Repetition
