class HeartbeatIAmAliveProcessor implements MessageProcessor {

    @Override
    public boolean process( Message<? extends MessageType> message )
    {
        if ( !message.isInternal() &&
                !message.getMessageType().equals( HeartbeatMessage.i_am_alive ) &&
                !message.getMessageType().equals( HeartbeatMessage.suspicions ) )
        {
            // We assume the HEADER_FROM header always exists.
            String from =  message.getHeader( Message.HEADER_FROM );
            if ( !from.equals( message.getHeader( Message.HEADER_TO ) )  )
            {
                InstanceId theId;
                if ( message.hasHeader( Message.HEADER_INSTANCE_ID ) )
                {
                    // HEADER_INSTANCE_ID is there since after 1.9.6
                    theId = new InstanceId( Integer.parseInt( message.getHeader( Message.HEADER_INSTANCE_ID ) ) );
                }
                else
                {
                    theId = clusterContext.getConfiguration().getIdForUri( URI.create( from ) );
                }

                if ( theId != null && clusterContext.getConfiguration().getMembers().containsKey( theId )
                        && !clusterContext.isMe( theId ) )
                {
                    Message<HeartbeatMessage> heartbeatMessage = message.copyHeadersTo(
                            Message.internal( HeartbeatMessage.i_am_alive,
                                    new HeartbeatMessage.IAmAliveState( theId ) ),
                            Message.HEADER_FROM, Message.HEADER_INSTANCE_ID
                    );
                    output.offer( heartbeatMessage );
                }
            }
        }
        return true;
    }

    public  HeartbeatIAmAliveProcessor( MessageHolder output, ClusterContext clusterContext );

}