@Override
  public void sendPacket(Component component, Packet packet) {
    if (packet != null && packet.getFrom() == null) {
      throw new IllegalArgumentException(
          "Packet with no FROM address was received from component.");
    }

    PacketRouter router = XMPPServer.getInstance().getPacketRouter();
    if (router != null) {
      router.route(packet);
    }
  }
 /**
  * Remove the roster item from the sender's roster (and possibly the recipient's). Actual roster
  * removal is done in the removeItem(Roster,RosterItem) method.
  *
  * @param roster The sender's roster.
  * @param sender The JID of the sender of the removal request
  * @param item The removal item element
  */
 private void removeItem(
     org.jivesoftware.openfire.roster.Roster roster, JID sender, org.xmpp.packet.Roster.Item item)
     throws SharedGroupException {
   JID recipient = item.getJID();
   // Remove recipient from the sender's roster
   roster.deleteRosterItem(item.getJID(), true);
   // Forward set packet to the subscriber
   if (localServer.isLocal(recipient)) { // Recipient is local so let's handle it here
     try {
       Roster recipientRoster = userManager.getUser(recipient.getNode()).getRoster();
       recipientRoster.deleteRosterItem(sender, true);
     } catch (UserNotFoundException e) {
       // Do nothing
     }
   } else {
     // Recipient is remote so we just forward the packet to them
     String serverDomain = localServer.getServerInfo().getXMPPDomain();
     // Check if the recipient may be hosted by this server
     if (!recipient.getDomain().contains(serverDomain)) {
       // TODO Implete when s2s is implemented
     } else {
       Packet removePacket = createRemoveForward(sender, recipient);
       router.route(removePacket);
     }
   }
 }
  /**
   * Handles the IQ packet sent by an owner of the room. Possible actions are:
   *
   * <ul>
   *   <li>Return the list of owners
   *   <li>Return the list of admins
   *   <li>Change user's affiliation to owner
   *   <li>Change user's affiliation to admin
   *   <li>Change user's affiliation to member
   *   <li>Change user's affiliation to none
   *   <li>Destroy the room
   *   <li>Return the room configuration within a dataform
   *   <li>Update the room configuration based on the sent dataform
   * </ul>
   *
   * @param packet the IQ packet sent by an owner of the room.
   * @param role the role of the user that sent the packet.
   * @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.
   */
  @SuppressWarnings("unchecked")
  public void handleIQ(IQ packet, MUCRole role)
      throws ForbiddenException, ConflictException, CannotBeInvitedException {
    // Only owners can send packets with the namespace "http://jabber.org/protocol/muc#owner"
    if (MUCRole.Affiliation.owner != role.getAffiliation()) {
      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(role, formElement);
    } else {
      Element destroyElement = element.element("destroy");
      if (destroyElement != null) {
        if (((MultiUserChatServiceImpl) room.getMUCService()).getMUCDelegate() != null) {
          if (!((MultiUserChatServiceImpl) room.getMUCService())
              .getMUCDelegate()
              .destroyingRoom(room.getName(), role.getUserAddress())) {
            // 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);
        }
        room.destroyRoom(alternateJID, destroyElement.elementTextTrim("reason"));
      } else {
        // If no element was included in the query element then answer the
        // configuration form
        if (!element.elementIterator().hasNext()) {
          refreshConfigurationFormValues();
          reply.setChildElement(probeResult.createCopy());
        }
        // 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)
      router.route(reply);
    }
  }
  public void send(Packet packet) {
    if (packet == null) {
      return;
    }
    packet.setTo(user.getAddress());

    if (session != null && session.getStatus() == Session.STATUS_AUTHENTICATED) {
      // Send the packet directly to the local user session
      session.process(packet);
    } else {
      router.route(packet);
    }
  }