@SuppressWarnings("unchecked")
    public List<String> onTabComplete(CommandSender sender, Command command, String label, String[] args) {
        StringBuilder commandName = new StringBuilder();
        List<String> arguments = new ArrayList<>();
        arguments.add(label);
        arguments.addAll(Arrays.asList(args));
        if (args.length > 0) {
            arguments.remove(args.length);
        }

        String lastCommand = "";
        int removeCount = 1;
        for (int i = 0; i < arguments.size(); i++) {
            String arg = arguments.get(i);
            if (commandName.length() != 0) {
                commandName.append(".");
            }
            commandName.append(arg);
            if (completers.containsKey(commandName.toString())) {
                lastCommand = commandName.toString();
                removeCount = i + 1;
            }
        }
        if (!lastCommand.isEmpty()) {
            for (int i = 0; i < removeCount; i++) {
                arguments.remove(0);
            }
            Entry<Method, Object> entry = completers.get(lastCommand);
            try {
                return (List<String>) entry.getKey().invoke(entry.getValue(), new CommandArgs(sender, command, arguments));
            } catch (IllegalArgumentException | IllegalAccessException | InvocationTargetException e) {
                e.printStackTrace();
            }
        }
        return EMPTY_LIST;
    }