private Set<Cell> getValidNeghbors(Cell cell, FixedCell fixedCell,
      Map<Cell, Set<Cell>> validNeighborsCache) {
    Set<Cell> result = validNeighborsCache.get(cell);
    if (result == null) {
      final Board board = cell.getBoard();
      result = new CellSet(board.getNeighborsSet(cell));

      // remove those that are not valid
      final Iterator<Cell> iterator = result.iterator();
      while (iterator.hasNext()) {
        final Cell neighbor = iterator.next();
        if (neighbor.isBlack()
            || (neighbor.getFixedCell() != null && !neighbor.getFixedCell().equals(fixedCell))) {
          iterator.remove();
        }
        else {
          // check if any neighbor has a different fixed cell
          for (final Cell neighborNeighbor : board.getNeighborsSet(neighbor)) {
            if (neighborNeighbor.getFixedCell() != null
                && !neighborNeighbor.getFixedCell().equals(fixedCell)) {
              // neighboring different fixed cells are not possible
              iterator.remove();
              break;
            }
          }
        }
      }

      validNeighborsCache.put(cell, result);
    }
    return result;
  }