private List<List<Location>> buildGridOfLocations() {
    List<Location> northMostFirst = liveCellLocations.stream().sorted().collect(toList());
    Location northMost = northMostFirst.get(0);
    Location southMost = northMostFirst.get(northMostFirst.size() - 1);

    List<Location> westMostFirst =
        liveCellLocations.stream().sorted(byWestMostFirst).collect(toList());
    Location westMost = westMostFirst.get(0);
    Location eastMost = westMostFirst.get(westMostFirst.size() - 1);

    Location topLeft = getTopLeft(northMost, westMost);
    Location topRight = getTopRight(northMost, eastMost);
    Location bottomLeft = getBottomLeft(northMost, southMost);

    List<Location> topRow = topRowWith(topLeft, topRight);

    return gridWith(topRow, topLeft, bottomLeft);
  }
 private List<Location> locationsOfNewbornCells() {
   return liveCellLocations
       .stream()
       .flatMap(
           l1 ->
               liveCellLocations
                   .stream()
                   .flatMap(
                       l2 ->
                           liveCellLocations
                               .stream()
                               .flatMap(
                                   l3 ->
                                       areInNeighbourhoodOfSomeCell(l1, l2, l3)
                                           ? emptyLocationsWithLiveNeighboursInAllAndOnlyLocations(
                                               l1, l2, l3)
                                           : Stream.empty())))
       .collect(toList());
 }
 private List<Location> locationsOfSurvivingCells() {
   return liveCellLocations.stream().filter(aCellWillSurviveAt).collect(toList());
 }