gt:             return Double.compare(evaluation, o.evaluation);
context: /**
   * 
   */
  package vroom.common.utilities;
  
  import java.util.Collections;
  import java.util.Iterator;
  import java.util.LinkedList;
  import java.util.List;
  import java.util.Map;
  import java.util.Map.Entry;
  
  import umontreal.iro.lecuyer.rng.RandomStream;
  
  /**
   * <code>RouletteWheel</code> is a simple implementation of a roulette wheel.
   * <p>
   * Creation date: May 12, 2011 - 2:03:33 PM
   * 
   * @author Victor Pillac, <a href="http://uniandes.edu.co">Universidad de Los Andes</a>-<a
   *         href="http://copa.uniandes.edu.co">Copa</a> <a href="http://www.emn.fr">Ecole des Mines de Nantes</a>-<a
   *         href="http://www.irccyn.ec-nantes.fr/irccyn/d/en/equipes/Slp">SLP</a>
   * @version 1.0
   */
  public class RouletteWheel<O> {
  
      private final List<WheelElement<O>> mWheel;
  
      private boolean                     mChanged;
  
      /**
       * Creates a new empty <code>RouletteWheel</code>
       */
      public RouletteWheel() {
          mWheel = new LinkedList<WheelElement<O>>();
      }
  
      /**
       * Creates a new <code>RouletteWheel</code>
       * 
       * @param evaluations
       *            a mapping between objects and their evaluation
       */
      public RouletteWheel(Map<O, Double> evaluations) {
          this();
          addAll(evaluations);
      }
  
      /**
       * Add an object to this wheel.
       * <p>
       * If this wheel already contains the object, then it will be added a second time.
       * </p>
       * 
       * @param object
       *            the object to be added
       * @param evaluation
       *            the evaluation of the added <code>object</code>
       */
      public void add(O object, double evaluation) {
          if (evaluation < 0)
              throw new IllegalArgumentException("Evaluation must be positive");
          mWheel.add(new WheelElement<O>(object, evaluation));
          mChanged = true;
      }
  
      /**
       * Add all the object from a map
       * 
       * @param evaluations
       *            a mapping between objects and their evaluation
       * @see #add(Object, double)
       */
      public void addAll(Map<O, Double> evaluations) {
          for (Entry<O, Double> e : evaluations.entrySet()) {
              add(e.getKey(), e.getValue());
          }
      }
  
      /**
       * Returns <code>true</code> if this wheel is empty
       * 
       * @return <code>true</code> if this wheel is empty
       */
      public boolean isEmpty() {
          return mWheel.isEmpty();
      }
  
      /**
       * Returns the number of objects in this wheel
       * 
       * @return the number of objects in this wheel
       */
      public int size() {
          return mWheel.size();
      }
  
      /**
       * Draw an object from this wheel
       * 
       * @param stream
       *            the {@link RandomStream} that will be used
       * @param removeAfterDraw
       *            <code>true</code> if the object should be removed after being drawn
       * @return the drawn object
       */
      public O drawObject(RandomStream stream, boolean removeAfterDraw) {
          if (size() == 0)
              return null;
          else if (size() == 1)
              return mWheel.get(0).object;
  
          updateWheel();
  
          double rnd = stream.nextDouble();
          Iterator<WheelElement<O>> it = mWheel.iterator();
          double acc = 0;
          WheelElement<O> e = null;
          while (it.hasNext() && acc < rnd) {
              e = it.next();
              acc += e.evaluation;
          }
          O object = e != null ? e.object : null;
  
          if (removeAfterDraw && object != null) {
              it.remove();
              mChanged = true;
          }
  
          return object;
      }
  
      /**
       * Calculate the probability of each wheel element and sort the wheel
       */
      private void updateWheel() {
          if (!mChanged)
              return;
  
          double cumulated = 0;
          for (WheelElement<O> e : mWheel) {
              cumulated += e.evaluation;
          }
          for (WheelElement<O> e : mWheel) {
              e.evaluation = e.evaluation / cumulated;
          }
          Collections.sort(mWheel);
  
          mChanged = false;
      }
  
      /**
       * Reset this selection wheel
       */
      public void clear() {
          mWheel.clear();
          mChanged = false;
      }
  
      @Override
      public String toString() {
          updateWheel();
  
          StringBuilder sb = new StringBuilder();
          sb.append("[");
          for (WheelElement<O> e : mWheel) {
              if (sb.length() > 1)
                  sb.append(",");
              sb.append(e.toString());
          }
          sb.append("]");
          return sb.toString();
      }
  
      /**
       * <code>WheelElement</code> representation of a wheel element for the random selection of an object
       * <p>
       * Creation date: 2 juil. 2010 - 21:00:56
       * 
       * @author Victor Pillac, <a href="http://uniandes.edu.co">Universidad de Los Andes</a>-<a
       *         href="http://copa.uniandes.edu.co">Copa</a> <a href="http://www.emn.fr">Ecole des Mines de Nantes</a>-<a
       *         href="http://www.irccyn.ec-nantes.fr/irccyn/d/en/equipes/Slp">SLP</a>
       * @version 1.0
       */
      class WheelElement<OO> implements Comparable<WheelElement<O>> {
          final O object;
          double  evaluation;
  
          /**
           * Creates a new <code>WheelElement</code>
           * 
           * @param object
           * @param evaluation
           */
          public WheelElement(O object, double probability) {
              this.object = object;
              this.evaluation = probability;
          }
  
          @Override
          public int compareTo(WheelElement<O> o) {
  