class DynamicLoadBalanceFactorProvider implements LoadBalanceFactorProvider, DynamicLoadBalanceFactorProviderMBean {

    @Override
    public synchronized int getLoadBalanceFactor(Engine engine) {
        boolean nodeUnavailable = false;
        int totalWeight = 0;
        double totalWeightedLoad = 0;

        for (Map.Entry<LoadMetric, List<Double>> entry : this.loadHistory.entrySet()) {
            LoadMetric metric = entry.getKey();

            int weight = metric.getWeight();

            if (weight > 0) {
                List<Double> metricLoadHistory = entry.getValue();

                try {
                    // Normalize load with respect to capacity
                    this.recordLoad(metricLoadHistory, metric.getLoad(engine) / metric.getCapacity());

                    totalWeight += weight;
                    totalWeightedLoad += this.average(metricLoadHistory) * weight;
                } catch (NodeUnavailableException e) {
                    // The metric requested to put the node into error state
                    // Call LoadMetric#getLoad on remaining metrics so that historical values are populated
                    nodeUnavailable = true;
                } catch (Exception e) {
                    this.log.error(e.getLocalizedMessage(), e);
                }
            }
        }

        if (nodeUnavailable) {
            return -1;
        }

        // Convert load ratio to integer percentage
        int load = (int) Math.round(100 * totalWeightedLoad / totalWeight);

        // apply ceiling & floor and invert to express as "load factor"
        // result should be a value between 1-100
        return 100 - Math.max(0, Math.min(load, 99));
    }

    public  DynamicLoadBalanceFactorProvider(Set<LoadMetric> metrics);
    public  DynamicLoadBalanceFactorProvider(Set<LoadMetric> metrics, int initialLoad);

}