private void handleRayoIQ(RayoIqProvider.DialIq dialIq) {
    String from = dialIq.getFrom();

    JitsiMeetConference conference = getConferenceForMucJid(from);

    if (conference == null) {
      logger.debug("Mute error: room not found for JID: " + from);
      return;
    }

    ChatRoomMemberRole role = conference.getRoleForMucJid(from);

    if (role == null) {
      // Only room members are allowed to send requests
      IQ error = createErrorResponse(dialIq, new XMPPError(XMPPError.Condition.forbidden));

      smackXmpp.getXmppConnection().sendPacket(error);

      return;
    }

    if (ChatRoomMemberRole.MODERATOR.compareTo(role) < 0) {
      // Moderator permission is required
      IQ error = createErrorResponse(dialIq, new XMPPError(XMPPError.Condition.not_allowed));

      smackXmpp.getXmppConnection().sendPacket(error);

      return;
    }

    // Check if Jigasi is available
    String jigasiJid = conference.getServices().getSipGateway();

    if (StringUtils.isNullOrEmpty(jigasiJid)) {
      // Not available
      IQ error =
          createErrorResponse(dialIq, new XMPPError(XMPPError.Condition.service_unavailable));

      smackXmpp.getXmppConnection().sendPacket(error);

      return;
    }

    // Redirect original request to Jigasi component
    String originalPacketId = dialIq.getPacketID();

    dialIq.setFrom(null);
    dialIq.setTo(jigasiJid);
    dialIq.setPacketID(IQ.nextID());

    IQ reply = (IQ) smackXmpp.getXmppConnection().sendPacketAndGetReply(dialIq);

    // Send Jigasi response back to the client
    reply.setFrom(null);
    reply.setTo(from);
    reply.setPacketID(originalPacketId);

    smackXmpp.getXmppConnection().sendPacket(reply);
  }
  /**
   * FIXME: replace with IQ.createErrorResponse Prosody does not allow to include request body in
   * error response. Replace this method with IQ.createErrorResponse once fixed.
   */
  private IQ createErrorResponse(IQ request, XMPPError error) {
    IQ.Type requestType = request.getType();
    if (!(requestType == IQ.Type.GET || requestType == IQ.Type.SET)) {
      throw new IllegalArgumentException(
          "IQ must be of type 'set' or 'get'. Original IQ: " + request.toXML());
    }

    final IQ result =
        new IQ() {
          @Override
          public String getChildElementXML() {
            return "";
          }
        };
    result.setType(IQ.Type.ERROR);
    result.setPacketID(request.getPacketID());
    result.setFrom(request.getTo());
    result.setTo(request.getFrom());
    result.setError(error);
    return result;
  }