@Override
    public Iterator<String> getFeatures(final String name, final String node, final JID senderJID) {
        final ArrayList<String> features = new ArrayList<>();
        if (name == null && node == null) {
            // Answer the features of the MUC service
            features.add("http://jabber.org/protocol/muc");
            features.add("http://jabber.org/protocol/disco#info");
            features.add("http://jabber.org/protocol/disco#items");
            if (IQExtendedChannelSearchHandler.PROPERTY_ENABLED.getValue()) {
                features.add(IQExtendedChannelSearchHandler.NAMESPACE);
            }
            if (IQMuclumbusSearchHandler.PROPERTY_ENABLED.getValue()) {
                features.add(IQMuclumbusSearchHandler.NAMESPACE);
            }
            features.add( "jabber:iq:search" );
            features.add(ResultSet.NAMESPACE_RESULT_SET_MANAGEMENT);
            if (!extraDiscoFeatures.isEmpty()) {
                features.addAll(extraDiscoFeatures);
            }
        }
        else if (name != null && node == null) {
            // Answer the features of a given room
            final MUCRoom room = getChatRoom(name);
            if (room != null) {
                features.add("http://jabber.org/protocol/muc");
                if (room.isPublicRoom()) {
                    features.add("muc_public");
                } else {
                    features.add("muc_hidden");
                }
                if (room.isMembersOnly()) {
                    features.add("muc_membersonly");
                }
                else {
                    features.add("muc_open");
                }
                if (room.isModerated()) {
                    features.add("muc_moderated");
                }
                else {
                    features.add("muc_unmoderated");
                }
                if (room.canAnyoneDiscoverJID()) {
                    features.add("muc_nonanonymous");
                }
                else {
                    features.add("muc_semianonymous");
                }
                if (room.isPasswordProtected()) {
                    features.add("muc_passwordprotected");
                }
                else {
                    features.add("muc_unsecured");
                }
                if (room.isPersistent()) {
                    features.add("muc_persistent");
                }
                else {
                    features.add("muc_temporary");
                }
                if (!extraDiscoFeatures.isEmpty()) {
                    features.addAll(extraDiscoFeatures);
                }
                if ( JiveGlobals.getBooleanProperty( "xmpp.muc.self-ping.enabled", true ) ) {
                    features.add( "http://jabber.org/protocol/muc#self-ping-optimization" );
                }
                if ( IQMUCvCardHandler.PROPERTY_ENABLED.getValue() ) {
                    features.add( IQMUCvCardHandler.NAMESPACE );
                }
                features.add( "urn:xmpp:sid:0" );
                features.add( "urn:xmpp:occupant-id:0" );
            }
        }
        return features.iterator();
    }
Returns the total number of outgoing messages since last reset.

@param resetAfter True if you want the counter to be reset after results returned.
@return the number of outgoing messages through the service.
xmppserver/src/main/java/org/jivesoftware/openfire/muc/spi/MultiUserChatServiceImpl.java