class Balance implements Command {

    @Override
    public void run() throws Exception {
        boolean balancerRunning = false;

        try {
            balancerRunning = turnBalancerOff();

            BalanceRule rule = BalanceRule.valueOf(ruleParam.toUpperCase());
            if (rule.equals(BalanceRule.DEFAULT)) {
                if (!args.isForceProceed()) {
                    if (!Util.askProceed()) {
                        return;
                    }
                }
                admin.balancer();
                System.out.println("Run hbase default balancer. This is an asynchronous operation.");
            } else {
                List<RegionPlan> regionPlanList = rule.makePlan(admin, tableNameSet, args);
                BalanceFactor.printFactor(BalanceFactor.parseArg(args));

                boolean asynchronous = args.has(Args.OPTION_MOVE_ASYNC);
                if (preview(regionPlanList, asynchronous))
                    balance(args, regionPlanList, Phase.BALANCE, asynchronous);
            }
        } finally {
            if (balancerRunning) {
                // turn balancer on if needed
                admin.setBalancerRunning(true, true);
                System.out.println("Turn balancer on.");
            }
        }
    }

    public  Balance(HBaseAdmin admin, Args args);

}