Index: sample/pingpong/PingPong.cpp
===================================================================
--- sample/pingpong/PingPong.cpp	(revision 2483)
+++ sample/pingpong/PingPong.cpp	(revision 3037)
@@ -12,5 +12,5 @@
 use_logging_cpp( PingPong );
 
-// the service id of the ping pong service
+// the service that the pingpong wants to use
 ServiceID PingPong::PINGPONG_ID = ServiceID( 111 );
 
@@ -40,20 +40,19 @@
 
 	// get initiator flag
-	this->isInitiator = Configuration::instance().read<bool> ("node.initiator");
+	this->isInitiator = Configuration::instance().read<bool>("node.initiator");
 
 	// get node name
 	Name nodeName = Name::UNSPECIFIED;
-	if (config.exists("node.name")) nodeName
-			= config.read<string> ("node.name");
+	if (config.exists("node.name")) nodeName = config.read<string> ("node.name");
 
 	// configure ariba module
 	if (config.exists("ariba.ip.addr")) ariba->setProperty("ip.addr",
-			config.read<string> ("ariba.ip.addr"));
+			config.read<string>("ariba.ip.addr"));
 	if (config.exists("ariba.tcp.port")) ariba->setProperty("tcp.port",
-			config.read<string> ("ariba.tcp.port"));
+			config.read<string>("ariba.tcp.port"));
 	if (config.exists("ariba.udp.port")) ariba->setProperty("udp.port",
-			config.read<string> ("ariba.udp.port"));
+			config.read<string>("ariba.udp.port"));
 	if (config.exists("ariba.bootstrap.hints")) ariba->setProperty("bootstrap.hints",
-			config.read<string> ("ariba.bootstrap.hints"));
+			config.read<string>("ariba.bootstrap.hints"));
 
 	// start ariba module
@@ -71,7 +70,7 @@
 
 	// bind communication and node listener
-	node->bind( this );
-	node->bind( this, PingPong::PINGPONG_ID);
-	
+	node->bind( this );                       /*NodeListener*/
+	node->bind( this, PingPong::PINGPONG_ID); /*CommunicationListener*/
+
 	// start the ping timer. if we are not
 	// the initiator this will happen in onJoinCompleted
@@ -79,5 +78,7 @@
 
 	// ping pong started up...
-	logging_info( "pingpong started up ");
+	logging_info( "pingpong starting up with"
+			<< " [spovnetid " << node->getSpoVNetId().toString() << "]"
+			<< " and [nodeid " << node->getNodeId().toString() << "]" );
 }
 
@@ -91,6 +92,6 @@
 
 	// unbind communication and node listener
-	node->unbind( this );
-	node->unbind( this, PingPong::PINGPONG_ID );
+	node->unbind( this );                        /*NodeListener*/
+	node->unbind( this, PingPong::PINGPONG_ID ); /*CommunicationListener*/
 
 	// leave spovnet
@@ -110,5 +111,5 @@
 // node listener interface
 void PingPong::onJoinCompleted( const SpoVNetID& vid ) {
-	logging_info( "pingpong node join completed, spovnetid=" << vid.toString() );
+	logging_error( "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX pingpong node join completed, spovnetid=" << vid.toString() );
 
 	// start the timer to ping every second
@@ -117,5 +118,39 @@
 
 void PingPong::onJoinFailed( const SpoVNetID& vid ) {
-	logging_error(" pingpong node join failed, spovnetid=" << vid.toString() );
+	logging_error("pingpong node join failed, spovnetid=" << vid.toString() );
+}
+
+void PingPong::onLeaveCompleted( const SpoVNetID& vid ){
+	logging_info("pingpong node leave completed, spovnetid=" << vid.toString() );
+}
+
+void PingPong::onLeaveFailed( const SpoVNetID& vid ){
+	logging_error("pingpong node leave failed, spovnetid=" << vid.toString() );
+}
+
+// timer event
+void PingPong::eventFunction() {
+
+	// we ping all nodes that are known in the overlay structure
+	// this can be all nodes (OneHop) overlay or just some neighbors
+	// in case of a Chord or Kademlia structure
+
+	logging_info( "pinging overlay neighbors with ping id " << ++pingId );
+
+	PingPongMessage pingmsg( pingId );
+
+	//-----------------------------------------------------------------------
+	// Option 1: get all neighboring nodes and send the message to each
+	//-----------------------------------------------------------------------
+	vector<NodeID> nodes = node->getNeighborNodes();
+	BOOST_FOREACH( NodeID nid, nodes ){
+		node->sendMessage( pingmsg, nid, PingPong::PINGPONG_ID );
+	}
+
+	//-----------------------------------------------------------------------
+	// Option 2: send a "broadcast message" that actually does the same thing
+	//           internally, gets all neighboring nodes and sends the message
+	//-----------------------------------------------------------------------
+	// node->sendBroadcastMessage( pingmsg, PingPong::PINGPONG_ID );
 }
 
@@ -127,5 +162,5 @@
 void PingPong::onMessage(const DataMessage& msg, const NodeID& remote, const LinkID& lnk) {
 
-	PingPongMessage* pingmsg = msg.getMessage()->decapsulate<PingPongMessage> ();
+	PingPongMessage* pingmsg = msg.getMessage()->convert<PingPongMessage> ();
 
 	logging_info( "received ping message on link " << lnk.toString()
@@ -134,15 +169,33 @@
 }
 
-// timer event
-void PingPong::eventFunction() {
-	
-	// we ping all nodes that are known in the overlay structure
-	// this can be all nodes (OneHop) overlay or just some neighbors
-	// in case of a Chord or Kademlia structure
-	
-	logging_info( "pinging overlay neighbors with ping id " << ++pingId );
-
-	PingPongMessage pingmsg( pingId );
-	node->sendBroadcastMessage( pingmsg, PingPong::PINGPONG_ID );
+void PingPong::onLinkUp(const LinkID& lnk, const NodeID& remote){
+	logging_info( "received link-up event for link " << lnk.toString()
+			<< " and node " << remote.toString() );
+}
+
+void PingPong::onLinkDown(const LinkID& lnk, const NodeID& remote){
+	logging_info( "received link-down event for link " << lnk.toString()
+			<< " and node " << remote.toString() );
+}
+
+void PingPong::onLinkChanged(const LinkID& lnk, const NodeID& remote){
+	logging_info( "received link-changed event for link " << lnk.toString()
+			<< " and node " << remote.toString() );
+}
+
+void PingPong::onLinkFail(const LinkID& lnk, const NodeID& remote){
+	logging_info( "received link-failed event for link " << lnk.toString()
+			<< " and node " << remote.toString() );
+}
+
+void PingPong::onLinkQoSChanged(const LinkID& lnk, const NodeID& remote, const LinkProperties& prop){
+	logging_info( "received link-qos-changed event for link " << lnk.toString()
+				<< " and node " << remote.toString()
+				<< " with link properties " << prop.toString() );
+}
+
+void PingPong::onMessageSent(seqnum_t seq_num, bool failed, const DataMessage& msg ){
+	logging_info( "received message sent event for seqnum " << seq_num
+			<< " with result " << failed );
 }
 
Index: sample/pingpong/PingPong.h
===================================================================
--- sample/pingpong/PingPong.h	(revision 2483)
+++ sample/pingpong/PingPong.h	(revision 3037)
@@ -37,8 +37,16 @@
 	virtual bool onLinkRequest(const NodeID& remote, const DataMessage& msg);
 	virtual void onMessage(const DataMessage& msg, const NodeID& remote, const LinkID& lnk= LinkID::UNSPECIFIED);
+	virtual void onLinkUp(const LinkID& lnk, const NodeID& remote);
+	virtual void onLinkDown(const LinkID& lnk, const NodeID& remote);
+	virtual void onLinkChanged(const LinkID& lnk, const NodeID& remote);
+	virtual void onLinkFail(const LinkID& lnk, const NodeID& remote);
+	virtual void onLinkQoSChanged(const LinkID& lnk, const NodeID& remote, const LinkProperties& prop);
+	virtual void onMessageSent(seqnum_t seq_num, bool failed, const DataMessage& msg = DataMessage::UNSPECIFIED);
 
 	// node listener interface
 	virtual void onJoinCompleted( const SpoVNetID& vid );
 	virtual void onJoinFailed( const SpoVNetID& vid );
+	virtual void onLeaveCompleted( const SpoVNetID& vid );
+	virtual void onLeaveFailed( const SpoVNetID& vid );
 
 	// startup wrapper interface
@@ -54,5 +62,5 @@
 	Node* node;
 
-	// flag, wheter this node initiates or just joins the spovnet
+	// flag, whether this node initiates or just joins the spovnet
 	bool isInitiator;
 
