/** {@inheritDoc} */
 public boolean solve(Grid grid) {
   Set<Set<Integer>> combinations = new HashSet<Set<Integer>>();
   combinations =
       Cell.generateCombinations(Cell.generateCandidateSet(1, 9), combinations, getSetSize());
   for (Set<Integer> combination : combinations) {
     if (solveHouses(grid.getHouses(), combination)) {
       return true;
     }
   }
   return false;
 }
 private boolean solveHouse(House house, Set<Integer> combination) {
   Set<Cell> selectedCells = new TreeSet<Cell>();
   for (Cell cell : house.getCells()) {
     if (cell.isSolved()) {
       // This house already contains a cell with
       // one of this quad's numbers.
       if (combination.contains(cell.getDigit())) {
         return false;
       }
       continue;
     }
     Collection<Integer> cellCandidates = cell.getCandidates();
     if (cellCandidates.size() > getSetSize()) {
       // Can't possibly be a subset
       continue;
     }
     Set<Integer> cellCandidatesCopy = new HashSet<Integer>(cellCandidates);
     cellCandidatesCopy.removeAll(combination);
     if (cellCandidatesCopy.size() == 0) {
       selectedCells.add(cell);
     }
   }
   if (selectedCells.size() == getSetSize()) {
     Set<Cell> houseCells = new HashSet<Cell>(house.getCells());
     houseCells.removeAll(selectedCells);
     boolean changed = false;
     for (Cell cell : houseCells) {
       if (cell.removeAll(combination)) {
         changed = true;
       }
     }
     return changed;
   }
   return false;
 }