class HANewSnapshotFunction implements Serializable,
        BiFunction<Iterable<MemberIsAvailable>,MemberIsAvailable,Iterable<MemberIsAvailable>> {

    @Override
    public Iterable<MemberIsAvailable> apply( Iterable<MemberIsAvailable> previousSnapshot,
            final MemberIsAvailable newMessage )
    {
        /*
         * If a master event is received, all events that set to slave that instance should be removed. The same
         * should happen to existing master events and backup events, no matter which instance they are for
         */
        if ( newMessage.getRole().equals( MASTER ) )
        {
            List<MemberIsAvailable> result = new LinkedList<>();
            for ( MemberIsAvailable existing : previousSnapshot )
            {
                if ( (isSlave( existing ) && sameIds( newMessage, existing ))
                        || isMaster( existing ) )
                {
                    continue;
                }
                result.add( existing );
            }
            result.add( newMessage );
            return result;
        }
        /*
         * If a slave event is received, all existing slave events for that instance should be removed. The same for
         * master and backup, which means remove all events for that instance.
         */
        else if ( newMessage.getRole().equals( SLAVE ) )
        {
            List<MemberIsAvailable> result = new LinkedList<>();
            for ( MemberIsAvailable existing : previousSnapshot )
            {
                if ( sameIds( newMessage, existing ) )
                {
                    continue;
                }
                result.add( existing );
            }
            result.add( newMessage );
            return result;
        }
        else if ( newMessage.getRole().equals( OnlineBackupKernelExtension.BACKUP ) )
        {
            List<MemberIsAvailable> result = new LinkedList<>();
            for ( MemberIsAvailable existing : previousSnapshot )
            {
                if ( existing.getRole().equals( OnlineBackupKernelExtension.BACKUP ) )
                {
                    continue;
                }
                result.add( existing );
            }
            result.add( newMessage );
            return result;
        }
        return Iterables.append( newMessage, previousSnapshot );
    }

}