/*------------------------------------------------------------
  countSuch:
  int countSuch2(Traversal<T> tr, ISelect<T> choice){
    return countSuchAcc(tr, 0, choice);
  }
  
  Method Header:  int countSuchAcc(Traversal tr, int acc, ISelect choice)
  BASE-VALUE:     0
  UPDATE:         int update(T t, int acc, ISelect choice){
                   if (choice.select(t)) 
                     return acc + 1;
                   else
                     return acc;
                  }
  --------------------------------------------------------------------*/

 /** RECURSIVE VERSION
  * Count how many data elements generated by the given traversal
  * satisfy the given ISelect predicate.
  */
 public <T> int countSuch2(Traversal<T> tr, ISelect<T> choice){
   return countSuchAcc(tr, 0, choice);
 }
 
 /** RECURSIVE VERSION --- accumulator based helper.
  * Count how many data elements generated by the given traversal
  * satisfy the given ISelect predicate.
  */
 public <T> int countSuchAcc(Traversal<T> tr, 
                             int acc, 
                             ISelect<T> choice){
   if (tr.isEmpty()) 
     return acc;
   else
     return countSuchAcc(tr.getRest(), 
                      updateCountSuch(tr.getFirst(), acc, choice),
                      choice);
 } 
 
 /** A helper to produce the updated value of the accumulator
  * @param <T> the type of data in this data set
  * @param t the instance of the data set to be used in the update
  * @param acc the current value of the accumulator
  * @param choice the given ISelect predicate.
  * @return the updated value of the accumulator.
  */
 protected <T> int updateCountSuch(T t, 
                                   int acc, 
                                   ISelect<T> choice){
   if (choice.select(t)) 
     return acc + 1;
   else
     return acc;
 }