istream &is
 )
 {
-    BOOST_ASSERT( (icmp::v4() == protocol) || (icmp::v6() == protocol) );
-
     IcmpPacketItem icmp_packet;
 
     if ( icmp::v4() == protocol )
     }
     else
     {
-        BOOST_ASSERT( !"Invalid ICMP Packet Type." );                                                                                       //lint !e506
+        GlobalLogger.warning() << "ICMP packet creation failed: "
+            << "Unknown protocol, expect ICMP v4 or v6!" << endl;
+        icmp_packet.reset();    // --> (!icmp_packet) is true
+        return icmp_packet;
     }
 
-    if ( !icmp_packet->read( is ) )
+    IcmpPacket::ReadReturnCode return_code = icmp_packet->read( is );
+    if ( return_code != IcmpPacket::ReadReturnCode_OK )
     {
-        GlobalLogger.info() << "ICMP packet creation failed" << endl;
+        GlobalLogger.warning() << "ICMP packet creation failed: "
+            << IcmpPacket::return_code_to_string(return_code) << endl;
         icmp_packet.reset();    // --> (!icmp_packet) is true
            // --> icmp_pinger will not try to continue working with this packet
 
         // TODO why good packets are reports as bad? The read() has problems!
     }
+    else if ( !is.good() )
+    {
+        GlobalLogger.warning() << "ICMP packet creation failed: "
+            << "Stream not good at end of creation!" << endl;
+        icmp_packet.reset();    // --> (!icmp_packet) is true
+    }
 
     return icmp_packet;
 }
 
     ReplyReceived( false ),
     EchoReplyTimeoutInSec( echo_reply_timeout_in_sec ),
     PingerStatus( PingStatus_NotSent ),
-    PingDoneCallback()
+    PingDoneCallback(),
+    ReceiveHandlerInPlace( false )
 {
     if ( !NetInterface.bind() )
     {
-        GlobalLogger.error() << "Error: could not bind the socket with the local interface. "
-                << ::strerror( errno )  << endl;
+        GlobalLogger.error()
+           << DestinationEndpoint.address().to_string()
+           << ": could not bind the socket with the local interface. "
+           << ::strerror( errno )  << endl;
     }
 
     // Create "unique" identifier
     ostream os( &request_buffer );
     if ( !icmp_packet->write( os ) )
     {
-        GlobalLogger.error() << "Error: fail writing ping data." << endl;
+        GlobalLogger.error()
+           << DestinationEndpoint.address().to_string()
+           << ": fail writing ping data." << endl;
     }
 
     TimeSent = microsec_clock::universal_time();
         size_t bytes_sent = Socket.send_to( data, DestinationEndpoint );
         if ( bytes_sent != buffer_size( data ) )
         {
-            GlobalLogger.error() << "Error: fail sending ping data." << endl;
+            GlobalLogger.error()
+                   << DestinationEndpoint.address().to_string()
+                   << ": fail sending ping data." << endl;
         }
     }
     catch ( const exception &ex )
     {
-        GlobalLogger.error() << "Error: fail sending ping data. " << ex.what() << endl;
+        GlobalLogger.error()
+                   << DestinationEndpoint.address().to_string()
+                   << ": fail sending ping data. " << ex.what() << endl;
     }
 
     schedule_timeout_echo_reply();
     // is also called by Timer.cancel();
     if ( !ReplyReceived )
     {
-        GlobalLogger.info() << "Request timed out" << endl;
+        GlobalLogger.info()
+                   << DestinationEndpoint.address().to_string()
+                   << ": Request timed out" << endl;
 
         set_ping_status( PingStatus_FailureTimeout );
     }
 
 void IcmpPinger::start_receive()
 {
-    // Discard any data already in the buffer.
-    if (ReplyBuffer.size() > 0)
-        GlobalLogger.debug() << "consuming unused " << ReplyBuffer.size() << "bytes!" << endl;
-    ReplyBuffer.consume( ReplyBuffer.size() );
+    if ( ReceiveHandlerInPlace )
+    {
+        GlobalLogger.info()
+                   << DestinationEndpoint.address().to_string()
+                   << ": Receive Handler in place, do not schedule another one" << endl;
+        return;
+    }
 
     // Waiting for a reply, We prepare the buffer to receive up to SOCKET_BUFFER_SIZE bytes
     Socket.async_receive(
             ReplyBuffer.prepare( SOCKET_BUFFER_SIZE ),
-            boost::bind( &IcmpPinger::handle_receive_icmp_packet, this, _2 )
+            boost::bind( &IcmpPinger::handle_receive_icmp_packet, this, _1, _2 )
     );
+    ReceiveHandlerInPlace = true;
 }
 
 /**
  * @param bytes_transferred Number of bytes transferred.
  * @return void
  **/
-void IcmpPinger::handle_receive_icmp_packet( const size_t &bytes_transferred )
+void IcmpPinger::handle_receive_icmp_packet( const boost::system::error_code &error,
+                                             const size_t &bytes_transferred )
 {
+
+    ReceiveHandlerInPlace = false;
+
+    if ( error )
+    {
+        GlobalLogger.warning()
+           << DestinationEndpoint.address().to_string()
+           << ": Received error " << error << " in ICMP packet handler; end handler.";
+        return;
+    }
+    if ( ReplyReceived )
+    {
+        GlobalLogger.info()
+            << DestinationEndpoint.address().to_string()
+            << ": Got another call to handler, probably due to earlier timeout. "
+            << "Ignore it." << endl;
+        return;
+    }
+
     // The actual number of bytes received is committed to the buffer so that we
     // can extract it using a std::istream object.
     ReplyBuffer.commit( bytes_transferred );
         istream is( &ReplyBuffer );
         if ( !is )
         {
-            GlobalLogger.error() << "Error: can't handle ReplyBuffer" << endl;
+            GlobalLogger.error()
+               << DestinationEndpoint.address().to_string()
+               << ": Can't handle ReplyBuffer" << endl;
             return;
         }
 
         IcmpPacketItem icmp_packet = IcmpPacketFactory::create_icmp_packet( Protocol, is );
         if ( !icmp_packet )
         {
-            GlobalLogger.notice() << "Warning: ignoring broken ICMP packet" << endl;
+            GlobalLogger.warning()
+               << DestinationEndpoint.address().to_string()
+               << ": Ignoring broken ICMP packet" << endl;
             return;
         }
 
                                 Identifier, SequenceNumber,
                                 DestinationEndpoint.address() ) )
         {
+            GlobalLogger.info()
+               << DestinationEndpoint.address().to_string()
+               << ": Received reply" << endl;
+
             ReplyReceived = true;
 
             icmp_packet->print_echo_reply( bytes_transferred, TimeSent );
                                      Identifier, SequenceNumber,
                                      DestinationEndpoint.address() ) )
         {
+            GlobalLogger.info()
+               << DestinationEndpoint.address().to_string()
+               << ": Received destination unreachable" << endl;
+
             ReplyReceived = true;
 
             icmp_packet->print_destination_unreachable();
         // Unknown ICMP reply, start another receive till timeout
         else
         {
+            GlobalLogger.info()
+               << DestinationEndpoint.address().to_string()
+               << ": Received packet that does not match" << endl;
             start_receive();
         }
     }
     catch ( ... )
     {
-        GlobalLogger.notice() << "Warning: exception during ICMP parse. "
+        GlobalLogger.notice()
+           << DestinationEndpoint.address().to_string()
+           << ": exception during ICMP parse. "
             << "Starting another receive till timeout." << endl;
         start_receive();
     }