@Override
    public void leftCluster( final byte[] nodeID )
    {
        // Another node left the cluster.
        //
        // If the cluster node leaves in an orderly fashion, it might have broadcasted
        // the necessary events itself. This cannot be depended on, as the cluster node
        // might have disconnected unexpectedly (as a result of a crash or network issue).
        //
        // Determine what components were available only on that node, and remove them.
        // For these, 'component unavailable' events need to be sent out. If the cluster
        // node exited cleanly, we won't find any entries to work on. If it did not
        // exit cleanly, all remaining cluster nodes will be in a race to clean up the
        // same data. The implementation below accounts for that, by only having the
        // senior cluster node to perform the cleanup.
        if (ClusterManager.isSeniorClusterMember())
        {
            final Map<Boolean, Map<JID, HashSet<NodeID>>> modified = CacheUtil.removeValueFromMultiValuedCache(componentCache, NodeID.getInstance(nodeID));

            modified.get(false).keySet().forEach(removedDomain -> {
                Log.debug("Cluster node {} just left the cluster, and was the only node on which component '{}' was living. Invoking the 'component unregistered' event on all remaining cluster nodes.",
                          NodeID.getInstance(nodeID),
                          removedDomain);
                notifyComponentUnregistered(removedDomain);

                // As we have removed the disappeared components from the clustered cache, other nodes
                // can no longer determine what components became unavailable. We'll need to broadcast
                // the unavailable event over the entire cluster!
                CacheFactory.doClusterTask(new NotifyComponentUnregistered(removedDomain));

                // Also clean up the cache of cluster-wide service discovery results.
                componentInfo.remove(removedDomain.toString());
            });
        }
    }
Processes packets that were sent to this service. Currently only packets that were sent from
registered components are being processed. In the future, we may also process packet of
trusted clients. Trusted clients may be able to execute ad-hoc commands such as adding or
removing components.

@param packet the packet to process.
xmppserver/src/main/java/org/jivesoftware/openfire/component/InternalComponentManager.java