@Override
    public void receivedAnswer(IQ packet) {
        // Look for the root node being discovered
        String domain = packet.getFrom().toString();
        boolean isRoot = true;
        if (!nodes.containsKey(domain)) {
            domain = roots.get(domain);
            isRoot = false;
        }

        // Check if this is a disco#info response
        if ("http://jabber.org/protocol/disco#info"
                .equals(packet.getChildElement().getNamespaceURI())) {

            // Check if the node supports JEP-33
            boolean supports = false;
            for (Iterator<Element> it = packet.getChildElement().elementIterator("feature"); it.hasNext();) {
                if (NAMESPACE.equals(it.next().attributeValue("var"))) {
                    supports = true;
                    break;
                }
            }

            if (supports) {
                // JEP-33 is supported by the entity
                Collection<String> items = nodes.remove(domain);
                for (String item : items) {
                    roots.remove(item);
                }
                String multicastService = packet.getFrom().toString();
                cache.put(domain, multicastService);
                sendToRemoteServer(domain, multicastService);
            }
            else {
                if (isRoot && IQ.Type.error != packet.getType()) {
                    // Discover node items with the hope that a sub-item supports JEP-33
                    IQ iq = new IQ(IQ.Type.get);
                    iq.setFrom(server.getServerInfo().getXMPPDomain());
                    iq.setTo(packet.getFrom());
                    iq.setChildElement("query", "http://jabber.org/protocol/disco#items");
                    // Send the disco#items request to the remote server or component. The reply will be
                    // processed by the IQResultListener (interface that this class implements)
                    iqRouter.addIQResultListener(iq.getID(), this);
                    iqRouter.route(iq);
                }
                else if (!isRoot) {
                    // Process the disco#info response of an item that does not support JEP-33
                    roots.remove(packet.getFrom().toString());
                    Collection<String> items = nodes.get(domain);
                    if (items != null) {
                        items.remove(packet.getFrom().toString());
                        if (items.isEmpty()) {
                            nodes.remove(domain);
                            cache.put(domain, "");
                            sendToRemoteServer(domain, "");
                        }
                    }
                }
                else {
                    // Root domain does not support disco#info
                    nodes.remove(domain);
                    cache.put(domain, "");
                    sendToRemoteServer(domain, "");
                }
            }

        }
        else {
            // This is a disco#items response
            Collection<Element> items = packet.getChildElement().elements("item");

            if (IQ.Type.error == packet.getType() || items.isEmpty()) {
                // Root domain does not support disco#items
                nodes.remove(domain);
                cache.put(domain, "");
                sendToRemoteServer(domain, "");
            }
            else {
                // Keep the list of items found in the requested domain
                List<String> jids = new ArrayList<>();
                for (Element item : items) {
                    String jid = item.attributeValue("jid");
                    jids.add(jid);
                    // Add that this item was found for the following domain
                    roots.put(jid, domain);
                }
                nodes.put(domain, new CopyOnWriteArrayList<>(jids));

                // Send disco#info to each discovered item
                for (Element item : items) {
                    // Discover if remote server supports JEP-33 (Extended Stanza Addressing)
                    IQ iq = new IQ(IQ.Type.get);
                    iq.setFrom(server.getServerInfo().getXMPPDomain());
                    iq.setTo(item.attributeValue("jid"));
                    Element child = iq.setChildElement("query", "http://jabber.org/protocol/disco#info");
                    if (item.attributeValue("node") != null) {
                        child.addAttribute("node", item.attributeValue("node"));
                    }
                    // Send the disco#info request to the discovered item. The reply will be
                    // processed by the IQResultListener (interface that this class implements)
                    iqRouter.addIQResultListener(iq.getID(), this);
                    iqRouter.route(iq);
                }
            }
        }
    }
Actually sends pending packets of the specified domain using the discovered multicast
service address. If remote server supports multicast service then a copy of the
orignal will be sent to the remote server. However, if no multicast service was found
then the local server sends a copy of the original stanza to each address.

@param domain domain of the remote server with pending packets.
@param multicastService address of the discovered multicast service.
xmppserver/src/main/java/org/jivesoftware/openfire/MulticastRouter.java