public boolean isDeliveryRelatedErrorResponse(@Nonnull final Packet stanza)
    {
        if (stanza instanceof IQ) {
            final IQ iq = ((IQ)stanza);
            if (iq.getType() != IQ.Type.error) {
                return false;
            }

            // Check if this is an error to a ghost-detection ping that we've sent out. Note that clients that are
            // connected but do not support XEP-0199 should send back a 'service-unavailable' error per the XEP, but
            // some clients are known to send 'feature-not-available'. Treat these as indications that the client is
            // still connected.
            final Collection<PacketError.Condition> pingErrorsIndicatingClientConnectivity = Arrays.asList(
                PacketError.Condition.service_unavailable,
                PacketError.Condition.feature_not_implemented
            );

            if (stanza.getError() != null && pingErrorsIndicatingClientConnectivity.contains(stanza.getError().getCondition())) {
                return false;
            }

            final JID jid = PINGS_SENT.get(iq.getID());
            return jid != null && iq.getFrom().equals(jid) && stanza.getError() != null;
        }

        // The remainder of this implementation applies to Message and Presence stanzas.

        // Conditions as defined in XEP-0045, section 'ghost users'.
        final Collection<PacketError.Condition> deliveryRelatedErrorConditions = Arrays.asList(
            PacketError.Condition.gone,
            PacketError.Condition.item_not_found,
            PacketError.Condition.recipient_unavailable,
            PacketError.Condition.redirect,
            PacketError.Condition.remote_server_not_found,
            PacketError.Condition.remote_server_timeout
        );

        final PacketError error = stanza.getError();
        return error != null && deliveryRelatedErrorConditions.contains(error.getCondition());
    }
Determines if a stanza is sent by (on behalf of) an entity that MUC room believes to be an occupant
when they've left: a 'ghost' occupant

For message and presence stanzas, the delivery errors as defined in section 18.1.2 of XEP-0045 are used.

For IQ stanzas, these errors may be due to lack of client support rather than a vanished occupant. Therefore,
IQ stanzas will only return 'true' when they are an error response to an IQ Ping request sent by this server.

@param stanza The stanza to check
@return true if the stanza is a delivery related error response (from a 'ghost user'), otherwise false.
@see <a href="https://xmpp.org/extensions/xep-0045.html#impl-service-ghosts">XEP-0045, section 'ghost users'</a>
xmppserver/src/main/java/org/jivesoftware/openfire/muc/spi/MultiUserChatServiceImpl.java