class StateTransitionLogger implements StateTransitionListener {

    @Override
    public void stateTransition( StateTransition transition )
    {
        Log log = logProvider.getLog( transition.getOldState().getClass() );

        if ( log.isDebugEnabled() )
        {
            if ( transition.getOldState() == HeartbeatState.heartbeat )
            {
                return;
            }

            // The bulk of the message
            String state = transition.getOldState().getClass().getSuperclass().getSimpleName();
            StringBuilder line = new StringBuilder( state ).append( ": " ).append( transition );

            // Who was this message from?
            if ( transition.getMessage().hasHeader( HEADER_FROM ) )
            {
                line.append( " from:" ).append( transition.getMessage().getHeader( HEADER_FROM ) );
            }

            if ( transition.getMessage().hasHeader( INSTANCE ) )
            {
                line.append( " instance:" ).append( transition.getMessage().getHeader( INSTANCE ) );
            }

            if ( transition.getMessage().hasHeader( HEADER_CONVERSATION_ID ) )
            {
                line.append( " conversation-id:" ).append( transition.getMessage().getHeader( HEADER_CONVERSATION_ID ) );
            }

            Object payload = transition.getMessage().getPayload();
            if ( payload != null )
            {
                if ( payload instanceof Payload )
                {
                    try
                    {
                        payload = atomicBroadcastSerializer.receive( (Payload) payload );
                    }
                    catch ( Throwable e )
                    {
                        // Ignore
                    }
                }

                line.append( " payload:" ).append( Strings.prettyPrint( payload ) );
            }

            // Throttle
            String msg = line.toString();
            if ( msg.equals( lastLogMessage ) )
            {
                return;
            }

            // Log it
            log.debug( line.toString() );
            lastLogMessage = msg;
        }
    }

    public  StateTransitionLogger( LogProvider logProvider, AtomicBroadcastSerializer atomicBroadcastSerializer );

}