@GuardedBy("mutex")
    private void deleteOccupantFromNode(@Nullable final Occupant oldOccupant, @Nonnull final NodeID nodeID)
    {
        if (oldOccupant != null) {
            final Map<JID, Set<Occupant>> occupantsOnNode = localOccupantsByNode.get(nodeID);
            if (occupantsOnNode != null) {
                final Set<Occupant> occupantsForJID = occupantsOnNode.get(oldOccupant.getRealJID());
                if (occupantsForJID != null) {
                    occupantsForJID.remove(oldOccupant);
                    // Clean up, don't leave behind empty entries.
                    if (occupantsForJID.isEmpty()) {
                        occupantsOnNode.remove(oldOccupant.getRealJID());
                        if (occupantsOnNode.isEmpty()) {
                            localOccupantsByNode.remove(nodeID);
                        }
                    }
                }
            }
            nodeByLocalOccupant.remove(oldOccupant);

            // When an occupant is being pinged, but removed from the node, cancel the ping.
            final TimerTask pendingPingTask = oldOccupant.getPendingPingTask();
            if (pendingPingTask != null) {
                Log.debug("Remove pending ping task for {} that is being deleted.", oldOccupant);
                TaskEngine.getInstance().cancelScheduledTask(pendingPingTask);
                oldOccupant.setPendingPingTask(null);
            }
        }
    }
Registers disappearance of an existing occupant on a specific node.

Calls to this method must be mode only under guard of a write lock that been obtained from {@link #mutex}.

@param oldOccupant An occupant that is to be removed from the registration of the referred node.
@param nodeID The ID of the node that the occupant need to be deregistered from.
xmppserver/src/main/java/org/jivesoftware/openfire/muc/spi/OccupantManager.java