public GameOfLife step() {
    Set<Coordinates> newLiveCells = new HashSet<Coordinates>();
    Set<Coordinates> cellsNextToALiveCell = new HashSet<Coordinates>();

    for (Coordinates coordinates : liveCells) {
      int numberOfNeighbors = countLiveNeighbors(coordinates);

      if ((numberOfNeighbors == 2) && isCellAlive(coordinates.x, coordinates.y))
        turnCellAlive(newLiveCells, coordinates);

      cellsNextToALiveCell.add(new Coordinates(coordinates.x + 1, coordinates.y + 1));
      cellsNextToALiveCell.add(new Coordinates(coordinates.x + 1, coordinates.y + 0));
      cellsNextToALiveCell.add(new Coordinates(coordinates.x + 1, coordinates.y - 1));
      cellsNextToALiveCell.add(new Coordinates(coordinates.x - 1, coordinates.y + 1));
      cellsNextToALiveCell.add(new Coordinates(coordinates.x - 1, coordinates.y + 0));
      cellsNextToALiveCell.add(new Coordinates(coordinates.x - 1, coordinates.y - 1));
      cellsNextToALiveCell.add(new Coordinates(coordinates.x + 0, coordinates.y + 1));
      cellsNextToALiveCell.add(new Coordinates(coordinates.x + 0, coordinates.y - 1));
    }
    for (Coordinates coordinates : cellsNextToALiveCell) {
      int numberOfNeighbors = countLiveNeighbors(coordinates);

      if (numberOfNeighbors == 3) turnCellAlive(newLiveCells, coordinates);
    }

    replaceWithContentOf(liveCells, newLiveCells);

    return this;
  }
 public void setInitialLiveCells(long[][] initialLiveCells) {
   replaceWithContentOf(this.liveCells, new HashSet<Coordinates>());
   for (int i = 0; i < initialLiveCells.length; i++) {
     long[] coordinates = initialLiveCells[i];
     turnCellAlive(coordinates[0], coordinates[1]);
   }
 }
 private void turnCellAlive(long x, long y) {
   turnCellAlive(liveCells, new Coordinates(x, y));
 }