* @return The minimum number of moves.
   */
  static int LeastMoves(Jars jars) {
    // Check for empty jar
    if (jars.EmptyJar()) {
      return 0; // If our start set of jars has an empty jar, then exit.
    } else {
      int leastMoves = 0; // result
      LinkedList<Jars> moves = new LinkedList<Jars>(); // create queue
      HashSet<Integer> visited = new HashSet<Integer>();
      moves.offer(jars); // add initial jars state to queue

      while ((!moves.isEmpty()) && (leastMoves == 0)) {
        Jars current = new Jars(moves.poll()); // remove first in queue
        visited.add(current.hashCode());
        
        // Process the current set of Jars, first check for empty jar
        if (current.EmptyJar()) {
          leastMoves = current.count; // store result

        } else {

          // Visit all neighbouring vertices (or Jars derived from the
          // current Jar).
          // Since all Jars are stored in numerical order (a<b<c), we
          // can reduce the number of tests to perform, and this also
          // ensures that any subtraction doesn't result in a negative
          // bead count.
          // We maintain a hash set with all visited states to ensure
          // don't revisit them in future
          Jars moveBtoA = new Jars(current);
          moveBtoA.moveBeads(Jars.B, Jars.A);
          int hash = moveBtoA.hashCode();
          if (!visited.contains(hash)) {
            moves.offer(moveBtoA);
            visited.add(hash);
          }

          Jars moveCtoA = new Jars(current);
          moveCtoA.moveBeads(Jars.C, Jars.A);
          hash = moveCtoA.hashCode();
          if (!visited.contains(hash)) {
            moves.offer(moveCtoA); // add result to queue
            visited.add(hash);
          }

          current.moveBeads(Jars.C, Jars.B);
          hash = current.hashCode();
          if (!visited.contains(hash)) {
            moves.offer(current); // add result to queue
            visited.add(hash);
          }
        }
      }
      // We have found a empty jar set
      return leastMoves;
    }
  }