code: package caevo.sieves;
  
  import java.io.IOException;
  import java.util.List;
  
  import org.apache.uima.UIMAException;
  import org.apache.uima.analysis_engine.AnalysisEngine;
  import org.apache.uima.analysis_engine.AnalysisEngineDescription;
  import org.apache.uima.jcas.JCas;
  import org.apache.uima.resource.ResourceInitializationException;
  import org.cleartk.timeml.type.Anchor;
  import org.cleartk.timeml.type.Event;
  import org.cleartk.timeml.type.TemporalLink;
  import org.cleartk.timeml.type.Time;
  import org.cleartk.timeml.util.CleartkInternalModelFactory;
  import org.uimafit.factory.AggregateBuilder;
  import org.uimafit.util.JCasUtil;
  
  import caevo.SieveDocument;
  import caevo.SieveDocuments;
  import caevo.tlink.EventEventLink;
  import caevo.tlink.EventTimeLink;
  import caevo.tlink.TLink;
  import caevo.util.SieveJCasUtil;
  import caevo.util.CaevoProperties;
  
  import com.google.common.collect.Lists;
  
  public class CleartkTimemlSieve_ImplBase implements Sieve {
  
    private AnalysisEngine engine;
  
    public CleartkTimemlSieve_ImplBase(AnalysisEngineDescription... descriptions)
        throws UIMAException {
      AggregateBuilder aggregate = new AggregateBuilder();
      for (AnalysisEngineDescription description : descriptions) {
        aggregate.add(description);
      }
      this.engine = aggregate.createAggregate();
    }
  
    @Override
    public List<TLink> annotate(SieveDocument doc, List<TLink> currentTLinks) {
      try {
        // run the annotator on the document
        JCas jCas = this.engine.newJCas();
        SieveJCasUtil.fillJCasFromSieveDocument(jCas, doc);
        this.engine.process(jCas);
  
        // create objects for each detected TLink
        List<TLink> tlinks = Lists.newArrayList();
        for (TemporalLink cleartkTLink : JCasUtil.select(jCas,
            TemporalLink.class)) {
          Anchor source = cleartkTLink.getSource();
          Anchor target = cleartkTLink.getTarget();
          String sourceId = source.getId();
          String targetId = target.getId();
          String relation = cleartkTLink.getRelationType();
          // create different types of TLinks -- necessary only because Evaluate
          // does not properly handle general TLinks, only the specific subclasses
          TLink tlink;
          if (source instanceof Event && target instanceof Event) {
            tlink = new EventEventLink(sourceId, targetId, relation);
          } else if ((source instanceof Event && target instanceof Time)
              || (target instanceof Event && source instanceof Time)) {
            tlink = new EventTimeLink(sourceId, targetId, relation);
          } else {
            throw new IllegalArgumentException(
                String.format("can't create TLink for %s and %s",
                    source.getClass().getName(), target.getClass().getName()));
          }
          tlinks.add(tlink);
        }
        return tlinks;
      } catch (UIMAException e) {
        throw new RuntimeException(e);
      }
    }
  
    @Override
    public void train(SieveDocuments infoDocs) {
      // trained previously on TimeBank+AQUAINT corpus
    }
  
    public static AnalysisEngineDescription getAnnotatorDescription(
        Class<?> sieveClass, CleartkInternalModelFactory factory)
        throws IOException, ResourceInitializationException {
      String property = String.format("%s.model", sieveClass.getSimpleName());
      return CaevoProperties.hasProperty(property)
          ? factory.getAnnotatorDescription(CaevoProperties.getString(property))
          : factory.getAnnotatorDescription();
    }
  }
  