class ModShardLocator extends AbstractCommonShardLocator<CTX> {

    @Override
    public Set<String> locateForBetween(ConditionContext ctx) {
        long lowerValue = (long) getNumberValue(ctx.getValue());
        long upperValue = (long) getNumberValue(ctx.getSecondValue());
        
        Set<String> shards = new HashSet<>();
        // Illegal case for between
        if(lowerValue > upperValue) {
            return shards;
        }
        
        // Cross all shards case
        if(upperValue - lowerValue >= (mod -1)) {
            return ctx.getAllShards();
        }
        
        //For same value
        if(upperValue == lowerValue) {
            int shard = Integer.parseInt(mod(mod, ctx.getValue()));
            shards.add(String.valueOf(shard));
            return applySuffix(shards);
        }

        int lowerShard = Integer.parseInt(mod(mod, ctx.getValue()));
        int upperShard = Integer.parseInt(mod(mod, ctx.getSecondValue()));
        
        if(lowerShard < upperShard) {
            while(lowerShard <= upperShard) {
                shards.add(String.valueOf(lowerShard++));
            }
        } else {
            while(lowerShard < mod) {
                shards.add(String.valueOf(lowerShard++));
            }
            
            int shard = 0;
            while(shard <= upperShard) {
                shards.add(String.valueOf(shard++));
            }
        }

        return applySuffix(shards);
    }

    public  ModShardLocator(Integer mod);
    public  ModShardLocator(Integer mod, String zeroPaddingFormat);

}