public Board(BoardBuilder boardBuilder) {
    width = boardBuilder.getWidth();
    height = boardBuilder.getHeight();

    cells = new Cell[getCellCount()];
    cellsListView = Collections.unmodifiableList(Arrays.asList(cells));

    int numberSum = 0;
    final int maxNum = 0;
    for (int x = 0; x < width; ++x) {
      for (int y = 0; y < height; ++y) {
        final int number = boardBuilder.getNumber(x, y);
        if (number == 0) {
          cells[coordsToIndex(x, y)] = new SimpleCell(this, x, y);
        }
        else {
          cells[coordsToIndex(x, y)] = new FixedCell(this, x, y, number);
        }
        numberSum += number;
      }
    }

    if (numberSum <= 0) {
      throw new IllegalArgumentException("no white fixed cells");
    }
    else if (numberSum > getCellCount()) {
      throw new IllegalArgumentException("solution impossible, to many expected white cells");
    }
    solutionWhiteCount = numberSum;
    maxNumber = maxNum;

    neighborSets = cellsListView.stream().map(cell -> {
      final int x = cell.getX();
      final int y = cell.getY();
      final Builder<Cell> builder = ImmutableSet.<Cell>builder();
      if (isLegalCoord(x + 1, y)) {
        builder.add(getCell(x + 1, y));
      }
      if (isLegalCoord(x - 1, y)) {
        builder.add(getCell(x - 1, y));
      }
      if (isLegalCoord(x, y + 1)) {
        builder.add(getCell(x, y + 1));
      }
      if (isLegalCoord(x, y - 1)) {
        builder.add(getCell(x, y - 1));
      }
      return builder.build();
    }).collect(Collectors.toList());
  }