public DataMutateResult.WithMergedNode setNode(DataType dataType, Node node, TemporaryNodeMergeStrategy mergeStrategy) {
        if (node.getExpiry() != null && mergeStrategy != TemporaryNodeMergeStrategy.NONE) {
            Node otherMatch = getData(dataType).nodesInContext(node.getContexts()).stream()
                    .filter(NodeEqualityPredicate.IGNORE_EXPIRY_TIME_AND_VALUE.equalTo(node))
                    .findFirst().orElse(null);

            if (otherMatch != null && otherMatch.getExpiry() != null) {
                NodeMap data = getData(dataType);

                Node newNode = null;
                switch (mergeStrategy) {
                    case ADD_NEW_DURATION_TO_EXISTING: {
                        // Create a new Node with the same properties, but add the expiry dates together
                        Instant newExpiry = otherMatch.getExpiry().plus(Duration.between(Instant.now(), node.getExpiry()));
                        newNode = node.toBuilder().expiry(newExpiry).build();
                        break;
                    }
                    case REPLACE_EXISTING_IF_DURATION_LONGER: {
                        // Only replace if the new expiry time is greater than the old one.
                        if (node.getExpiry().compareTo(otherMatch.getExpiry()) > 0) {
                            newNode = node;
                        }
                        break;
                    }
                }

                if (newNode != null) {
                    // Remove the old Node & add the new one.
                    Difference<Node> changes = data.removeThenAdd(otherMatch, newNode);
                    invalidateCache();
                    this.plugin.getEventDispatcher().dispatchNodeChanges(this, dataType, changes);

                    return new MergedNodeResult(DataMutateResult.SUCCESS, newNode);
                }
            }
        }

        // Fallback to the normal handling.
        return new MergedNodeResult(setNode(dataType, node, true), node);
    }
Removes temporary permissions that have expired

@return true if permissions had expired and were removed
common/src/main/java/me/lucko/luckperms/common/model/PermissionHolder.java