Index: /etc/pingpong/settings_initiator.cnf
===================================================================
--- /etc/pingpong/settings_initiator.cnf	(revision 2445)
+++ /etc/pingpong/settings_initiator.cnf	(revision 2452)
@@ -4,3 +4,3 @@
 ariba.tcp.port = 5002
 #ariba.udp.port =
-#ariba.bootstrap.hints =
+ariba.bootstrap.hints=pingpong{ip{127.0.0.1},tcp(ip,5002)}
Index: /etc/pingpong/settings_node1.cnf
===================================================================
--- /etc/pingpong/settings_node1.cnf	(revision 2445)
+++ /etc/pingpong/settings_node1.cnf	(revision 2452)
@@ -4,3 +4,3 @@
 ariba.tcp.port = 5003
 #ariba.udp.port =
-ariba.bootstrap.hints = <spovnet>pingpong<ip>127.0.0.1<port>5002
+ariba.bootstrap.hints=pingpong{ip{127.0.0.1},tcp(ip,5002)}
Index: /etc/pingpong/settings_node2.cnf
===================================================================
--- /etc/pingpong/settings_node2.cnf	(revision 2445)
+++ /etc/pingpong/settings_node2.cnf	(revision 2452)
@@ -4,3 +4,3 @@
 ariba.tcp.port = 5010
 #ariba.udp.port =
-ariba.bootstrap.hints = <spovnet>pingpong<ip>127.0.0.1<port>5002
+ariba.bootstrap.hints=pingpong{ip{127.0.0.1},tcp(ip,5002)}
Index: /source/ariba/AribaModule.cpp
===================================================================
--- /source/ariba/AribaModule.cpp	(revision 2445)
+++ /source/ariba/AribaModule.cpp	(revision 2452)
@@ -45,4 +45,5 @@
 // ariba includes
 #include "ariba/utility/misc/Helper.h"
+#include "ariba/utility/misc/StringFormat.h"
 
 // hack includes
@@ -53,6 +54,11 @@
 using namespace ariba::utility::Helper;
 using ariba::interface::UnderlayAbstraction;
+using ariba::communication::EndpointDescriptor;
 
 namespace ariba {
+
+AribaModule::BootstrapNode::~BootstrapNode() {
+	if (desc!=NULL) delete desc;
+}
 
 AribaModule::AribaModule() {
@@ -69,36 +75,76 @@
 }
 
-
 string AribaModule::getBootstrapHints(const Name& spoVNetName) const {
-
+	std::ostringstream o;
+	BOOST_FOREACH( const BootstrapInfo& info, bootstrapNodes ) {
+		o << info.spovnetName.toString() << "{";
+		int i=0;
+		BOOST_FOREACH( const BootstrapNode& node, info.nodes ) {
+			if (i!=0) o << ",";
+			if( node.desc != NULL ) o << node.desc->toString();
+			i++;
+		}
+	}
+	return o.str();
 }
 
 void AribaModule::addBootstrapHints(string boot_info) {
-	string str = boot_info;
-	static ::boost::regex boot_expr("<([^>:]+)[:]?([0-9]+)?>([^<]+)(.*)");
-	::boost::smatch what;
-	while (::boost::regex_match(str, what, boot_expr)) {
-		std::cout << what[1].str() << ":" << what[2].str() << "=" << what[3]
-				<< std::endl;
-		str = what[4].str();
-	}
-}
-
-void AribaModule::addBootstrapNode(const Name& spovnet, const Name& node,
+	using namespace boost::xpressive;
+	using namespace ariba::utility::string_format;
+	using namespace ariba::utility::Helper;
+	using namespace std;
+
+	smatch match;
+	if (regex_search(boot_info, match, robjects)) {
+		regex_nav nav = match;
+		for (int i = 0; i < nav.size(); i++) {
+			string type = nav[i][robject_id].str();
+			string data = nav[i][robject_data].str();
+			data = data.substr(1, data.size() - 2);
+			Name name = type;
+			EndpointDescriptor* desc = EndpointDescriptor::fromString(data);
+			addBootstrapNode(name, desc);
+		}
+	}
+}
+
+void AribaModule::addBootstrapNode(const Name& spovnet,
 		communication::EndpointDescriptor* desc) {
 
+	// set bootstrap node
+	BootstrapNode node;
+	node.timestamp = 0;
+	node.desc = desc;
+	bool added = false;
+
+	// add node to existing bootstrap list
+	BOOST_FOREACH( BootstrapInfo& info, bootstrapNodes ){
+		if (info.spovnetName == spovnet) {
+			info.nodes.push_back(node);
+			added = true;
+			break;
+		}
+	}
+
+	// create new entry
+	if (!added) {
+		BootstrapInfo info;
+		info.spovnetName = spovnet;
+		info.nodes.push_back(node);
+		bootstrapNodes.push_back(info);
+	}
+
+	std::cout << "added bootstrap info: " << getBootstrapHints() << std::endl;
 }
 
 const communication::EndpointDescriptor* AribaModule::getBootstrapNode(
-		const Name& spovnet) {
-
-	BOOST_FOREACH( BootstrapInfo info, bootstrapNodes ){
-		if( info.spovnetName == spovnet ){
-			BOOST_FOREACH( BootstrapNode node, info.desc ){
+		const Name& spovnet) const {
+	BOOST_FOREACH( const BootstrapInfo& info, bootstrapNodes ) {
+		if( info.spovnetName == spovnet ) {
+			BOOST_FOREACH( const BootstrapNode& node, info.nodes ) {
 				if( node.desc != NULL ) return node.desc;
 			}
 		}
 	}
-
 	return NULL;
 }
@@ -150,5 +196,6 @@
 		*loc = communication::IPv4Locator::fromString(value);
 		ip_addr = loc;
-	} else if (key == "tcp.port") tcp_port = stoi(value);
+	}
+	else if (key == "tcp.port") tcp_port = stoi(value);
 	else if (key == "udp.port") udp_port = stoi(value);
 	else if (key == "bootstrap.hints") addBootstrapHints(value);
Index: /source/ariba/AribaModule.h
===================================================================
--- /source/ariba/AribaModule.h	(revision 2445)
+++ /source/ariba/AribaModule.h	(revision 2452)
@@ -141,4 +141,13 @@
 	class BootstrapNode {
 	public:
+		inline BootstrapNode() : timestamp(0), desc(NULL) {
+
+		}
+		inline BootstrapNode(uint32_t timestamp,
+				communication::EndpointDescriptor* desc) :
+			timestamp(timestamp), desc(desc) {
+
+		}
+		~BootstrapNode();
 		uint32_t timestamp;
 		communication::EndpointDescriptor* desc;
@@ -149,5 +158,5 @@
 	public:
 		Name spovnetName;
-		vector<BootstrapNode> desc;
+		vector<BootstrapNode> nodes;
 	};
 	vector<BootstrapInfo> bootstrapNodes;
@@ -155,12 +164,12 @@
 protected:
 	// members
-	string bootstrapFile; 	//< file with bootstrap information
-	bool started;			//< flag, if module has been started
+	string bootstrapFile; //< file with bootstrap information
+	bool started; //< flag, if module has been started
 
 	// bootstrap node management
-	void addBootstrapNode(const Name& spovnet, const Name& node,
+	void addBootstrapNode(const Name& spovnet,
 			communication::EndpointDescriptor* desc);
 	const communication::EndpointDescriptor* getBootstrapNode(
-			const Name& spovnet);
+			const Name& spovnet) const;
 
 	// TODO: merge with old interface
Index: /source/ariba/communication/EndpointDescriptor.cpp
===================================================================
--- /source/ariba/communication/EndpointDescriptor.cpp	(revision 2445)
+++ /source/ariba/communication/EndpointDescriptor.cpp	(revision 2452)
@@ -38,4 +38,6 @@
 
 #include "EndpointDescriptor.h"
+#include "ariba/utility/misc/StringFormat.h"
+#include "ariba/utility/misc/Helper.h"
 
 namespace ariba {
@@ -68,11 +70,40 @@
 string EndpointDescriptor::toString() const {
 	if( locator == NULL ) return "<undefined locator>";
-	else                  return locator->toString();
+	std::ostringstream o;
+	o << "ip{" << locator->getIP() << "}";
+	o << ",";
+	o << "tcp(ip,{" << locator->getPort() << "})";
+	return o.str();
 }
 
 EndpointDescriptor* EndpointDescriptor::fromString( string str ) {
-	EndpointDescriptor* ep = new EndpointDescriptor();
-	ep->locator->fromString(str);
-	ep->isUnspec = false;
+	using namespace boost::xpressive;
+	using namespace ariba::utility::string_format;
+	using namespace ariba::utility::Helper;
+	using namespace std;
+
+	EndpointDescriptor* ep = NULL;
+	smatch match;
+	if (regex_search(str, match, robjects)) {
+		regex_nav nav = match;
+		for (int i=0; i<nav.size(); i++) {
+			string type = nav[i][robject_id].str();
+			if (type=="ip") {
+				string ip = nav[i][robject_data].str();
+				ip = ip.substr(1,ip.size()-2);
+				cout << "ep-ip = " <<ip << endl;
+				ep = new EndpointDescriptor();
+				ep->locator = new IPv4Locator();
+				ep->locator->setIP(ip);
+				ep->isUnspec = false;
+			} else
+			if (type=="tcp") {
+				string port = nav[i][robject_data][rfields][1].str();
+				port = port.substr(1,port.size()-2);
+				cout << "ep-tcp-port = " << port << endl;
+				ep->locator->setPort(stoi(port));
+			}
+		}
+	}
 	return ep;
 }
Index: /source/ariba/communication/modules/network/ip/IPv4Locator.h
===================================================================
--- /source/ariba/communication/modules/network/ip/IPv4Locator.h	(revision 2445)
+++ /source/ariba/communication/modules/network/ip/IPv4Locator.h	(revision 2452)
@@ -77,4 +77,8 @@
 	virtual string toString() const;
 
+	void setIP( string ip ) {
+		ipv4Address = boost::asio::ip::address_v4::from_string( ip );
+	}
+
 	string getIP() const {
 		return ipv4Address.to_string();
@@ -91,5 +95,4 @@
 	boost::asio::ip::address_v4 ipv4Address;
 	uint16_t port;
-
 };
 
Index: /source/ariba/utility/misc/StringFormat.cpp
===================================================================
--- /source/ariba/utility/misc/StringFormat.cpp	(revision 2445)
+++ /source/ariba/utility/misc/StringFormat.cpp	(revision 2452)
@@ -4,38 +4,45 @@
 #include "boost/xpressive/xpressive.hpp"
 
+namespace ariba {
+namespace utility {
+namespace string_format {
+
 using namespace boost::xpressive;
 
 // regex: string
-const sregex StringFormat::rstring = '"' >> keep(*~(boost::xpressive::set = '"'))
+const sregex rstring = '"' >> keep(*~(boost::xpressive::set = '"'))
 		>> '"';
 
 // regex: base64 encoding
-const sregex StringFormat::rbase64 = '!' >> +(range('a', 'z') | range('A', 'Z')
+const sregex rbase64 = '!' >> +(range('a', 'z') | range('A', 'Z')
 		| range('0', '9') | '/' | '+') >> *(boost::xpressive::set = '=');
 
 // regex: raw alphabet
-const sregex StringFormat::rchars = +(range('a', 'z') | range('A', 'Z'));
+const sregex rchars = +(range('a', 'z') | range('A', 'Z'));
 
 // regex: integer
-const sregex StringFormat::rint = '0' | (range('1', '9') >> !(range('0', '9')));
+const sregex rint = '0' | (range('1', '9') >> !(range('0', '9')));
 
 // regex: binary label
-const sregex StringFormat::rlabel = rchars | rstring | rbase64;
+const sregex rlabel = rchars | rstring | rbase64;
 
 // regex: dot separated identifier
-const sregex StringFormat::rid = rlabel >> *('.' >> rlabel) >> *('.' >> rint);
+const sregex rid = rlabel >> *('.' >> rlabel) >> *('.' >> rint);
 
 // regex: "leaf" data
-const sregex StringFormat::rdata = !(boost::xpressive::set = '!') >> '{'
+const sregex rdata = !(boost::xpressive::set = '!') >> '{'
 		>> *(keep(+~(boost::xpressive::set = '{', '}')) | by_ref(rdata))
 		>> '}';
 
 // regex: fields
-const sregex StringFormat::rfield_label = rlabel >> '=';
-const sregex StringFormat::rfield = !rfield_label >> (rid | rdata);
-const sregex StringFormat::rfields = '(' >> rfield >> *(',' >> rfield) >> ')';
+const sregex rfield_label = rlabel >> '=';
+const sregex rfield = !rfield_label >> (rid | rdata);
+const sregex rfields = '(' >> rfield >> *(',' >> rfield) >> ')';
 
-// regex: objects
-const sregex StringFormat::robject_data = (rdata | rfields);
-const sregex StringFormat::robject = rid >> robject_data;
-const sregex StringFormat::robjects = robject >> *(',' >> robject);
+// regex objects
+const sregex robject_data = (rdata | rfields);
+const sregex robject_id = rid;
+const sregex robject = robject_id >> robject_data;
+const sregex robjects = robject >> *(',' >> robject);
+
+}}}
Index: /source/ariba/utility/misc/StringFormat.h
===================================================================
--- /source/ariba/utility/misc/StringFormat.h	(revision 2445)
+++ /source/ariba/utility/misc/StringFormat.h	(revision 2452)
@@ -5,44 +5,90 @@
 #include "boost/xpressive/xpressive.hpp"
 
+namespace ariba {
+namespace utility {
+namespace string_format {
+
 using boost::xpressive::sregex;
 
-/**
- * This class defines some regular expressions ...
- *
- * @author Sebastian Mies
- */
-class StringFormat {
+class regex_nav {
+private:
+	typedef boost::xpressive::smatch _match;
+	typedef _match::nested_results_type nested_results;
+	typedef nested_results::const_iterator nested_iterator;
+	const _match& match;
+
 public:
-	// regex: string
-	static const sregex rstring;
+	regex_nav(const _match& match) :
+		match(match) {
+	}
 
-	// regex: base64 encoding
-	static const sregex rbase64;
+	regex_nav() :
+		match(*((const _match*) NULL)) {
+	}
 
-	// regex: raw alphabet
-	static const sregex rchars;
+	bool matched() const {
+		return &match != NULL;
+	}
 
-	// regex: integer
-	static const sregex rint;
+	regex_nav operator[] (const sregex& type) const {
+		const nested_results& nr = match.nested_results();
+		for (nested_iterator i = nr.begin(); i != nr.end(); i++) {
+			if (i->regex_id() == type.regex_id()) return regex_nav(*i);
+		}
+		return regex_nav();
+	}
 
-	// regex: binary label
-	static const sregex rlabel;
+	regex_nav operator[](int index) const {
+		const nested_results& nr = match.nested_results();
+		for (nested_iterator i = nr.begin(); i != nr.end() && index >= 0; i++) {
+			if (index == 0) return regex_nav(*i);
+			index--;
+		}
+		return regex_nav();
+	}
 
-	// regex: dot separated identifier
-	static const sregex rid;
+	int size() const {
+		return match.nested_results().size();
+	}
 
-	// regex: "leaf" data
-	static const sregex rdata;
-
-	// regex: fields
-	static const sregex rfield_label;
-	static const sregex rfield;
-	static const sregex rfields;
-
-	// regex: objects
-	static const sregex robject_data;
-	static const sregex robject;
-	static const sregex robjects;
+	std::string str() const {
+		if (!matched()) return std::string("<no match>");
+		return match[0].str();
+	}
 };
 
+// regex: string
+extern const sregex rstring;
+
+// regex: base64 encoding
+extern const sregex rbase64;
+
+// regex: raw alphabet
+extern const sregex rchars;
+
+// regex: integer
+extern const sregex rint;
+
+// regex: binary label
+extern const sregex rlabel;
+
+// regex: dot separated identifier
+extern const sregex rid;
+
+// regex: "leaf" data
+extern const sregex rdata;
+
+// regex: fields
+extern const sregex rfield_label;
+extern const sregex rfield;
+extern const sregex rfields;
+
+// regex: objects
+extern const sregex robject_data;
+extern const sregex robject_id;
+extern const sregex robject;
+extern const sregex robjects;
+
+}}}
+
 #endif /* STRINGFORMAT_H_ */
