public void handleIQ(@Nonnull final IQ packet, @Nullable final MUCOccupant actorOccupant) throws ForbiddenException, ConflictException, CannotBeInvitedException, NotAcceptableException, NotAllowedException
    {
        final Affiliation actorAffiliation = actorOccupant != null ? actorOccupant.getAffiliation() : room.getAffiliation(packet.getFrom());

        // Only owners can send packets with the namespace "http://jabber.org/protocol/muc#owner"
        if (Affiliation.owner != actorAffiliation) {
            throw new ForbiddenException();
        }

        IQ reply = IQ.createResultIQ(packet);
        Element element = packet.getChildElement();

        // Analyze the action to perform based on the included element
        Element formElement = element.element(QName.get("x", "jabber:x:data"));
        if (formElement != null) {
            handleDataFormElement(actorAffiliation, packet.getFrom(), formElement);
        }
        else {
            Element destroyElement = element.element("destroy");
            if (destroyElement != null) {
                if (room.getMUCService().getMUCDelegate() != null) {
                    if (!room.getMUCService().getMUCDelegate().destroyingRoom(room.getName(), packet.getFrom())) {
                        // Delegate said no, reject destroy request.
                        throw new ForbiddenException();
                    }
                }

                JID alternateJID = null;
                final String jid = destroyElement.attributeValue("jid");
                if (jid != null) {
                    alternateJID = new JID(jid);
                }
                final String password = destroyElement.elementTextTrim("password");
                room.destroyRoom(alternateJID, password, destroyElement.elementTextTrim("reason"));
            }
            else {
                // If no element was included in the query element then answer the
                // configuration form
                if (!element.elementIterator().hasNext()) {
                    final Locale preferredLocale = SessionManager.getInstance().getLocaleForSession(packet.getFrom());
                    reply.setChildElement(generateProbeResult(preferredLocale));
                }
                // An unknown and possibly incorrect element was included in the query
                // element so answer a BAD_REQUEST error
                else {
                    reply.setChildElement(packet.getChildElement().createCopy());
                    reply.setError(PacketError.Condition.bad_request);
                }
            }
        }
        if (reply.getTo() != null) {
            // Send a reply only if the sender of the original packet was from a real JID. (i.e. not
            // a packet generated locally)
            XMPPServer.getInstance().getPacketRouter().route(reply);
        }
    }
Handles the IQ packet sent by an owner of the room. Possible actions are:
<ul>
<li>Return the list of owners</li>
<li>Return the list of admins</li>
<li>Change user's affiliation to owner</li>
<li>Change user's affiliation to admin</li>
<li>Change user's affiliation to member</li>
<li>Change user's affiliation to none</li>
<li>Destroy the room</li>
<li>Return the room configuration within a dataform</li>
<li>Update the room configuration based on the sent dataform</li>
</ul>

@param packet the IQ packet sent by an owner of the room.
@param actorOccupant the occupant that sent the packet, if it was sent by an occupant.
@throws ForbiddenException if the user does not have enough permissions (ie. is not an owner).
@throws ConflictException If the room was going to lose all of its owners.
@throws CannotBeInvitedException never
@throws NotAcceptableException if the room requires a password that was not supplied
xmppserver/src/main/java/org/jivesoftware/openfire/muc/spi/IQOwnerHandler.java