private static Table<?> copy2(
     GridModel model,
     Range<Integer> r,
     Range<Integer> c,
     boolean rowHeader,
     boolean columnHeader) {
   if (model.getRowCount() == 0 || model.getColumnCount() == 0) {
     return new Table<>(0, 0);
   }
   int firstRow =
       r.hasLowerBound()
           ? (r.lowerBoundType().equals(BoundType.CLOSED)
               ? r.lowerEndpoint()
               : (r.lowerEndpoint() + 1))
           : 0;
   int lastRow =
       r.hasUpperBound()
           ? (r.upperBoundType().equals(BoundType.CLOSED)
               ? r.upperEndpoint()
               : (r.upperEndpoint() - 1))
           : (model.getRowCount() - 1);
   int firstColumn =
       c.hasLowerBound()
           ? (c.lowerBoundType().equals(BoundType.CLOSED)
               ? c.lowerEndpoint()
               : (c.lowerEndpoint() + 1))
           : 0;
   int lastColumn =
       c.hasUpperBound()
           ? (c.upperBoundType().equals(BoundType.CLOSED)
               ? c.upperEndpoint()
               : (c.upperEndpoint() - 1))
           : (model.getColumnCount() - 1);
   return copy(model, firstRow, firstColumn, lastRow, lastColumn, rowHeader, columnHeader);
 }
 // <editor-fold defaultstate="collapsed" desc="Implementation">
 private static Table<?> copy(
     GridModel model,
     int firstRow,
     int firstColumn,
     int lastRow,
     int lastColumn,
     boolean rowHeader,
     boolean columnHeader) {
   Table<Object> result =
       new Table<>(
           lastRow + 1 - firstRow + (columnHeader ? 1 : 0),
           lastColumn + 1 - firstColumn + (rowHeader ? 1 : 0));
   for (int i = firstRow; i < lastRow + 1; i++) {
     for (int j = firstColumn; j < lastColumn + 1; j++) {
       result.set(
           i - firstRow + (columnHeader ? 1 : 0),
           j - firstColumn + (rowHeader ? 1 : 0),
           model.getValueAt(i, j));
     }
   }
   if (rowHeader) {
     for (int i = firstRow; i < lastRow + 1; i++) {
       result.set(i - firstRow + (columnHeader ? 1 : 0), 0, model.getRowName(i));
     }
   }
   if (columnHeader) {
     for (int j = firstColumn; j < lastColumn + 1; j++) {
       result.set(0, j - firstColumn + (rowHeader ? 1 : 0), model.getColumnName(j));
     }
   }
   return result;
 }