IcmpDestinationUnreachableMessage::IcmpDestinationUnreachableMessage()
 {
     fill( Payload, Payload + sizeof(Payload), 0 );
-
-    set_type( IcmpType_InvalidLast );
-    set_code( 0 );
-    set_checksum( 0 );
-    set_identifier( 0 );
-    set_sequence_number( 0 );
-}
-
-IcmpDestinationUnreachableMessage::IcmpDestinationUnreachableMessage(
-        const IcmpType type,
-        const uint8_t code,
-        const uint16_t checksum,
-        const uint16_t identifier,
-        const uint16_t sequence_number
-)
-{
-    fill( Payload, Payload + sizeof(Payload), 0 );
-
-    set_type( type );
-    set_code( code );
-    set_checksum( checksum );
-    set_identifier( identifier );
-    set_sequence_number( sequence_number );
 }
 
 IcmpDestinationUnreachableMessage::~IcmpDestinationUnreachableMessage()
 
 {
 public:
     IcmpDestinationUnreachableMessage();
-    IcmpDestinationUnreachableMessage(
-            const IcmpType type,
-            const uint8_t code,
-            const uint16_t checksum,
-            const uint16_t identifier,
-            const uint16_t sequence_number
-    );
     virtual ~IcmpDestinationUnreachableMessage();
 
     IcmpType get_type() const;
 
 IcmpEchoReplyMessage::IcmpEchoReplyMessage()
 {
     fill( Payload, Payload + sizeof(Payload), 0 );
-
-    set_type( IcmpType_InvalidLast );
-    set_code( 0 );
-    set_checksum( 0 );
-    set_identifier( 0 );
-    set_sequence_number( 0 );
-}
-
-IcmpEchoReplyMessage::IcmpEchoReplyMessage(
-        const IcmpType type,
-        const uint8_t code,
-        const uint16_t checksum,
-        const uint16_t identifier,
-        const uint16_t sequence_number
-)
-{
-    fill( Payload, Payload + sizeof(Payload), 0 );
-
-    set_type( type );
-    set_code( code );
-    set_checksum( checksum );
-    set_identifier( identifier );
-    set_sequence_number( sequence_number );
 }
 
 IcmpEchoReplyMessage::~IcmpEchoReplyMessage()
 
 {
 public:
     IcmpEchoReplyMessage();
-    IcmpEchoReplyMessage(
-            const IcmpType type,
-            const uint8_t code,
-            const uint16_t checksum,
-            const uint16_t identifier,
-            const uint16_t sequence_number
-    );
     virtual ~IcmpEchoReplyMessage();
 
     IcmpType get_type() const;
 
 IcmpEchoRequestMessage::IcmpEchoRequestMessage()
 {
     fill( Payload, Payload + sizeof(Payload), 0 );
-
-    set_type( IcmpType_InvalidLast );
-    set_code( 0 );
-    set_checksum( 0 );
-    set_identifier( 0 );
-    set_sequence_number( 0 );
-}
-
-IcmpEchoRequestMessage::IcmpEchoRequestMessage(
-        const IcmpType type,
-        const uint8_t code,
-        const uint16_t checksum,
-        const uint16_t identifier,
-        const uint16_t sequence_number
-)
-{
-    fill( Payload, Payload + sizeof(Payload), 0 );
-
-    set_type( type );
-    set_code( code );
-    set_checksum( checksum );
-    set_identifier( identifier );
-    set_sequence_number( sequence_number );
 }
 
 IcmpEchoRequestMessage::~IcmpEchoRequestMessage()
 
 {
 public:
     IcmpEchoRequestMessage();
-    IcmpEchoRequestMessage(
-            const IcmpType type,
-            const uint8_t code,
-            const uint16_t checksum,
-            const uint16_t identifier,
-            const uint16_t sequence_number
-    );
     virtual ~IcmpEchoRequestMessage();
 
     IcmpType get_type() const;
 
 
 IcmpGenericMessage::IcmpGenericMessage()
 {
-    set_type( IcmpType_InvalidLast );
-    set_code( 0 );
-    set_checksum( 0 );
-    set_identifier( 0 );
-    set_sequence_number( 0 );
-}
-
-IcmpGenericMessage::IcmpGenericMessage(
-        const IcmpType type,
-        const uint8_t code,
-        const uint16_t checksum,
-        const uint16_t identifier,
-        const uint16_t sequence_number
-)
-{
-    set_type( type );
-    set_code( code );
-    set_checksum( checksum );
-    set_identifier( identifier );
-    set_sequence_number( sequence_number );
 }
 
 IcmpGenericMessage::~IcmpGenericMessage()
 
 IcmpType IcmpGenericMessage::get_type() const
 {
-    return IcmpType_InvalidLast;
+    return IcmpType_Generic;
 }
 
 void IcmpGenericMessage::set_type( IcmpType )
 
 {
 public:
     IcmpGenericMessage();
-    IcmpGenericMessage(
-            const IcmpType type,
-            const uint8_t code,
-            const uint16_t checksum,
-            const uint16_t identifier,
-            const uint16_t sequence_number
-    );
     virtual ~IcmpGenericMessage();
 
     IcmpType get_type() const;
 
                 break;
             case IcmpType_DestinationUnreachable:
                 MessageFormat.reset(
-                        new IcmpDestinationUnreachableMessage );
+                        new IcmpDestinationUnreachableMessage
+                );
                 break;
-            default:
+            case IcmpType_SourceQuench:
+            case IcmpType_Redirect:
+            case IcmpType_TimeExceeded:
+            case IcmpType_ParameterProblem:
+            case IcmpType_TimestampRequest:
+            case IcmpType_TimestampReply:
+            case IcmpType_InfoRequest:
+            case IcmpType_InfoReply:
+            case IcmpType_AddressRequest:
+            case IcmpType_AddressReply:
                 MessageFormat.reset( new IcmpGenericMessage );
                 break;
+            case IcmpType_InvalidLast:
+            default:
+                BOOST_ASSERT( false );
+                break;
         }
+
+        MessageFormat->init( type );
     }
+
+    BOOST_ASSERT( MessageFormat.get() != NULL );
+    BOOST_ASSERT( MessageFormat->get_type() != IcmpType_InvalidLast );
 }
 
 void IcmpHeader::set_icmp_message_format( std::istream &is )
 {
     // read the first byte, which contains the type of the ICMP message
     char first_byte;
-    is.read( &first_byte, 1 );
+    (void) is.read( &first_byte, 1 );
 
     // must keep the stream intact, so place the read byte back
-    is.putback( first_byte );
+    (void) is.putback( first_byte );
 
     // now select the message format for the given type
     IcmpType header_type = static_cast<IcmpType> ( first_byte );
 
 IcmpMessage::~IcmpMessage()
 {
 }
+
+/**
+ * This method MUST be called to initialize the data member of ICMP Messages.
+ */
+void IcmpMessage::init( const IcmpType type )
+{
+    // Note: this code can not be placed in the constructor, because it calls
+    // virtual function. If you call virtual functions from within a
+    // constructor, the Base class version of methods will be called, not the
+    // Derived class, because the Base is constructed before the Derived class.
+    set_type( type );
+    set_code( 0 );
+    set_checksum( 0 );
+    set_identifier( 0 );
+    set_sequence_number( 0 );
+}
 
     IcmpMessage();
     virtual ~IcmpMessage();
 
+    void init( const IcmpType type );
+
     virtual IcmpType get_type() const = 0;
     virtual void set_type( const IcmpType type ) = 0;
 
 
     IcmpType_InfoReply = 16,
     IcmpType_AddressRequest = 17,
     IcmpType_AddressReply = 18,
-    IcmpType_InvalidLast = 42
+    IcmpType_InvalidLast = 42,
+    IcmpType_Generic = 43
 };
 
 #endif /* ICMP_TYPE_H */