/** Log the over utilized & under utilized nodes */
 private void logImbalancedNodes() {
   if (LOG.isInfoEnabled()) {
     int underUtilized = 0, overUtilized = 0;
     for (BalancerDatanode node : this.datanodes.values()) {
       if (isUnderUtilized(node)) underUtilized++;
       else if (isOverUtilized(node)) overUtilized++;
     }
     StringBuilder msg = new StringBuilder();
     msg.append(overUtilized);
     msg.append(" over utilized nodes:");
     for (BalancerDatanode node : this.datanodes.values()) {
       if (isOverUtilized(node)) {
         msg.append(" ");
         msg.append(node.getName());
       }
     }
     LOG.info(msg);
     msg = new StringBuilder();
     msg.append(underUtilized);
     msg.append(" under utilized nodes: ");
     for (BalancerDatanode node : this.datanodes.values()) {
       if (isUnderUtilized(node)) {
         msg.append(" ");
         msg.append(node.getName());
       }
     }
     LOG.info(msg);
   }
 }
 /** Log node utilization after the plan execution */
 private void logPlanOutcome() {
   if (LOG.isInfoEnabled()) {
     LOG.info(
         "Predicted plan outcome: bytesLeftToMove: "
             + bytesLeftToMove
             + ", bytesToMove: "
             + bytesToMove);
     for (BalancerDatanode node : this.datanodes.values()) {
       LOG.info(node.getName() + " remaining: " + node.getCurrentRemaining());
     }
   }
 }