class Main {

    public static <T extends AbstractCommand> T parseCommandLine(String[] args) throws Exception {
        CommandContext cm = new CommandContext();
        JCommander jc = JCommander.newBuilder()
                .programName("blobit.sh")
                .addObject(cm)
                .addCommand("createbucket", new CommandCreateBucket(cm))
                .addCommand("deletebucket", new CommandDeleteBucket(cm))
                .addCommand("gcbucket", new CommandGcBucket(cm))
                .addCommand("listbuckets", new CommandListBuckets(cm))
                .addCommand("put", new CommandPut(cm))
                .addCommand("get", new CommandGet(cm))
                .addCommand("stat", new CommandStat(cm))
                .addCommand("ls", new CommandLs(cm))
                .addCommand("help", new CommandHelp(cm))
                .build();
        cm.jCommander = jc;
        try {
            jc.parse(args);
        } catch (ParameterException err) {
            System.out.println("Error: " + err.getMessage());
            return (T) new CommandHelp(cm);
        }
        if (jc.getParsedCommand() == null) {
            return (T) new CommandHelp(cm);
        }
        return (T) jc.getCommands().get(jc.getParsedCommand()).getObjects().get(0);
    }

}