@Override
    public void sendNotification(Node node, Message orig, JID recipientJID) {
        Log.trace( "Recipient '{}' is an intended recipient of service '{}' sending a notification for node '{}': {}", recipientJID, this.getServiceID(), node.getUniqueIdentifier().getNodeId(), orig.toXML() );

        final boolean recipientIsOwner = serviceOwner.asBareJID().equals(recipientJID.asBareJID());

        final Set<JID> deliveryAddresses = new HashSet<>();

        if (XMPPServer.getInstance().isLocal(recipientJID)) {
            // When the recipient is a local entity, then we can be sure that we have appropriate presence information
            // to determine all desirable delivery addresses.
            if (recipientJID.getResource() == null) {
                // If the recipient subscribed with a bare JID collect all of their full JIDs based on active sessions
                // and send the notification to each below.
                Log.trace("Recipient '{}' is a local user using a bare JID. Notifications will be sent to all its active sessions.", recipientJID);
                for (final ClientSession clientSession : SessionManager.getInstance().getSessions(recipientJID.getNode())) {
                    if (!clientSession.isClosed()) {
                        deliveryAddresses.add(clientSession.getAddress());
                    }
                }
            } else {
                // If the recipient subscribed with a full JID, only send a notification if their session is online.
                final ClientSession session = SessionManager.getInstance().getSession(recipientJID);
                final boolean doDeliver = session != null && !session.isClosed();
                Log.trace("Recipient '{}' is a local user using a full JID. Notifications will be sent only if there's an active session (which there {})", recipientJID, doDeliver ? "is" : "is not");
                if (doDeliver) {
                    deliveryAddresses.add(recipientJID);
                }
            }
        } else {
            // When the recipient is not a local entity, this service does not have appropriate presence information
            // and can only use the provided recipient address.
            Log.trace("Recipient '{}' is a remote user. Notifications will be sent to to the address as-is.", recipientJID);
            deliveryAddresses.add(recipientJID);
        }

        if (deliveryAddresses.isEmpty()) {
            Log.trace("Recipient '{}': Done processing, recipient has no delivery addresses", recipientJID);
            return;
        }

        if ( Log.isTraceEnabled() ) {
            Log.trace("Recipient '{}' has these delivery address(es): {}", recipientJID, deliveryAddresses.stream().map(JID::toString).collect(Collectors.joining(", ")));
        }

        final Message message = orig.createCopy(); // Defensive copy: Do not let data from one iteration leak into the next.
        message.setTo(recipientJID);
        message.setFrom(getAddress());
        message.setID(StringUtils.randomString(8));

        for (final JID deliveryAddress : deliveryAddresses) {
            // Include an Extended Stanza Addressing "replyto" extension specifying the publishing
            // resource. However, only include the extension if the receiver has a presence subscription
            // to the service owner.
            try {
                JID publisher = null;

                // Get the ID of the node that had an item published to or retracted from.
                Element itemsElement = message.getElement().element("event").element("items");
                String nodeID = itemsElement.attributeValue("node");

                // Get the ID of the item that was published or retracted.
                String itemID = null;
                Element itemElement = itemsElement.element("item");
                if (itemElement == null) {
                    Element retractElement = itemsElement.element("retract");
                    if (retractElement != null) {
                        itemID = retractElement.attributeValue("id");
                    }
                }
                else {
                    itemID = itemElement.attributeValue("id");
                }

                // Check if the recipientFullJID is interested in notifications for this node.
                // If the recipient has not yet requested any notification filtering, continue and send
                // the notification.
                EntityCapabilities entityCaps = entityCapsManager.getEntityCapabilities(deliveryAddress);
                if (entityCaps != null) {
                    if (!entityCaps.containsFeature(nodeID + "+notify")) {
                        Log.trace( "Recipient '{}': Not sending notification to address '{}' that does not have CAPS {}+notify", recipientJID, deliveryAddress, nodeID );
                        continue;
                    }
                }

                // Get the full JID of the item publisher from the node that was published to.
                // This full JID will be used as the "replyto" address in the addressing extension.
                if (node.isCollectionNode()) {
                    for (Node leafNode : node.getNodes()) {
                        if (leafNode.getUniqueIdentifier().getNodeId().equals(nodeID)) {
                            publisher = leafNode.getPublishedItem(itemID).getPublisher();

                            // Ensure the recipientJID has access to receive notifications for items published to the leaf node.
                            AccessModel accessModel = leafNode.getAccessModel();
                            if (!accessModel.canAccessItems(leafNode, deliveryAddress, publisher)) {
                                Log.trace( "Recipient '{}': Not sending notification to address '{}': This JID is not allowed to access items on node {}", recipientJID, deliveryAddress, nodeID );
                                continue;
                            }

                            break;
                        }
                    }
                }
                else {
                    publisher = node.getPublishedItem(itemID).getPublisher();
                }

                // Ensure the recipient is subscribed to the service owner's (publisher's) presence.
                if (publisher == null) {
                    Log.warn( "Item {} on node {} has no known publisher.", itemID, node.getUniqueIdentifier());
                } else if (recipientIsOwner || canProbePresence(publisher, deliveryAddress)) {
                    Element addresses = DocumentHelper.createElement(QName.get("addresses", "http://jabber.org/protocol/address"));
                    Element address = addresses.addElement("address");
                    address.addAttribute("type", "replyto");
                    address.addAttribute("jid", publisher.toString());

                    Message extendedMessage = message.createCopy();
                    extendedMessage.addExtension(new PacketExtension(addresses));

                    extendedMessage.setTo(deliveryAddress);
                    Log.trace( "Recipient '{}': Sending notification to recipient address: '{}'", recipientJID, extendedMessage.getTo() );
                    router.route(extendedMessage);
                } else {
                    Log.trace( "Recipient '{}': Not sending notification to address '{}': This address is not allowed to probe presence of publisher '{}'", recipientJID, deliveryAddress, publisher );
                }
            }
            catch (IndexOutOfBoundsException e) {
                // Do not add addressing extension to message.
                Log.trace( "IndexOutOfBoundException occurred while trying to send PEP notification.", e );
            }
            catch (UserNotFoundException e) {
                // Do not add addressing extension to message.
                Log.trace( "Recipient '{}': Service '{}' is sending a notification for node '{}' to address: {}", recipientJID, this.getServiceID(), node.getUniqueIdentifier().getNodeId(), message.getTo(), e );
                router.route(message);
            }
            catch (NullPointerException e) {
                try {
                    if (recipientIsOwner || canProbePresence(getAddress(), deliveryAddress)) {
                        message.setTo(deliveryAddress);
                    }
                }
                catch (UserNotFoundException e1) {
                    // Do nothing
                }
                Log.trace( "Recipient '{}': Service '{}' is sending a notification on node '{}' to address: {}", recipientJID, this.getServiceID(), node.getUniqueIdentifier().getNodeId(), message.getTo(), e );
                router.route(message);
            }
        }
        Log.trace( "Recipient '{}': Done processing notification for service '{}' on node '{}'", recipientJID, this.getServiceID(), node.getUniqueIdentifier().getNodeId() );
    }
Returns the permission policy for creating nodes. A true value means that not anyone can create a node,
only the service admin.

Note that PEP services will always return 'true'.

@return true
xmppserver/src/main/java/org/jivesoftware/openfire/pep/PEPService.java