diff --git a/ipaacalib/cpp/include/ipaaca/ipaaca-payload.h b/ipaacalib/cpp/include/ipaaca/ipaaca-payload.h
index 353bce4b01d06c353d7e20da9728844e700aa210..bd128c9569d62a54505e35c7bfa99e439db8fa50 100644
--- a/ipaacalib/cpp/include/ipaaca/ipaaca-payload.h
+++ b/ipaacalib/cpp/include/ipaaca/ipaaca-payload.h
@@ -55,6 +55,7 @@ IPAACA_HEADER_EXPORT template<> void pack_into_json_value(rapidjson::Value&, rap
 IPAACA_HEADER_EXPORT template<> void pack_into_json_value(rapidjson::Value&, rapidjson::Document::AllocatorType&, double);
 IPAACA_HEADER_EXPORT template<> void pack_into_json_value(rapidjson::Value&, rapidjson::Document::AllocatorType&, bool);
 IPAACA_HEADER_EXPORT template<> void pack_into_json_value(rapidjson::Value&, rapidjson::Document::AllocatorType&, const std::string&);
+IPAACA_HEADER_EXPORT template<> void pack_into_json_value(rapidjson::Value&, rapidjson::Document::AllocatorType&, const char*);
 
 IPAACA_HEADER_EXPORT template<typename T> void pack_into_json_value(rapidjson::Value& valueobject, rapidjson::Document::AllocatorType& allocator, const std::vector<T>& ts)
 {
@@ -102,104 +103,12 @@ IPAACA_HEADER_EXPORT class PayloadDocumentEntry//{{{
 		IPAACA_HEADER_EXPORT inline ~PayloadDocumentEntry() { IPAACA_INFO("") }
 		//IPAACA_HEADER_EXPORT PayloadDocumentEntry(const std::string& source): modified(false), json_source(source), {};
 		IPAACA_HEADER_EXPORT std::string to_json_string_representation();
-		static std::shared_ptr<PayloadDocumentEntry> from_json_string_representation(const std::string& input);
-		static std::shared_ptr<PayloadDocumentEntry> create_null();
-		std::shared_ptr<PayloadDocumentEntry> clone();
+		IPAACA_HEADER_EXPORT static std::shared_ptr<PayloadDocumentEntry> from_json_string_representation(const std::string& input);
+		IPAACA_HEADER_EXPORT static std::shared_ptr<PayloadDocumentEntry> create_null();
+		IPAACA_HEADER_EXPORT std::shared_ptr<PayloadDocumentEntry> clone();
+		IPAACA_HEADER_EXPORT rapidjson::Value& get_or_create_nested_value_from_proxy_path(PayloadEntryProxy* pep);
 	typedef std::shared_ptr<PayloadDocumentEntry> ptr;
 };
-//}}}
-IPAACA_HEADER_EXPORT class PayloadEntryProxy//{{{
-{
-	protected:
-		//IPAACA_MEMBER_VAR_EXPORT rapidjson::Document* _json_parent_node;
-		//IPAACA_MEMBER_VAR_EXPORT rapidjson::Document* _json_node;
-		IPAACA_MEMBER_VAR_EXPORT Payload* _payload;
-		IPAACA_MEMBER_VAR_EXPORT std::string _key;
-		//
-		// new json stuff / hierarchical navigation
-		//
-		PayloadEntryProxy* parent; // parent (up to document root -> then null)
-		PayloadDocumentEntry::ptr document_entry; // contains lock and json Doc
-		bool existent; // whether Value exists already (or blindly navigated)
-		bool addressed_as_array; // whether long or string navigation used
-		long addressed_index;
-		std::string addressed_key;
-		/// currently navigated value in json tree (or a new Null value)
-		rapidjson::Value* json_value;
-	protected:
-		IPAACA_HEADER_EXPORT void connect_to_existing_parents();
-	public:
-		// constructor to create a new top-most parent proxy (from a payload key)
-		IPAACA_HEADER_EXPORT PayloadEntryProxy(Payload* payload, const std::string& key);
-		// constructors for navigation through objects
-		IPAACA_HEADER_EXPORT PayloadEntryProxy(PayloadEntryProxy* parent, const std::string& addressed_key);
-		IPAACA_HEADER_EXPORT PayloadEntryProxy(PayloadEntryProxy* parent, size_t addressed_index);
-	public:
-		IPAACA_HEADER_EXPORT PayloadEntryProxy operator[](size_t index); // array-style navigation
-		IPAACA_HEADER_EXPORT PayloadEntryProxy operator[](const std::string& key);
-		//                   
-		IPAACA_HEADER_EXPORT PayloadEntryProxy& operator=(const std::string& value);
-		IPAACA_HEADER_EXPORT PayloadEntryProxy& operator=(const char* value);
-		IPAACA_HEADER_EXPORT PayloadEntryProxy& operator=(double value);
-		IPAACA_HEADER_EXPORT PayloadEntryProxy& operator=(bool value);
-		
-		IPAACA_HEADER_EXPORT operator std::string();
-		IPAACA_HEADER_EXPORT operator long();
-		IPAACA_HEADER_EXPORT operator double();
-		IPAACA_HEADER_EXPORT operator bool();
-		IPAACA_HEADER_EXPORT template<typename Inner> operator std::vector<Inner>() {
-			if ((!json_value) || (!json_value->IsArray())) throw PayloadAddressingError();
-			std::vector<Inner> result;
-			for (auto it = json_value->Begin(); it != json_value->End(); ++it) {
-				result.push_back( json_value_cast<Inner>(*it) );
-			}
-			return result;
-		}
-		IPAACA_HEADER_EXPORT template<typename Inner> operator std::list<Inner>() {
-			if ((!json_value) || (!json_value->IsArray())) throw PayloadAddressingError();
-			std::list<Inner> result;
-			for (auto it = json_value->Begin(); it != json_value->End(); ++it) {
-				result.push_back( json_value_cast<Inner>(*it) );
-			}
-			return result;
-		}
-		IPAACA_HEADER_EXPORT template<typename Inner> operator std::map<std::string, Inner>() {
-			if ((!json_value) || (!json_value->IsObject())) throw PayloadAddressingError();
-			std::map<std::string, Inner> result;
-			for (auto it = json_value->MemberBegin(); it != json_value->MemberEnd(); ++it) {
-				result[std::string(it->name.GetString())] = json_value_cast<Inner>(it->value);
-			}
-			return result;
-		}
-		// FIXME why are these needed again?
-		IPAACA_HEADER_EXPORT std::string to_str();
-		//long to_int() { return operator long(); ;
-		IPAACA_HEADER_EXPORT long to_long();
-		IPAACA_HEADER_EXPORT double to_float();
-		IPAACA_HEADER_EXPORT bool to_bool();
-		// getters
-		IPAACA_HEADER_EXPORT template<typename T> T get() { return json_value_cast<T>(json_value); } // specializations below
-		// setters
-		IPAACA_HEADER_EXPORT template<typename T> PayloadEntryProxy& set(T t);
-		/*{
-			pack_into_json_value<T>(t);
-			connect_to_existing_parents();
-			_payload->set(key, document_entry->document);
-		}*/
-};
-// Available interpretations of payload entries (or children thereof) below.
-//  Usage of standard complex data structures (vector etc.) currently entails
-//  casting all entries to a uniform type (a-priori choice: std::string).
-/*
-IPAACA_HEADER_EXPORT template<> long PayloadEntryProxy::get();
-IPAACA_HEADER_EXPORT template<> double PayloadEntryProxy::get();
-IPAACA_HEADER_EXPORT template<> bool PayloadEntryProxy::get();
-IPAACA_HEADER_EXPORT template<> std::string PayloadEntryProxy::get();
-IPAACA_HEADER_EXPORT template<> std::vector<std::string> PayloadEntryProxy::get();
-IPAACA_HEADER_EXPORT template<> std::list<std::string> PayloadEntryProxy::get();
-IPAACA_HEADER_EXPORT template<> std::map<std::string, std::string> PayloadEntryProxy::get();
-*/
-
 //}}}
 
 /*
@@ -300,4 +209,110 @@ IPAACA_HEADER_EXPORT class Payload//{{{
 	typedef boost::shared_ptr<Payload> ptr;
 };//}}}
 
+IPAACA_HEADER_EXPORT class PayloadEntryProxy//{{{
+{
+	protected:
+	public:
+		//IPAACA_MEMBER_VAR_EXPORT rapidjson::Document* _json_parent_node;
+		//IPAACA_MEMBER_VAR_EXPORT rapidjson::Document* _json_node;
+		IPAACA_MEMBER_VAR_EXPORT Payload* _payload;
+		IPAACA_MEMBER_VAR_EXPORT std::string _key;
+		//
+		// new json stuff / hierarchical navigation
+		//
+		IPAACA_MEMBER_VAR_EXPORT PayloadEntryProxy* parent; // parent (up to document root -> then null)
+		IPAACA_MEMBER_VAR_EXPORT PayloadDocumentEntry::ptr document_entry; // contains lock and json Doc
+		IPAACA_MEMBER_VAR_EXPORT bool existent; // whether Value exists already (or blindly navigated)
+		IPAACA_MEMBER_VAR_EXPORT bool addressed_as_array; // whether long or string navigation used
+		IPAACA_MEMBER_VAR_EXPORT long addressed_index;
+		IPAACA_MEMBER_VAR_EXPORT std::string addressed_key;
+		/// currently navigated value in json tree (or a new Null value)
+		IPAACA_MEMBER_VAR_EXPORT rapidjson::Value* json_value;
+/*	protected:
+		IPAACA_HEADER_EXPORT void connect_to_existing_parents();
+*/
+	public:
+		// constructor to create a new top-most parent proxy (from a payload key)
+		IPAACA_HEADER_EXPORT PayloadEntryProxy(Payload* payload, const std::string& key);
+		// constructors for navigation through objects
+		IPAACA_HEADER_EXPORT PayloadEntryProxy(PayloadEntryProxy* parent, const std::string& addressed_key);
+		IPAACA_HEADER_EXPORT PayloadEntryProxy(PayloadEntryProxy* parent, size_t addressed_index);
+	public:
+		IPAACA_HEADER_EXPORT PayloadEntryProxy operator[](size_t index); // array-style navigation
+		IPAACA_HEADER_EXPORT PayloadEntryProxy operator[](const std::string& key);
+		IPAACA_HEADER_EXPORT PayloadEntryProxy operator[](const char* key);
+		//                   
+		IPAACA_HEADER_EXPORT template<typename T> PayloadEntryProxy& operator=(T t)
+		{
+			PayloadDocumentEntry::ptr new_entry = document_entry->clone(); // copy-on-write, no lock required
+			rapidjson::Value& newval = new_entry->get_or_create_nested_value_from_proxy_path(this);
+			pack_into_json_value(newval, new_entry->document.GetAllocator(), t);
+			_payload->set(_key, new_entry);
+			return *this;
+		}
+		
+		//IPAACA_HEADER_EXPORT PayloadEntryProxy& operator=(const std::string& value);
+		//IPAACA_HEADER_EXPORT PayloadEntryProxy& operator=(const char* value);
+		//IPAACA_HEADER_EXPORT PayloadEntryProxy& operator=(double value);
+		//IPAACA_HEADER_EXPORT PayloadEntryProxy& operator=(bool value);
+		
+		IPAACA_HEADER_EXPORT operator std::string();
+		IPAACA_HEADER_EXPORT operator long();
+		IPAACA_HEADER_EXPORT operator double();
+		IPAACA_HEADER_EXPORT operator bool();
+		IPAACA_HEADER_EXPORT template<typename Inner> operator std::vector<Inner>() {
+			if ((!json_value) || (!json_value->IsArray())) throw PayloadAddressingError();
+			std::vector<Inner> result;
+			for (auto it = json_value->Begin(); it != json_value->End(); ++it) {
+				result.push_back( json_value_cast<Inner>(*it) );
+			}
+			return result;
+		}
+		IPAACA_HEADER_EXPORT template<typename Inner> operator std::list<Inner>() {
+			if ((!json_value) || (!json_value->IsArray())) throw PayloadAddressingError();
+			std::list<Inner> result;
+			for (auto it = json_value->Begin(); it != json_value->End(); ++it) {
+				result.push_back( json_value_cast<Inner>(*it) );
+			}
+			return result;
+		}
+		IPAACA_HEADER_EXPORT template<typename Inner> operator std::map<std::string, Inner>() {
+			if ((!json_value) || (!json_value->IsObject())) throw PayloadAddressingError();
+			std::map<std::string, Inner> result;
+			for (auto it = json_value->MemberBegin(); it != json_value->MemberEnd(); ++it) {
+				result[std::string(it->name.GetString())] = json_value_cast<Inner>(it->value);
+			}
+			return result;
+		}
+		// FIXME why are these needed again?
+		IPAACA_HEADER_EXPORT std::string to_str();
+		//long to_int() { return operator long(); ;
+		IPAACA_HEADER_EXPORT long to_long();
+		IPAACA_HEADER_EXPORT double to_float();
+		IPAACA_HEADER_EXPORT bool to_bool();
+		// getters
+		IPAACA_HEADER_EXPORT template<typename T> T get() { return json_value_cast<T>(json_value); } // specializations below
+		// setters
+		IPAACA_HEADER_EXPORT template<typename T> PayloadEntryProxy& set(T t);
+		/*{
+			pack_into_json_value<T>(t);
+			connect_to_existing_parents();
+			_payload->set(key, document_entry->document);
+		}*/
+};
+// Available interpretations of payload entries (or children thereof) below.
+//  Usage of standard complex data structures (vector etc.) currently entails
+//  casting all entries to a uniform type (a-priori choice: std::string).
+/*
+IPAACA_HEADER_EXPORT template<> long PayloadEntryProxy::get();
+IPAACA_HEADER_EXPORT template<> double PayloadEntryProxy::get();
+IPAACA_HEADER_EXPORT template<> bool PayloadEntryProxy::get();
+IPAACA_HEADER_EXPORT template<> std::string PayloadEntryProxy::get();
+IPAACA_HEADER_EXPORT template<> std::vector<std::string> PayloadEntryProxy::get();
+IPAACA_HEADER_EXPORT template<> std::list<std::string> PayloadEntryProxy::get();
+IPAACA_HEADER_EXPORT template<> std::map<std::string, std::string> PayloadEntryProxy::get();
+*/
+
+//}}}
+
 #endif
diff --git a/ipaacalib/cpp/src/ipaaca-fake.cc b/ipaacalib/cpp/src/ipaaca-fake.cc
index 0cb444beeb4906f9eeec45a06775c6e24a16adc2..df0354c931ab4e5e1dff4df41c02dc828ee95452 100644
--- a/ipaacalib/cpp/src/ipaaca-fake.cc
+++ b/ipaacalib/cpp/src/ipaaca-fake.cc
@@ -35,11 +35,15 @@
 
 namespace ipaaca {
 
-IPAACA_EXPORT inline FakeIU::FakeIU() { IPAACA_INFO("") }
+IPAACA_EXPORT inline FakeIU::FakeIU() {
+	IPAACA_INFO("")
+}
 IPAACA_EXPORT boost::shared_ptr<FakeIU> FakeIU::create()
 {
 	IPAACA_INFO("");
-	return boost::shared_ptr<FakeIU>(new FakeIU());
+	auto iu = boost::shared_ptr<FakeIU>(new FakeIU());
+	iu->_payload.initialize(iu);
+	return iu;
 }
 IPAACA_EXPORT void FakeIU::add_fake_payload_item(const std::string& key, PayloadDocumentEntry::ptr entry)
 {
diff --git a/ipaacalib/cpp/src/ipaaca-json.cc b/ipaacalib/cpp/src/ipaaca-json.cc
index d5dd285cc9b9aa6839da7bff1b25907998107adf..83ac873f7de2187baa0aecbb291b369db36d8d0d 100644
--- a/ipaacalib/cpp/src/ipaaca-json.cc
+++ b/ipaacalib/cpp/src/ipaaca-json.cc
@@ -34,6 +34,8 @@
 #include <ipaaca/ipaaca.h>
 #include <ipaaca/ipaaca-json.h>
 
+#include <iomanip>
+
 using namespace rapidjson;
 using namespace std;
 
@@ -131,179 +133,25 @@ int main(int argc, char** argv) {
 	//iu->payload()["b"] = "newEntry";
 	
 	//std::vector<long> vs = { 10, 20, 30, 40 };
-	std::map<std::string, double> vs = { {"A", 10}, {"B", 20}, {"C", 30}, {"D", 40} };
-	ipaaca::pack_into_json_value(entry->document, entry->document.GetAllocator(), vs);
-	{
+	//std::map<std::string, double> vs = { {"A", 10}, {"B", 20}, {"C", 30}, {"D", 40} };
+	//ipaaca::pack_into_json_value(entry->document, entry->document.GetAllocator(), vs);
+	std::cout << "Setting a value deep in the object:" << std::endl;
+	//iu->payload()["a"][(int)0] = "set by pep::op=";
+	iu->payload()["a"]["A"] = "set by pep::op=";
+	
+	std::cout << "Final payload (printed as strings):" << std::endl;
+	std::map<std::string, std::string> pl_flat = iu->payload();
+	for (auto& kv: pl_flat) {
+		std::cout << "  " << std::left << std::setw(15) << (kv.first+": ") << kv.second << std::endl;
+	}
+	/*{
 		StringBuffer buffer;
 		Writer<StringBuffer> writer(buffer);
 		entry->document.Accept(writer);
 		std::string docstring = buffer.GetString();
 		std::cout << "Final document:  " << docstring << std::endl;
-	}
+	}*/
 	
 	// Done
 	return 0;
-
-	////////////////////////////////////////////////////////////////////////////
-	// 1. Parse a JSON text string to a document.
-	const char json[] = " { \"hello\" : \"world\", \"t\" : true , \"f\" : false, \"n\": null, \"i\":123, \"pi\": 3.1416, \"a\":[1, 2, 3, 4], \"dict\":{\"s\":\"stringvalue\", \"arr\":[6, 7, \"test\"]} } ";
-	printf("Original JSON:\n %s\n", json);
-	
-	ipaaca::PayloadDocumentStore ds;
-	ds["document_test"] = std::make_shared<ipaaca::PayloadDocumentEntry>();
-	Document& document = ds["document_test"]->document;
-
-	//std::map<std::string, Document> documents;
-	//Document _document; // Default template parameter uses UTF8 and MemoryPoolAllocator.
-	//documents["document_test"] = std::move(_document);
-	//Document& document = documents["document_test"];
-	
-	printf("Check whether document contains 'none' initially ...");
-	assert(document.IsNull()); // initial state of object
-#if 1
-	// "normal" parsing, decode strings to new buffers. Can use other input stream via ParseStream().
-	if (document.Parse(json).HasParseError())
-		return 1;
-#else
-	// In-situ parsing, decode strings directly in the source string. Source must be string.
-	{
-		char buffer[sizeof(json)];
-		memcpy(buffer, json, sizeof(json));
-		if (document.ParseInsitu(buffer).HasParseError())
-			return 1;
-	}
-#endif
-	printf("\nParsing succeeded.\n");
-	////////////////////////////////////////////////////////////////////////////
-
-	assert(document.IsObject()); // testing dict here
-	assert(document.HasMember("dict"));
-	assert(document["dict"].IsObject());
-	assert(document["dict"].HasMember("s"));
-	assert(document["dict"]["s"].IsString());
-	assert(document["dict"].HasMember("arr"));
-	assert(document["dict"]["arr"].IsArray());
-	Value& arr = document["dict"]["arr"];
-	printf("dict.arr size: %d\n", arr.Size());
-	for (SizeType i = 0; i < arr.Size(); i++) {
-		if (arr[i].IsInt()) {
-			printf("a[%d] = %d\n", i, arr[i].GetInt());
-		} else {
-			printf("a[%d] = \"%s\"\n", i, arr[i].GetString());
-		}
-	}
-	puts("Putting new dict in array.\n");
-	Document::AllocatorType& allocator = document.GetAllocator();
-	Value dict;
-	Value insertstr;
-	insertstr.SetString("testvalue", allocator);
-	dict.SetObject();
-	dict.AddMember("testkey", insertstr, allocator);
-	arr.PushBack(dict, allocator);
-	
-	Value newint;
-	newint.SetInt(12345);
-	document["i"] = newint;
-	puts("Done.\n");
-	// ->Assertion failed in []:
-	//   Value& nonexisting = document["dict"]["NONEXISTING"];
-	
-#if 0
-	// 2. Access values in document.
-	printf("\nAccess values in document:\n");
-	assert(document.IsObject()); // Document is a JSON value represents the root of DOM. Root can be either an object or array.
-	assert(document.HasMember("hello"));
-	assert(document["hello"].IsString());
-	printf("hello = %s\n", document["hello"].GetString());
-	// Since version 0.2, you can use single lookup to check the existing of member and its value:
-	Value::MemberIterator hello = document.FindMember("hello");
-	assert(hello != document.MemberEnd());
-	assert(hello->value.IsString());
-	assert(strcmp("world", hello->value.GetString()) == 0);
-	(void)hello;
-	assert(document["t"].IsBool()); // JSON true/false are bool. Can also uses more specific function IsTrue().
-	printf("t = %s\n", document["t"].GetBool() ? "true" : "false");
-	assert(document["f"].IsBool());
-	printf("f = %s\n", document["f"].GetBool() ? "true" : "false");
-	printf("n = %s\n", document["n"].IsNull() ? "null" : "?");
-	assert(document["i"].IsNumber()); // Number is a JSON type, but C++ needs more specific type.
-	assert(document["i"].IsInt()); // In this case, IsUint()/IsInt64()/IsUInt64() also return true.
-	printf("i = %d\n", document["i"].GetInt()); // Alternative (int)document["i"]
-	assert(document["pi"].IsNumber());
-	assert(document["pi"].IsDouble());
-	printf("pi = %g\n", document["pi"].GetDouble());
-	{
-		const Value& a = document["a"]; // Using a reference for consecutive access is handy and faster.
-		assert(a.IsArray());
-		for (SizeType i = 0; i < a.Size(); i++) // rapidjson uses SizeType instead of size_t.
-			printf("a[%d] = %d\n", i, a[i].GetInt());
-		int y = a[0].GetInt();
-		(void)y;
-		// Iterating array with iterators
-		printf("a = ");
-		for (Value::ConstValueIterator itr = a.Begin(); itr != a.End(); ++itr)
-			printf("%d ", itr->GetInt());
-		printf("\n");
-	}
-	// Iterating object members
-	static const char* kTypeNames[] = { "Null", "False", "True", "Object", "Array", "String", "Number" };
-	for (Value::ConstMemberIterator itr = document.MemberBegin(); itr != document.MemberEnd(); ++itr)
-		printf("Type of member %s is %s\n", itr->name.GetString(), kTypeNames[itr->value.GetType()]);
-	////////////////////////////////////////////////////////////////////////////
-	// 3. Modify values in document.
-	// Change i to a bigger number
-	{
-		uint64_t f20 = 1; // compute factorial of 20
-		for (uint64_t j = 1; j <= 20; j++)
-			f20 *= j;
-		document["i"] = f20; // Alternate form: document["i"].SetUint64(f20)
-		assert(!document["i"].IsInt()); // No longer can be cast as int or uint.
-	}
-	// Adding values to array.
-	{
-		Value& a = document["a"]; // This time we uses non-const reference.
-		Document::AllocatorType& allocator = document.GetAllocator();
-		for (int i = 5; i <= 10; i++)
-			a.PushBack(i, allocator); // May look a bit strange, allocator is needed for potentially realloc. We normally uses the document's.
-		// Fluent API
-		a.PushBack("Lua", allocator).PushBack("Mio", allocator);
-	}
-	// Making string values.
-	// This version of SetString() just store the pointer to the string.
-	// So it is for literal and string that exists within value's life-cycle.
-	{
-		document["hello"] = "rapidjson"; // This will invoke strlen()
-		// Faster version:
-		// document["hello"].SetString("rapidjson", 9);
-	}
-	// This version of SetString() needs an allocator, which means it will allocate a new buffer and copy the the string into the buffer.
-	Value author;
-	{
-		char buffer[10];
-		int len = sprintf(buffer, "%s %s", "Milo", "Yip"); // synthetic example of dynamically created string.
-		author.SetString(buffer, static_cast<size_t>(len), document.GetAllocator());
-		// Shorter but slower version:
-		// document["hello"].SetString(buffer, document.GetAllocator());
-		// Constructor version:
-		// Value author(buffer, len, document.GetAllocator());
-		// Value author(buffer, document.GetAllocator());
-		memset(buffer, 0, sizeof(buffer)); // For demonstration purpose.
-	}
-	// Variable 'buffer' is unusable now but 'author' has already made a copy.
-	document.AddMember("author", author, document.GetAllocator());
-	assert(author.IsNull()); // Move semantic for assignment. After this variable is assigned as a member, the variable becomes null.
-	////////////////////////////////////////////////////////////////////////////
-#endif
-	StringBuffer buffer;
-	Writer<StringBuffer> writer(buffer);
-	document.Accept(writer);
-	std::string docstring = buffer.GetString();
-	std::cout << "FIRST DUMP:  " << docstring << std::endl;
-
-	//// 4. Stringify JSON
-	//printf("\nModified JSON with reformatting:\n");
-	//FileStream f(stdout);
-	//PrettyWriter<FileStream> writer(f);
-	//document.Accept(writer); // Accept() traverses the DOM and generates Handler events.
-	return 0;
 }
diff --git a/ipaacalib/cpp/src/ipaaca-payload.cc b/ipaacalib/cpp/src/ipaaca-payload.cc
index aeb95163905f0525325cc99c5d21cc5bf6d31ade..7393ab6333a9470313cdf7a6e146c12696fe2df8 100644
--- a/ipaacalib/cpp/src/ipaaca-payload.cc
+++ b/ipaacalib/cpp/src/ipaaca-payload.cc
@@ -142,6 +142,10 @@ IPAACA_EXPORT template<> void pack_into_json_value(rapidjson::Value& valueobject
 {
 	valueobject.SetString(newvalue.c_str(), allocator);
 }
+IPAACA_EXPORT template<> void pack_into_json_value(rapidjson::Value& valueobject, rapidjson::Document::AllocatorType& allocator, const char* newvalue)
+{
+	valueobject.SetString(newvalue, allocator);
+}
 /*
 IPAACA_EXPORT template<> void pack_into_json_value(rapidjson::Value& valueobject, rapidjson::Document::AllocatorType& allocator, const std::vector<std::string>& newvalue)
 {
@@ -185,16 +189,89 @@ IPAACA_EXPORT inline PayloadDocumentEntry::ptr PayloadDocumentEntry::create_null
 	entry->json_source = "null"; // rapidjson::Document value is also null implicitly
 	return entry;
 }
-IPAACA_EXPORT inline PayloadDocumentEntry::ptr PayloadDocumentEntry::clone()
+IPAACA_EXPORT PayloadDocumentEntry::ptr PayloadDocumentEntry::clone()
 {
+	IPAACA_INFO("")
 	return PayloadDocumentEntry::from_json_string_representation(this->json_source);
 }
+IPAACA_EXPORT rapidjson::Value& PayloadDocumentEntry::get_or_create_nested_value_from_proxy_path(PayloadEntryProxy* pep)
+{
+	if (!(pep->parent)) {
+		IPAACA_INFO("Reached top-most parent")
+		return document;
+	}
+	IPAACA_INFO("(Check parent)")
+	rapidjson::Value& parent_value = get_or_create_nested_value_from_proxy_path(pep->parent);
+	IPAACA_INFO("Resolving address path")
+	if (pep->addressed_as_array) {
+		IPAACA_INFO("Addressed as array with index " << pep->addressed_index)
+		if (! parent_value.IsArray()) {
+			throw PayloadAddressingError();
+		} else {
+			long idx = pep->addressed_index;
+			long s = parent_value.Size();
+			if (idx<s) {
+				return parent_value[idx];
+			} else {
+				throw PayloadAddressingError();
+			}
+		}
+		// for append / push_back? :
+		/*if (parent_value.IsNull()) {
+			wasnull = true;
+			parent_value.SetArray();
+		}
+		if (wasnull || parent_value.IsArray()) {
+			long idx = pep->addressed_index;
+			long s = parent_value.Size();
+			if (idx<s) {
+				// existing element modified
+				parent_value[idx] = *json_value;
+			} else {
+				// implicitly initialize missing elements to null values
+				if (idx>s) {
+					long missing_elements = pep->addressed_index - p;
+					for (int i=0; i<missing_elements; ++i) {
+						parent_value.PushBack(, allocator)
+					}
+				}
+			}
+			if (s == 
+		} else {
+			throw PayloadAddressingError();
+		}*/
+	} else {
+		IPAACA_INFO("Addressed as dict with key " << pep->addressed_key)
+		// addressed as object (dict)
+		//rapidjson::Value& parent_value = *(pep->parent->json_value);
+		if (! parent_value.IsObject()) {
+			throw PayloadAddressingError();
+		} else {
+			rapidjson::Document::AllocatorType& allocator = document.GetAllocator();
+			//Value key;
+			//key.SetString(pep->addressed_key, allocator);
+			//parent_value.AddMember(key, *json_value, allocator);
+			Value key;
+			key.SetString(pep->addressed_key, allocator);
+			// FIXME LAST this complains
+			auto it = parent_value.FindMember(key);
+			if (it != parent_value.MemberEnd()) {
+				return parent_value[pep->addressed_key.c_str()];
+			} else {
+				rapidjson::Value val;
+				parent_value.AddMember(key, val, allocator);
+				return parent_value[key];
+			}
+		}
+	}
+}
 
 //}}}
 
 // PayloadEntryProxy//{{{
 
  // only if not top-level
+#if 0
 IPAACA_EXPORT void PayloadEntryProxy::connect_to_existing_parents()
 {
 	rapidjson::Document::AllocatorType& allocator = document_entry->document.GetAllocator();
@@ -251,55 +328,81 @@ IPAACA_EXPORT void PayloadEntryProxy::connect_to_existing_parents()
 		pep = pep->parent;
 	}
 }
-
+#endif
 
 
 IPAACA_EXPORT PayloadEntryProxy::PayloadEntryProxy(Payload* payload, const std::string& key)
 : _payload(payload), _key(key), parent(nullptr)
 {
+	IPAACA_INFO("PEP construction on parent document ...")
 	document_entry = _payload->get_entry(key);
 	json_value = &(document_entry->document);
+	IPAACA_INFO("... parent done.")
 }
 IPAACA_EXPORT PayloadEntryProxy::PayloadEntryProxy(PayloadEntryProxy* parent_, const std::string& addr_key_)
 : parent(parent_), addressed_key(addr_key_), addressed_as_array(false)
 {
+	IPAACA_INFO("PEP construction as dict child, addressed by " << addr_key_ << " ...")
 	_payload = parent->_payload;
 	_key = parent->_key;
 	document_entry = parent->document_entry;
 	auto it = parent->json_value->FindMember(addr_key_.c_str());
-	if (it != json_value->MemberEnd()) {
+	if (it != parent->json_value->MemberEnd()) {
 		json_value = &(parent->json_value->operator[](addr_key_.c_str()));
 		existent = true;
 	} else {
 		json_value = nullptr; // avoid heap construction here
 		existent = false;
 	}
+	IPAACA_INFO("... dict child done.")
 }
 IPAACA_EXPORT PayloadEntryProxy::PayloadEntryProxy(PayloadEntryProxy* parent_, size_t addr_idx_)
 : parent(parent_), addressed_index(addr_idx_), addressed_as_array(true)
 {
+	IPAACA_INFO("PEP construction as array child, addressed by " << addr_idx_ << " ...")
 	_payload = parent->_payload;
 	_key = parent->_key;
 	document_entry = parent->document_entry;
 	json_value = &(parent->json_value->operator[](addr_idx_));
 	existent = true;
+	IPAACA_INFO("... array child done.")
 }
 
+IPAACA_EXPORT PayloadEntryProxy PayloadEntryProxy::operator[](const char* addr_key_)
+{
+	return operator[](std::string(addr_key_));
+}
 IPAACA_EXPORT PayloadEntryProxy PayloadEntryProxy::operator[](const std::string& addr_key_)
 {
-	if (!json_value) throw PayloadAddressingError();
-	if (! json_value->IsObject()) throw PayloadAddressingError();
+	if (!json_value) {
+		IPAACA_INFO("Invalid json_value!")
+		throw PayloadAddressingError();
+	}
+	if (! json_value->IsObject()) {
+		IPAACA_INFO("Expected Object for operator[](string)!")
+		throw PayloadAddressingError();
+	}
 	return PayloadEntryProxy(this, addr_key_);
 }
 IPAACA_EXPORT PayloadEntryProxy PayloadEntryProxy::operator[](size_t addr_idx_)
 {
-	if (!json_value) throw PayloadAddressingError();
-	if (! json_value->IsArray()) throw PayloadAddressingError();
+	if (!json_value) {
+		IPAACA_INFO("Invalid json_value!")
+		throw PayloadAddressingError();
+	}
+	if (! json_value->IsArray()) {
+		IPAACA_INFO("Expected Array for operator[](size_t)!")
+		throw PayloadAddressingError();
+	}
 	long s = json_value->Size();
-	if (addr_idx_>=s) throw PayloadAddressingError();
+	if (addr_idx_>=s) {
+		IPAACA_INFO("Array out of bounds!")
+		throw PayloadAddressingError();
+	}
 	return PayloadEntryProxy(this, addr_idx_);
 }
 
+/*
 IPAACA_EXPORT PayloadEntryProxy& PayloadEntryProxy::operator=(const std::string& value)
 {
 	//std::cout << "operator=(string)" << std::endl;
@@ -328,6 +431,7 @@ IPAACA_EXPORT PayloadEntryProxy& PayloadEntryProxy::operator=(bool value)
 	//_payload->set(_key, boost::lexical_cast<std::string>(value));
 	return *this;
 }
+*/
 
 IPAACA_EXPORT PayloadEntryProxy::operator std::string()
 {
@@ -443,11 +547,12 @@ IPAACA_EXPORT PayloadEntryProxy Payload::operator[](const std::string& key)
 	//boost::shared_ptr<PayloadEntryProxy> p(new PayloadEntryProxy(this, key));
 	return PayloadEntryProxy(this, key);
 }
+
 IPAACA_EXPORT Payload::operator std::map<std::string, std::string>()
 {
 	std::map<std::string, std::string> result;
 	std::for_each(_document_store.begin(), _document_store.end(), [&result](std::pair<std::string, PayloadDocumentEntry::ptr> pair) {
-			result[pair.first] =  pair.second->document.GetString();
+			result[pair.first] =  json_value_cast<std::string>(pair.second->document);
 			});
 	return result;
 }