class CommandMapper {

    public FoundCommandResult mapPartsToCommand(CommandSender sender, List<String> parts) {
        if (Utils.isCollectionEmpty(parts)) {
            return new FoundCommandResult(null, parts, null, 0.0, MISSING_BASE_COMMAND);
        }

        CommandDescription base = getBaseCommand(parts.get(0));
        if (base == null) {
            return new FoundCommandResult(null, parts, null, 0.0, MISSING_BASE_COMMAND);
        }

        // Prefer labels: /register help goes to "Help command", not "Register command" with argument 'help'
        List<String> remainingParts = parts.subList(1, parts.size());
        CommandDescription childCommand = getSuitableChild(base, remainingParts);
        if (childCommand != null) {
            FoundResultStatus status = getPermissionAwareStatus(sender, childCommand);
            FoundCommandResult result = new FoundCommandResult(
                childCommand, parts.subList(0, 2), parts.subList(2, parts.size()), 0.0, status);
            return transformResultForHelp(result);
        } else if (hasSuitableArgumentCount(base, remainingParts.size())) {
            FoundResultStatus status = getPermissionAwareStatus(sender, base);
            return new FoundCommandResult(base, parts.subList(0, 1), parts.subList(1, parts.size()), 0.0, status);
        }

        return getCommandWithSmallestDifference(base, parts);
    }

    @Inject public  CommandMapper(CommandInitializer commandInitializer, PermissionsManager permissionsManager);

}