void sendPublishedNotifications(Message notification, Element event, LeafNode leafNode, List<PublishedItem> publishedItems)
    {
        if (!publishedItems.isEmpty()) {
            Map<List<NodeSubscription>, List<PublishedItem>> itemsBySubs = getItemsBySubscriptions(leafNode, publishedItems);
            Log.trace("Sending publication notification for {} published item(s) to {} subscription(s) in {} batch(es).", publishedItems.size(), itemsBySubs.keySet().stream().flatMap(Collection::stream).collect(Collectors.toSet()).size(), itemsBySubs.size());

            // Send one notification for published items that affect the same subscriptions
            for (final Map.Entry<List<NodeSubscription>, List<PublishedItem>> entry : itemsBySubs.entrySet()) {
                final List<NodeSubscription> nodeSubscriptions = entry.getKey();
                final List<PublishedItem> groupedItems = entry.getValue();
                Log.trace("Preparing publication notification batch for {} item(s) to {} subscription(s).", groupedItems.size(), nodeSubscriptions.size());

                // Add items information
                Element items = event.addElement("items");
                items.addAttribute("node", getNode().getUniqueIdentifier().getNodeId());
                for (PublishedItem publishedItem : groupedItems) {
                    // FIXME: This was added for compatibility with PEP supporting clients.
                    //        Alternate solution needed when XEP-0163 version > 1.0 is released.
                    //
                    // If the node ID looks like a JID, replace it with the published item's node ID.
                    if (getNode().getUniqueIdentifier().getNodeId().contains("@")) {
                        items.addAttribute("node", publishedItem.getNodeID());                        
                    }

                    // Add item information to the event notification
                    Element item = items.addElement("item");
                    if (leafNode.isItemRequired()) {
                        item.addAttribute("id", publishedItem.getID());
                    }
                    if (leafNode.isPayloadDelivered()) {
                        item.add(publishedItem.getPayload().createCopy());
                    }
                    // Add leaf leafNode information if affiliated leafNode and node
                    // where the item was published are different
                    if (leafNode != getNode()) {
                        item.addAttribute("node", leafNode.getUniqueIdentifier().getNodeId());
                    }
                }
                // Send the event notification
                sendEventNotification(notification, nodeSubscriptions);
                // Remove the added items information
                event.remove(items);
            }
        }
        else {
            // Filter affiliate subscriptions and only use approved and configured ones
            List<NodeSubscription> affectedSubscriptions = new ArrayList<>();
            for (NodeSubscription subscription : getSubscriptions()) {
                if (subscription.canSendPublicationEvent(leafNode, null)) {
                    affectedSubscriptions.add(subscription);
                }
            }
            Log.trace("Sending publication notification to {} subscription(s)", affectedSubscriptions.size());

            // Add item information to the event notification
            Element items = event.addElement("items");
            items.addAttribute("node", leafNode.getUniqueIdentifier().getNodeId());
            // Send the event notification
            sendEventNotification(notification, affectedSubscriptions);
            // Remove the added items information
            event.remove(items);
        }

        // TODO this horribly duplicates part of the functionality above. Code-clutter should be reduced.
        // XEP-0136 specifies that all connected resources of the owner of the PEP service should also get a notification.
        if (leafNode.getService() instanceof PEPService) {
            final PEPService service = (PEPService) leafNode.getService();
            final Collection<ClientSession> sessions = SessionManager.getInstance().getSessions(service.getAddress().getNode());
            Log.trace("Sending publication notification to {} session(s) of PEP node owner.", sessions.size());
            for( final ClientSession session : sessions ) {
                // Add item information to the event notification
                Element items = event.addElement("items");
                items.addAttribute("node", leafNode.getUniqueIdentifier().getNodeId());

                for (PublishedItem publishedItem : publishedItems) {
                    // FIXME: This was added for compatibility with PEP supporting clients.
                    //        Alternate solution needed when XEP-0163 version > 1.0 is released.
                    //
                    // If the node ID looks like a JID, replace it with the published item's node ID.
                    if (getNode().getUniqueIdentifier().getNodeId().contains("@")) {
                        items.addAttribute("node", publishedItem.getNodeID());
                    }

                    // Add item information to the event notification
                    Element item = items.addElement("item");
                    if (leafNode.isItemRequired()) {
                        item.addAttribute("id", publishedItem.getID());
                    }
                    if (leafNode.isPayloadDelivered()) {
                        item.add(publishedItem.getPayload().createCopy());
                    }
                    // Add leaf leafNode information if affiliated leafNode and node
                    // where the item was published are different
                    if (leafNode != getNode()) {
                        item.addAttribute("node", leafNode.getUniqueIdentifier().getNodeId());
                    }
                }

                // Send the event notification
                service.sendNotification(leafNode, notification, session.getAddress());
                // Remove the added items information
                event.remove(items);
            }
        }
    }
Sends an event notification for the published items to the affiliate. The event
notification may contain zero, one or many published items based on the items
included in the original publication. If the affiliate has many subscriptions and
many items were published then the affiliate will get a notification for each set
of items that affected the same subscriptions.

If the affiliate is an owner of the node, and the node is in a PEP service, then
all connected resources of the affiliated user will be sent an event notification.

@param notification the message to sent to the subscribers. The message will be completed
       with the items to include in each notification.
@param event the event Element included in the notification message. Passed as an
       optimization to avoid future look ups.
@param leafNode the leaf node where the items where published.
@param publishedItems the list of items that were published. Could be an empty list.
xmppserver/src/main/java/org/jivesoftware/openfire/pubsub/NodeAffiliate.java