private void publishItemsToNode(PubSubService service, IQ iq, Element publishElement) {
        String nodeID = publishElement.attributeValue("node");
        Node node;

        JID from = iq.getFrom();
        // TODO Assuming that owner is the bare JID (as defined in the JEP). This can be replaced with an explicit owner specified in the packet
        JID owner = from.asBareJID();

        if (nodeID == null) {
            // XEP-0060 Section 7.2.3.3 - No node was specified. Return bad_request error
            // This suggests that Instant nodes should not be auto-created
            Element pubsubError = DocumentHelper.createElement(QName.get("nodeid-required", "http://jabber.org/protocol/pubsub#errors"));
            sendErrorPacket(iq, PacketError.Condition.bad_request, pubsubError);
            return;
        }

        // Optional Publish Options.
        final DataForm publishOptions = getPublishOptions( iq );

        // Look for the specified node
        node = service.getNode(nodeID);
        if (node == null) {
            if (service instanceof PEPService && service.isServiceAdmin(owner) && canAutoCreate( publishOptions ) ) {
                // If it is a PEP service & publisher is service owner - auto create nodes.
                CreateNodeResponse response = createNodeHelper(service, iq.getFrom(), iq.getChildElement().element("configure"), publishElement.attributeValue("node"), publishOptions);

                if (response.newNode == null) {
                    // New node creation failed. Since pep#auto-create is advertised
                    // in disco#info, node creation error should be sent to the client.
                    sendErrorPacket(iq, response.creationStatus, response.pubsubError);
                    return;
                } else {
                    // Node creation succeeded, set node to newNode.
                    node = response.newNode;
                }
            } else {
                // Node does not exist. Return item-not-found error
                sendErrorPacket(iq, PacketError.Condition.item_not_found, null);
                return;
            }
        } else {
            // Check if the preconditions defined in the publish options (if any) are met.
            if ( !nodeMeetsPreconditions( node, publishOptions ) )
            {
                Element pubsubError = DocumentHelper.createElement(QName.get("precondition-not-met", "http://jabber.org/protocol/pubsub#errors"));
                sendErrorPacket(iq, PacketError.Condition.conflict, pubsubError);
                return;
            }
        }

        if (!node.getPublisherModel().canPublish(node, owner) && !service.isServiceAdmin(owner)) {
            // Entity does not have sufficient privileges to publish to node
            sendErrorPacket(iq, PacketError.Condition.forbidden, null);
            return;
        }

        if (node.isCollectionNode()) {
            // Node is a collection node. Return feature-not-implemented error
            Element pubsubError = DocumentHelper.createElement(
                    QName.get("unsupported", "http://jabber.org/protocol/pubsub#errors"));
            pubsubError.addAttribute("feature", "publish");
            sendErrorPacket(iq, PacketError.Condition.feature_not_implemented, pubsubError);
            return;
        }

        LeafNode leafNode = (LeafNode) node;
        Iterator<Element> itemElements = publishElement.elementIterator("item");

        // Check that an item was included if node persist items or includes payload
        if (!itemElements.hasNext() && leafNode.isItemRequired()) {
            Element pubsubError = DocumentHelper.createElement(QName.get(
                    "item-required", "http://jabber.org/protocol/pubsub#errors"));
            sendErrorPacket(iq, PacketError.Condition.bad_request, pubsubError);
            return;
        }
        // Check that no item was included if node doesn't persist items and doesn't
        // includes payload
        if (itemElements.hasNext() && !leafNode.isItemRequired()) {
            Element pubsubError = DocumentHelper.createElement(QName.get(
                    "item-forbidden", "http://jabber.org/protocol/pubsub#errors"));
            sendErrorPacket(iq, PacketError.Condition.bad_request, pubsubError);
            return;
        }
        List<Element> items = new ArrayList<>();
        List<Element> entries;
        Element payload;
        while (itemElements.hasNext()) {
            Element item = itemElements.next();
            entries = item.elements();
            payload = entries.isEmpty() ? null : entries.get(0);
            // Check that a payload was included if node is configured to include payload
            // in notifications
            if (payload == null && leafNode.isPayloadDelivered()) {
                Element pubsubError = DocumentHelper.createElement(QName.get(
                        "payload-required", "http://jabber.org/protocol/pubsub#errors"));
                sendErrorPacket(iq, PacketError.Condition.bad_request, pubsubError);
                return;
            }
            // Check that the payload (if any) contains only one child element
            if (entries.size() > 1) {
                Element pubsubError = DocumentHelper.createElement(QName.get(
                        "invalid-payload", "http://jabber.org/protocol/pubsub#errors"));
                sendErrorPacket(iq, PacketError.Condition.bad_request, pubsubError);
                return;
            }
            items.add(item);
        }

        // Return success operation
        router.route(IQ.createResultIQ(iq));
        // Publish item and send event notifications to subscribers
        leafNode.publishItems(from, items);
    }
Handles Message packets sent to the pubsub service. Messages may be of type error
when an event notification was sent to a susbcriber whose address is no longer available.<p>

Answers to authorization requests sent to node owners to approve pending subscriptions
will also be processed by this method.

@param service the PubSub service this action is to be performed for.
@param message the Message packet sent to the pubsub service.
xmppserver/src/main/java/org/jivesoftware/openfire/pubsub/PubSubEngine.java