private void clearOldSelections() {
   for (MonthCellDescriptor selectedCell : selectedCells) {
     // De-select the currently-selected cell.
     selectedCell.setSelected(false);
   }
   selectedCells.clear();
   selectedCals.clear();
 }
 @Override
 public void handleClick(MonthCellDescriptor cell) {
   if (!cell.isSelected()) {
     clearAllOldSelections();
     mSelectedCellList.add(cell);
     cell.setSelected(true);
     Calendar newlySelectedCal = Calendar.getInstance(Locale.getDefault());
     newlySelectedCal.setTime(cell.getDate());
     mSelectedCalendarList.add(newlySelectedCal);
     flushView();
   }
 }
 private Date applyMultiSelect(Date date, Calendar selectedCal) {
   for (MonthCellDescriptor selectedCell : selectedCells) {
     if (selectedCell.getDate().equals(date)) {
       // De-select the currently-selected cell.
       selectedCell.setSelected(false);
       selectedCells.remove(selectedCell);
       date = null;
       break;
     }
   }
   for (Calendar cal : selectedCals) {
     if (sameDate(cal, selectedCal)) {
       selectedCals.remove(cal);
       break;
     }
   }
   return date;
 }
 private void clearOldCellSelections() {
   for (MonthCellDescriptor cellDescriptor : mSelectedCellList) {
     cellDescriptor.setSelected(false);
   }
   mSelectedCellList.clear();
 }
  private boolean doSelectDate(Date date, MonthCellDescriptor cell) {
    Calendar newlySelectedCal = Calendar.getInstance(locale);
    newlySelectedCal.setTime(date);
    // Sanitize input: clear out the hours/minutes/seconds/millis.
    setMidnight(newlySelectedCal);

    // Clear any remaining range state.
    for (MonthCellDescriptor selectedCell : selectedCells) {
      selectedCell.setRangeState(RangeState.NONE);
    }

    switch (selectionMode) {
      case RANGE:
        if (selectedCals.size() > 1) {
          // We've already got a range selected: clear the old one.
          clearOldSelections();
        } else if (selectedCals.size() == 1 && newlySelectedCal.before(selectedCals.get(0))) {
          // We're moving the start of the range back in time: clear the
          // old start date.
          clearOldSelections();
        }
        break;

      case MULTIPLE:
        date = applyMultiSelect(date, newlySelectedCal);
        break;

      case SINGLE:
        clearOldSelections();
        break;
      default:
        throw new IllegalStateException("Unknown selectionMode " + selectionMode);
    }

    if (date != null) {
      // Select a new cell.
      if (selectedCells.size() == 0 || !selectedCells.get(0).equals(cell)) {
        selectedCells.add(cell);
        cell.setSelected(true);
      }
      selectedCals.add(newlySelectedCal);

      if (selectionMode == SelectionMode.RANGE && selectedCells.size() > 1) {
        // Select all days in between start and end.
        Date start = selectedCells.get(0).getDate();
        Date end = selectedCells.get(1).getDate();
        selectedCells.get(0).setRangeState(MonthCellDescriptor.RangeState.FIRST);
        selectedCells.get(1).setRangeState(MonthCellDescriptor.RangeState.LAST);

        for (List<List<MonthCellDescriptor>> month : cells) {
          for (List<MonthCellDescriptor> week : month) {
            for (MonthCellDescriptor singleCell : week) {
              if (singleCell.getDate().after(start)
                  && singleCell.getDate().before(end)
                  && singleCell.isSelectable()) {
                singleCell.setSelected(true);
                singleCell.setRangeState(MonthCellDescriptor.RangeState.MIDDLE);
                selectedCells.add(singleCell);
              }
            }
          }
        }
      }
    }

    // Update the adapter.
    validateAndUpdate();
    return date != null;
  }