public void publishItems(JID publisher, List<Element> itemElements) {
        Log.trace("Publisher '{}' is publishing {} item(s)", publisher, itemElements.size());
        List<PublishedItem> newPublishedItems = new ArrayList<>();
        if (isItemRequired()) {
            String itemID;
            Element payload;
            PublishedItem newItem;
            for (Element item : itemElements) {
                itemID = item.attributeValue("id");
                List<Element> entries = item.elements();
                payload = entries.isEmpty() ? null : entries.get(0);
                
                // Make sure that the published item has a unique ID if NOT assigned by publisher
                if (itemID == null) {
                    itemID = UUID.randomUUID().toString();
                }

                // Create a new published item
                newItem = new PublishedItem(this, publisher, itemID, new Date(CacheFactory.getClusterTime()));
                newItem.setPayload(payload);
                Log.trace("Created new PublishedItem instance with itemID {}", itemID);

                // Add the new item to the list of published items
                newPublishedItems.add(newItem);
                setLastPublishedItem(newItem);
                // Add the new published item to the queue of items to add to the database. The
                // queue is going to be processed by another thread
                if (isPersistPublishedItems()) {
                    Log.trace("Adding PublishedItem in persistence provider as node is configured to persist published items");
                    XMPPServer.getInstance().getPubSubModule().getPersistenceProvider().savePublishedItem(newItem);
                }
            }
        }

        // Build event notification packet to broadcast to subscribers
        Message message = new Message();
        Element event = message.addChildElement("event", "http://jabber.org/protocol/pubsub#event");
        // Broadcast event notification to subscribers and parent node subscribers
        Set<NodeAffiliate> affiliatesToNotify = getAffiliatesToNotify();
        Log.trace("Built event notification stanza to broadcast notification to {} affiliate(s)", affiliatesToNotify.size());

        // TODO Use another thread for this (if # of subscribers is > X)????
        for (NodeAffiliate affiliate : affiliatesToNotify) {
            affiliate.sendPublishedNotifications(message, event, this, newPublishedItems);
        }
    }
Publishes the list of items to the node. Event notifications will be sent to subscribers
for the new published event, as well as all connected resources of the owner, in case the node
is a node in a PEP service.<p>

The published event may or may not include an item. When the
node is not persistent and does not require payloads then an item is not going to be created
or included in the event notification.<p>

When an affiliate has many subscriptions to the node, the affiliate will get a
notification for each set of items that affected the same list of subscriptions.<p>

When an item is included in the published event then a new {@link PublishedItem} is
going to be created and added to the list of published item. Each published item will
have a unique ID in the node scope. The new published item will be added to the end
of the published list to keep the chronological order. When the max number of published
items is exceeded then the oldest published items will be removed.<p>

For performance reasons the newly added published items and the deleted items (if any)
are saved to the database using a background thread. Sending event notifications to
node subscribers may also use another thread to ensure good performance.<p>

@param publisher the full JID of the user that sent the new published event.
@param itemElements list of dom4j elements that contain info about the published items.
xmppserver/src/main/java/org/jivesoftware/openfire/pubsub/LeafNode.java