public void route(IQ packet) {
        if (packet == null) {
            throw new NullPointerException();
        }
        JID sender = packet.getFrom();
        ClientSession session = sessionManager.getSession(sender);
        Element childElement = packet.getChildElement(); // may be null
        try {
            // Invoke the interceptors before we process the read packet
            InterceptorManager.getInstance().invokeInterceptors(packet, session, true, false);
            JID to = packet.getTo();
            if (session == null || session.isAuthenticated() || (
                    childElement != null && isLocalServer(to) && (
                        "jabber:iq:auth".equals(childElement.getNamespaceURI()) ||
                        "jabber:iq:register".equals(childElement.getNamespaceURI()) ||
                        "urn:ietf:params:xml:ns:xmpp-bind".equals(childElement.getNamespaceURI())))) {
                handle(packet);
            } else if (SessionPacketRouter.isInvalidStanzaSentPriorToResourceBinding(packet, session)) {
                Log.debug("Closing session that attempts to send stanza to an entity other than the server itself or the client's account, before completing resource binding. Session closed: {}", session);
                session.deliverRawText(new StreamError(StreamError.Condition.not_authorized, "Do not send invalid stanza prior to authentication/resource binding.").toXML());
                session.close();
                return;
            } else {
                Log.debug("Rejecting stanza from client that has not (yet?) established an authenticated session: {}", packet.toXML());
                if (packet.getType() == IQ.Type.get || packet.getType() == IQ.Type.set) {
                    IQ reply = IQ.createResultIQ(packet);
                    if (childElement != null) {
                        reply.setChildElement(childElement.createCopy());
                    }
                    reply.setError(PacketError.Condition.not_authorized);
                    session.process(reply);
                }
            }
            // Invoke the interceptors after we have processed the read packet
            InterceptorManager.getInstance().invokeInterceptors(packet, session, true, true);
        }
        catch (PacketRejectedException e) {
            if (session != null) {
                // An interceptor rejected this packet so answer with an error
                IQ reply = new IQ();
                if (childElement != null) {
                    reply.setChildElement(childElement.createCopy());
                }
                reply.setID(packet.getID());
                reply.setTo(session.getAddress());
                reply.setFrom(packet.getTo());

                if (e.getRejectionError() != null) {
                    reply.setError(e.getRejectionError());
                } else {
                    reply.setError(PacketError.Condition.not_allowed);
                }
                session.process(reply);

                // Check if a message notifying the rejection should be sent
                if (e.getRejectionMessage() != null && !e.getRejectionMessage().trim().isEmpty()) {
                    // A message for the rejection will be sent to the sender of the rejected packet
                    Message notification = new Message();
                    notification.setTo(session.getAddress());
                    notification.setFrom(packet.getTo());
                    notification.setBody(e.getRejectionMessage());
                    session.process(notification);
                }
            }
        }
    }
<p>Performs the actual packet routing.</p>
<p>You routing is considered 'quick' and implementations may not take
excessive amounts of time to complete the routing. If routing will take
a long amount of time, the actual routing should be done in another thread
so this method returns quickly.</p>
<h2>Warning</h2>
<p>Be careful to enforce concurrency DbC of concurrent by synchronizing
any accesses to class resources.</p>

@param packet The packet to route
@throws NullPointerException If the packet is null
xmppserver/src/main/java/org/jivesoftware/openfire/IQRouter.java