code: package com.quui.tm2;
  
  import java.io.Serializable;
  import java.util.ArrayList;
  import java.util.List;
  
  /**
   * Skeletal implementation of the Agent interface (cf. Bloch 2008, Item 18)
   * <p/>
   * TODO: document inheritance (Bloch 2008, Item 17)
   * @author Fabian Steeg (fsteeg)
   * @param <I> The input type
   * @param <O> The output type
   */
  public abstract class AbstractAgent<I extends Comparable<I> & Serializable, O extends Comparable<O> & Serializable>
          implements Agent<I, O> {
  
      /**
       * @param input The input to process, of type I
       * @return Returns the result of processing I, of type O
       */
      public abstract O process(I input);
  
      /**
       * @param input The input annotations
       * @return Returns the output annotationscreated for the input
       * @see com.quui.tm2.Agent#process(java.util.List)
       */
      public final List<Annotation<O>> process(final List<Annotation<I>> input) {
          List<Annotation<O>> result = new ArrayList<Annotation<O>>();
          for (Annotation<I> annotation : input) {
              @SuppressWarnings( "unchecked" ) // We are AbstractAgent<I,O>, should be safe
              Class<? extends AbstractAgent<I, O>> author = (Class<? extends AbstractAgent<I, O>>) getClass();
              Annotation<O> resultAnnotation = ImmutableAnnotation.getInstance(author, // TODO not convenient for API!
                      process(annotation.getValue()), annotation.getStart(), annotation.getEnd());
              result.add(resultAnnotation);
          }
          return result;
      }
  }
  