code: public static <R> ImmutableGrid<R> copyOf(Grid<R> grid) {
          if (grid == null) {
              throw new IllegalArgumentException("Grid must not be null");
          }
          if (grid instanceof ImmutableGrid) {
              return (ImmutableGrid<R>) grid;
          }
          validateCounts(grid.rowCount(), grid.columnCount());
          if (grid.size() == 0) {
              return new EmptyGrid<R>(grid.rowCount(), grid.columnCount());
          }
          if (grid.size() == 1) {
              Cell<R> cell = grid.cells().iterator().next();
              return new SingletonGrid<R>(grid.rowCount(), grid.columnCount(), cell);
          }
          if (grid.size() >= (grid.rowCount() * grid.columnCount() / 2)) {
              return DenseImmutableGrid.create(grid);
          }
          return new SparseImmutableGrid<R>(grid);
      }
docs: Obtains an immutable grid by copying another grid.
  <p>
  If you need to change the row-column count, use {@link #copyOf(int, int, Iterable)}
  passing in the set of cells from the grid.
  
  @param <R> the type of the value
  @param grid  the grid to copy, not null
  @return the immutable grid, not null
  @throws IndexOutOfBoundsException if either index is less than zero