public DemotionResult demote(User user, ContextSet context, Predicate<String> previousGroupPermissionChecker, @Nullable Sender sender, boolean removeFromFirst) {
        if (getSize() <= 1) {
            throw new IllegalStateException("Track contains one or fewer groups, unable to demote");
        }

        // find all groups that are inherited by the user in the exact contexts given and applicable to this track
        List<InheritanceNode> nodes = user.normalData().inheritanceNodesInContext(context).stream()
                .filter(Node::getValue)
                .filter(node -> containsGroup(node.getGroupName()))
                .distinct()
                .collect(Collectors.toList());

        if (nodes.isEmpty()) {
            return DemotionResults.notOnTrack();
        }

        if (nodes.size() != 1) {
            return DemotionResults.ambiguousCall();
        }

        InheritanceNode oldNode = nodes.get(0);
        String old = oldNode.getGroupName();
        String previous = getPrevious(old);

        if (!previousGroupPermissionChecker.test(oldNode.getGroupName())) {
            return DemotionResults.undefinedFailure();
        }

        if (previous == null) {
            if (!removeFromFirst) {
                return DemotionResults.removedFromFirst(null);
            }

            user.unsetNode(DataType.NORMAL, oldNode);
            this.plugin.getEventDispatcher().dispatchUserDemote(user, this, old, null, sender);
            return DemotionResults.removedFromFirst(old);
        }

        Group previousGroup = this.plugin.getGroupManager().getIfLoaded(previous);
        if (previousGroup == null) {
            return DemotionResults.malformedTrack(previous);
        }

        user.unsetNode(DataType.NORMAL, oldNode);
        user.setNode(DataType.NORMAL, oldNode.toBuilder().group(previousGroup.getName()).build(), true);

        if (context.isEmpty() && user.getPrimaryGroup().getStoredValue().orElse(GroupManager.DEFAULT_GROUP_NAME).equalsIgnoreCase(old)) {
            user.getPrimaryGroup().setStoredValue(previousGroup.getName());
        }

        this.plugin.getEventDispatcher().dispatchUserDemote(user, this, old, previousGroup.getName(), sender);
        return DemotionResults.success(old, previousGroup.getName());
    }
Clear all of the groups within this track
common/src/main/java/me/lucko/luckperms/common/model/Track.java