void advanceMultipleSelection (ListSelectionModel firstModel, int firstMin,
void advanceMultipleSelection(JTable table, ListSelectionModel firstModel, int firstMin,
    void advanceMultipleSelection (ListSelectionModel firstModel, int firstMin,                                   int firstMax, ListSelectionModel secondModel,                                    int secondMin, int secondMax, boolean reverse,                                   boolean eventIsTab)    {      // If eventIsTab, all the "firsts" correspond to columns, otherwise, to rows      // "seconds" correspond to the opposite      int firstLead = firstModel.getLeadSelectionIndex();      int secondLead = secondModel.getLeadSelectionIndex();      int numFirsts = eventIsTab ?         table.getModel().getColumnCount() : table.getModel().getRowCount();      int numSeconds = eventIsTab ?         table.getModel().getRowCount() : table.getModel().getColumnCount();      // check if we have to wrap the "firsts" around, going to the other side      if ((firstLead == firstMax && !reverse) ||           (reverse && firstLead == firstMin))        {          firstModel.addSelectionInterval(reverse ? firstMax : firstMin,                                           reverse ? firstMax : firstMin);                    // check if we have to wrap the "seconds"          if ((secondLead == secondMax && !reverse) ||               (reverse && secondLead == secondMin))            secondModel.addSelectionInterval(reverse ? secondMax : secondMin,                                              reverse ? secondMax : secondMin);          // if we're not wrapping the seconds, we have to find out where we          // are within the secondModel and advance to the next cell (or           // go back to the previous cell if reverse == true)          else            {              int[] secondsSelected;              if (eventIsTab && table.getRowSelectionAllowed() ||                   !eventIsTab && table.getColumnSelectionAllowed())                secondsSelected = eventIsTab ?                   table.getSelectedRows() : table.getSelectedColumns();              else                {                  // if row selection is not allowed, then the entire column gets                  // selected when you click on it, so consider ALL rows selected                  secondsSelected = new int[numSeconds];                  for (int i = 0; i < numSeconds; i++)                  secondsSelected[i] = i;                }              // and now find the "next" index within the model              int secondIndex = reverse ? secondsSelected.length - 1 : 0;              if (!reverse)                while (secondsSelected[secondIndex] <= secondLead)                  secondIndex++;              else                while (secondsSelected[secondIndex] >= secondLead)                  secondIndex--;                            // and select it - updating the lead selection index              secondModel.addSelectionInterval(secondsSelected[secondIndex],                                                secondsSelected[secondIndex]);            }        }      // We didn't have to wrap the firsts, so just find the "next" first      // and select it, we don't have to change "seconds"      else        {          int[] firstsSelected;          if (eventIsTab && table.getColumnSelectionAllowed() ||               !eventIsTab && table.getRowSelectionAllowed())            firstsSelected = eventIsTab ?               table.getSelectedColumns() : table.getSelectedRows();          else            {              // if selection not allowed, consider ALL firsts to be selected              firstsSelected = new int[numFirsts];              for (int i = 0; i < numFirsts; i++)                firstsSelected[i] = i;            }          int firstIndex = reverse ? firstsSelected.length - 1 : 0;          if (!reverse)            while (firstsSelected[firstIndex] <= firstLead)              firstIndex++;          else             while (firstsSelected[firstIndex] >= firstLead)              firstIndex--;          firstModel.addSelectionInterval(firstsSelected[firstIndex],                                           firstsSelected[firstIndex]);          secondModel.addSelectionInterval(secondLead, secondLead);        }    }