// file: $isip/doc/examples/class/mmedia/mmedia_example_05/example.cc
//

// isip include files
//
#include <AnnotationGraph.h>
#include <Console.h>

// this example demonstrates how to use the AnnotationGraph object
//
int main(int argc, const char** argv) {

  // declare AnnotationGraph objects
  //
  String gname_00(L"SWB0");
  String gtype_00(L"SWB0");
  String gtype_01(L"SWB1");
  String gtype_03(L"SWB2");
  String gtype_04(L"SWB3");    
  
  AnnotationGraph angr_00(gname_00, gtype_00);
  
  // verify the annotation graph id
  //
  if (!angr_00.getId().eq(gname_00)) {
    Console::put(L"invalid annotation graph\n");
  }

  // verify the annotation graph type
  //
  if (!angr_00.getType().eq(gtype_00)) {
    Console::put(L"invalid annotation graph\n");
  }

  angr_00.setType(gtype_01);
  if (!angr_00.getType().eq(gtype_01)) {
    Console::put(L"invalid annotation graph\n");
  }

  // create and delete anchors in the annotation graph
  //
  String gname_01(L"Timit");  
  Anchor* ancr_00;
  Anchor* ancr_01;  
  String newid_00;
  String newid_01;
  String newid_02;    
  Float offset_00(2.4);
  Float offset_01(4.9);
  Float offset_02(8.9);  
  String unit_00(L"seconds");
  
  AnnotationGraph angr_01(gname_01, gtype_01);

  newid_00 = angr_01.createAnchor(gname_01, offset_00, unit_00);
  ancr_00 = angr_01.getAnchorById(newid_00);

  newid_01 = angr_01.createAnchor(gname_01, offset_01, unit_00);
  ancr_01 = angr_01.getAnchorById(newid_01);
  
  if (ancr_00 == (Anchor*)NULL) {
    Console::put(L"invalid annotation graph\n");
  }
  if (angr_01.getAnchorById(newid_00) != ancr_00) {
    Console::put(L"invalid annotation graph\n");
  }

  angr_01.deleteAnchor(ancr_00);
  ancr_00 = angr_01.getAnchorById(newid_00);
  if (ancr_00 != (Anchor*)NULL) {
    Console::put(L"invalid annotation graph\n");
  }

  if (ancr_01 == (Anchor*)NULL) {
    Console::put(L"invalid annotation graph\n");
  }
  if (angr_01.getAnchorById(newid_01) != ancr_01) {
    Console::put(L"invalid annotation graph\n");
  }

  angr_01.deleteAnchor(ancr_01);
  ancr_01 = angr_01.getAnchorById(newid_01);
  if (ancr_01 != (Anchor*)NULL) {
    Console::put(L"invalid annotation graph\n");
  }  

  // add and delete anchor in the annotation graph
  //
  String ancrid_00(L"Anchor1");
  String ancrid_01(L"Anchor2");
  Anchor* ancr_02 = new Anchor(ancrid_00, offset_00, unit_00);
  Anchor* ancr_03 = new Anchor(ancrid_01, offset_01, unit_00);  

  angr_01.addAnchor(ancr_02);
  angr_01.addAnchor(ancr_03);  

  if (angr_01.getAnchorById(ancrid_00) != ancr_02) {
    Console::put(L"invalid annotation graph\n");
  }  
  if (angr_01.getAnchorById(ancrid_01) != ancr_03) {
    Console::put(L"invalid annotation graph\n");
  }

  angr_01.deleteAnchor(ancr_02);
  if (angr_01.getAnchorById(ancrid_00) != (Anchor*)NULL) {
    Console::put(L"invalid annotation graph\n");
  }
  angr_01.deleteAnchor(ancr_03);
  if (angr_01.getAnchorById(ancrid_01) != (Anchor*)NULL) {
    Console::put(L"invalid annotation graph\n");
  }  

  // create and delete annotations in the annotation graph
  //
  Annotation* anno_00;
  Annotation* anno_01;  
  String atype_00(L"Word");
  String atype_01(L"Transcription"); 
  Anchor* ancr_04 = new Anchor(ancrid_00, offset_00, unit_00);
  Anchor* ancr_05 = new Anchor(ancrid_01, offset_01, unit_00);
  
  newid_00 = angr_01.createAnnotation(gname_01, ancr_04, ancr_05, atype_00);
  newid_01 = angr_01.createAnnotation(gname_01, ancr_04, ancr_05, atype_01);

  anno_00 = angr_01.getById(newid_00);
  if (anno_00 == (Annotation*)NULL) {
    Console::put(L"invalid annotation graph\n");
  }
  if (angr_01.getById(newid_00) != anno_00) {
    Console::put(L"invalid annotation graph\n");
  }    
  anno_01 = angr_01.getById(newid_01);  
  if (anno_01 == (Annotation*)NULL) {
    Console::put(L"invalid annotation graph\n");
  }
  if (angr_01.getById(newid_01) != anno_01) {
    Console::put(L"invalid annotation graph\n");
  }

  angr_01.deleteAnnotation(anno_00);
  if (angr_01.getById(newid_00) != (Annotation*)NULL) {
    Console::put(L"invalid annotation graph\n");
  }
  angr_01.deleteAnnotation(anno_01);
  if (angr_01.getById(newid_01) != (Annotation*)NULL) {
    Console::put(L"invalid annotation graph\n");
  }  

  // add and delete annotation in the annotation graph
  //
  String annoid_00(L"Annotation1");
  String annoid_01(L"Annotation2");
  ancr_04 = new Anchor(ancrid_00, offset_00, unit_00);
  ancr_05 = new Anchor(ancrid_01, offset_01, unit_00);
  Annotation* anno_02 = new Annotation(annoid_00, ancr_04, ancr_05, atype_00);
  Annotation* anno_03 = new Annotation(annoid_01, ancr_04, ancr_05, atype_01);
  
  angr_01.add(anno_02);
  angr_01.add(anno_03);

  anno_00 = angr_01.getById(annoid_00);
  if (anno_00 == (Annotation*)NULL) {
    Console::put(L"invalid annotation graph\n");
  }
  if (angr_01.getById(annoid_00) != anno_00) {
    Console::put(L"invalid annotation graph\n");
  }    
  anno_01 = angr_01.getById(annoid_01);  
  if (anno_01 == (Annotation*)NULL) {
    Console::put(L"invalid annotation graph\n");
  }
  if (angr_01.getById(annoid_01) != anno_01) {
    Console::put(L"invalid annotation graph\n");
  }

  angr_01.deleteAnnotation(anno_00);
  if (angr_01.getById(annoid_00) != (Annotation*)NULL) {
    Console::put(L"invalid annotation graph\n");
  }
  angr_01.deleteAnnotation(anno_01);
  if (angr_01.getById(annoid_01) != (Annotation*)NULL) {
    Console::put(L"invalid annotation graph\n");
  }

  // set and get anchors and annotations via their offsets
  //
  float offset;
  String ancrid_02(L"Anchor3");
  String ancrid_03(L"Anchor4");  

  Anchor* ancr_06 = new Anchor(ancrid_02, offset_00, unit_00);
  angr_01.addAnchor(ancr_06);
  Anchor* ancr_07 = new Anchor(ancrid_03, offset_00, unit_00);
  angr_01.addAnchor(ancr_07);
  
  offset = 0.23456;
  angr_01.setAnchorOffset(ancr_06, offset);
  if (angr_01.getAnchorOffset(ancr_06) != offset) {
    Console::put(L"invalid annotation graph\n");
  }

  offset = 4.3356;
  angr_01.setAnchorOffset(ancr_07, offset);
  if (angr_01.getAnchorOffset(ancr_07) != offset) {
    Console::put(L"invalid annotation graph\n");
  }  

  if (!angr_01.unsetAnchorOffset(ancr_06)) {
    Console::put(L"invalid annotation graph\n");
  }
  if (!angr_01.unsetAnchorOffset(ancr_07)) {
    Console::put(L"invalid annotation graph\n");
  }

  offset = 0.0;
  angr_01.setAnchorOffset(ancr_06, offset);
  if (angr_01.getAnchorOffset(ancr_06) != offset) {
    Console::put(L"invalid annotation graph\n");
  }

  offset = 0.0;
  angr_01.setAnchorOffset(ancr_07, offset);
  if (angr_01.getAnchorOffset(ancr_07) != offset) {
    Console::put(L"invalid annotation graph\n");
  }
  
  angr_01.deleteAnchor(ancr_06);
  angr_01.deleteAnchor(ancr_07);

  // create some annotation graphs
  //
  String gname_02(L"Treebank");
  AnnotationGraph angr_02(gname_02, gtype_03);

  String ancrid_04(L"Anchor5");
  String ancrid_05(L"Anchor6");
  String ancrid_06(L"Anchor7");  

  String atype_02(L"T/he");
  String atype_03(L"T/she");

  Annotation* anno_04;
  Annotation* anno_04a;
  
  Annotation* anno_05;

  DoubleLinkedList<Anchor> anchor_list;  
  DoubleLinkedList<Annotation> anno_list;
  
  Anchor* ancr_08 = new Anchor(ancrid_04, offset_00, unit_00);
  Anchor* ancr_09 = new Anchor(ancrid_05, offset_01, unit_00);
  Anchor* ancr_10 = new Anchor(ancrid_06, offset_02, unit_00);
  
  newid_00 = angr_02.createAnnotation(gname_02, ancr_08, ancr_09, atype_02);
  anno_04 = angr_02.getById(newid_00);
  newid_01 = angr_02.createAnnotation(gname_02, ancr_09, ancr_10, atype_03);
  anno_05 = angr_02.getById(newid_01);

  // verify the incoming and outgoing methods in the annotation grah
  //
  if (!angr_02.getIncomingAnnotationSet(ancr_08, anno_list)) {
    Console::put(L"invalid annotation graph\n");
  }
  if (anno_list.length() != 0) {
    Console::put(L"invalid annotation graph\n");
  }

  if (!angr_02.getOutgoingAnnotationSet(ancr_10, anno_list)) {
    Console::put(L"invalid annotation graph\n");
  }
  if (anno_list.length() != 0) {
    Console::put(L"invalid annotation graph\n");
  }

  if (!angr_02.getIncomingAnnotationSet(ancr_10, anno_list)) {
    Console::put(L"invalid annotation graph\n");
  }
  if (anno_list.getFirst() != anno_05) {
    Console::put(L"invalid annotation graph\n");
  }

  if (!angr_02.getOutgoingAnnotationSet(ancr_08, anno_list)) {
    Console::put(L"invalid annotation graph\n");
  }
  if (anno_list.getFirst() != anno_04) {
    Console::put(L"invalid annotation graph\n");
  }

  if (!angr_02.getIncomingAnnotationSet(ancr_09, anno_list)) {
    Console::put(L"invalid annotation graph\n");
  }
  if (anno_list.getFirst() != anno_04) {
    Console::put(L"invalid annotation graph\n");
  }

  if (!angr_02.getOutgoingAnnotationSet(ancr_09, anno_list)) {
    Console::put(L"invalid annotation graph\n");
  }
  if (anno_list.getFirst() != anno_05) {
    Console::put(L"invalid annotation graph\n");
  }  

  // split the anchors and annotations in the annotation graph
  //
  Anchor* ancr_09a;
  Anchor* ancr_09b;  
  
  ancr_09a = angr_02.splitAnchor(ancr_09);

  if (!angr_02.getIncomingAnnotationSet(ancr_09, anno_list)) {
    Console::put(L"invalid annotation graph\n");
  }
  if (anno_list.getFirst() != anno_04) {
    Console::put(L"invalid annotation graph\n");
  }

  if (!angr_02.getOutgoingAnnotationSet(ancr_09, anno_list)) {
    Console::put(L"invalid annotation graph\n");
  }
  if (anno_list.length() != 0) {
    Console::put(L"invalid annotation graph\n");
  }

  if (!angr_02.getIncomingAnnotationSet(ancr_09a, anno_list)) {
    Console::put(L"invalid annotation graph\n");
  }
  if (anno_list.length() != 0) {
    Console::put(L"invalid annotation graph\n");
  }
  
  if (!angr_02.getOutgoingAnnotationSet(ancr_09a, anno_list)) {
    Console::put(L"invalid annotation graph\n");
  }
  if (anno_list.getFirst() != anno_05) {
    Console::put(L"invalid annotation graph\n");
  }  

  anno_04a = angr_02.splitAnnotation(anno_04);
  ancr_09b = anno_04->getEndAnchor();

  if (!(anno_04->getType()).eq(anno_04a->getType())) {
    Console::put(L"invalid annotation graph\n");
  }
  if (anno_04->getEndAnchor() != anno_04a->getStartAnchor()) {
    Console::put(L"invalid annotation graph\n");
  }
  if (anno_04->getEndAnchor()->getAnchored()) {
    Console::put(L"invalid annotation graph\n");
  }

  Annotation* anno_05a;
  Annotation* anno_05b;  
  Anchor* ancr_10a;
  Anchor* ancr_10b;

  angr_02.nSplitAnnotation(anno_05, 3, anno_list);
  anno_list.gotoFirst();  

  if (anno_list.length() != 3) {
    Console::put(L"invalid annotation graph\n");
  }
  if (!(anno_list.getCurr()->getType()).eq(anno_list.getNext()->getType())) {
    Console::put(L"invalid annotation graph\n");
  }
  if (anno_list.getCurr()->getEndAnchor() != anno_list.getNext()->getStartAnchor()) {
    Console::put(L"invalid annotation graph\n");
  }
  if (anno_list.getCurr()->getEndAnchor()->getAnchored()) {
    Console::put(L"invalid annotation graph\n");
  }

  anno_list.gotoNext();
  anno_05a = anno_list.getCurr();
  ancr_10a = anno_05a->getStartAnchor();
  
  if (anno_list.length() != 3) {
    Console::put(L"invalid annotation graph\n");
  }
  if (!(anno_list.getCurr()->getType()).eq(anno_list.getNext()->getType())) {
    Console::put(L"invalid annotation graph\n");
  }
  if (anno_list.getCurr()->getEndAnchor() != anno_list.getNext()->getStartAnchor()) {
    Console::put(L"invalid annotation graph\n");
  }
  if (anno_list.getCurr()->getEndAnchor()->getAnchored()) {
    Console::put(L"invalid annotation graph\n");
  }

  anno_list.gotoNext();
  anno_05b = anno_list.getCurr(); 
  ancr_10b = anno_05b->getStartAnchor();

  // get the anchor set and annotation set by offset in the annotation graph
  //
  angr_02.getAnchorSet(anchor_list);

  if (anchor_list.length() != 7) {
    Console::put(L"invalid annotation graph\n");
  }

  angr_02.getAnchorSetByOffset(offset_00, anchor_list);
  if (anchor_list.getFirst() != ancr_08) {
    Console::put(L"invalid annotation graph\n");
  }
  angr_02.getAnchorSetByOffset(offset_01, anchor_list);
  if (anchor_list.getFirst() != ancr_09) {
    Console::put(L"invalid annotation graph\n");
  }
  if (anchor_list.getLast() != ancr_09a) {
    Console::put(L"invalid annotation graph\n");
  }  
  angr_02.getAnchorSetByOffset(offset_02, anchor_list);
  if (anchor_list.getFirst() != ancr_10) {
    Console::put(L"invalid annotation graph\n");
  }  

  // get annotation by the type in the annotation graph
  //
  angr_02.getAnnotationSetByType(atype_02, anno_list);

  if (anno_list.length() != 2) {
    Console::put(L"invalid annotation graph\n");
  }
  if (anno_list.getFirst() != anno_04) {
    Console::put(L"invalid annotation graph\n");
  }
  if (anno_list.getLast() != anno_04a) {
    Console::put(L"invalid annotation graph\n");
  }
  
  angr_02.getAnnotationSetByType(atype_03, anno_list);

  anno_list.gotoFirst();  
  if (anno_list.length() != 3) {
    Console::put(L"invalid annotation graph\n");
  }    
  if (anno_list.getFirst() != anno_05) {
    Console::put(L"invalid annotation graph\n");
  }
  if (anno_list.getNext() != anno_05a) {
    Console::put(L"invalid annotation graph\n");
  }
  if (anno_list.getLast() != anno_05b) {
    Console::put(L"invalid annotation graph\n");
  }    

  // clear the dynamically allocated anchors 
  //
  for (boolean more = anchor_list.gotoFirst(); more;
       more = anchor_list.gotoNext()) {
    angr_02.deleteAnchor(anchor_list.getCurr());
  }

  // set up an example annotation graph
  //
  String gname_03(L"AG1");  
  AnnotationGraph angr_03(gname_03, gtype_04);

  String ancrid_07(L"Anchor8");
  String ancrid_08(L"Anchor9");
  String ancrid_09(L"Anchor10");  

  String feat_00(L"feature0");
  String feat_01(L"feature1");
  String feat_02(L"feature2");
  String feat_03(L"feature3");    

  String value_00(L"value0");
  String value_01(L"value1");
  String value_02(L"value2");
  String value_03(L"value3");    
  
  Annotation* anno_06;
  Annotation* anno_07;

  Anchor* ancr_11;
  Anchor* ancr_12;
  Anchor* ancr_13;  
  
  String atype_04(L"T/see");
  String atype_05(L"T/Jane");

  newid_00 = angr_03.createAnchor(gname_03, offset_00, unit_00);
  ancr_11 = angr_03.getAnchorById(newid_00);
  newid_01 = angr_03.createAnchor(gname_03, offset_01, unit_00);
  ancr_12 = angr_03.getAnchorById(newid_01);
  newid_02 = angr_03.createAnchor(gname_03, offset_02, unit_00);
  ancr_13 = angr_03.getAnchorById(newid_02);  
  
  newid_00 = angr_03.createAnnotation(gname_03, ancr_11, ancr_12, atype_04);
  anno_06 = angr_03.getById(newid_00);  
  newid_01 = angr_03.createAnnotation(gname_03, ancr_12, ancr_13, atype_05);
  anno_07 = angr_03.getById(newid_01);

  // get the annotation by its offset in the annotation graph
  //
  angr_03.getAnnotationSetByOffset(offset_00, anno_list);
  if (anno_list.getFirst() != anno_06) {
    Console::put(L"invalid annotation graph\n");
  }
  
  angr_03.getAnnotationSetByOffset(offset_01, anno_list);
  if (anno_list.getFirst() != anno_06) {
    Console::put(L"invalid annotation graph\n");
  }
  if (anno_list.getLast() != anno_07) {
    Console::put(L"invalid annotation graph\n");
  }
  
  angr_03.getAnnotationSetByOffset(offset_02, anno_list);  
  if (anno_list.getLast() != anno_07) {
    Console::put(L"invalid annotation graph\n");
  }

  // get annotation sequence by its offset in the annotation graph
  //
  angr_03.getAnnotationSeqByOffset(anno_list, 2.0, 3.4);
  if (anno_list.getFirst() != anno_06) {
    Console::put(L"invalid annotation graph\n");
  }

  angr_03.getAnnotationSeqByOffset(anno_list, 0.0, 1.3);
  if (anno_list.length() != 0) {
    Console::put(L"invalid annotation graph\n");
  }

  angr_03.getAnnotationSeqByOffset(anno_list, 2.4, 4.9);
  if (anno_list.getFirst() != anno_06) {
    Console::put(L"invalid annotation graph\n");
  }
  if (anno_list.getLast() != anno_07) {
    Console::put(L"invalid annotation graph\n");
  }      

  angr_03.getAnnotationSeqByOffset(anno_list, 3.7, 6.7);
  if (anno_list.getFirst() != anno_07) {
    Console::put(L"invalid annotation graph\n");
  }

  angr_03.getAnnotationSeqByOffset(anno_list, 5.8, 10.4);
  if (anno_list.length() != 0) {
    Console::put(L"invalid annotation graph\n");
  }  

  // get the annotation by its offset in the annotation graph
  //
  if (angr_03.getAnnotationByOffset(2.3) != (Annotation*)NULL) {
    Console::put(L"invalid annotation graph\n");
  }
  if (angr_03.getAnnotationByOffset(2.4) != anno_06) {
    Console::put(L"invalid annotation graph\n");
  }
  if (angr_03.getAnnotationByOffset(3.4) != anno_06) {
    Console::put(L"invalid annotation graph\n");
  }
  if (angr_03.getAnnotationByOffset(4.9) != anno_06) {
    Console::put(L"invalid annotation graph\n");
  }
  
  if (angr_03.getAnnotationByOffset(4.91) != anno_07) {
    Console::put(L"invalid annotation graph\n");
  }
  if (angr_03.getAnnotationByOffset(5.91) != anno_07) {
    Console::put(L"invalid annotation graph\n");
  }
  if (angr_03.getAnnotationByOffset(8.9) != anno_07) {
    Console::put(L"invalid annotation graph\n");
  }          
  if (angr_03.getAnnotationByOffset(8.91) != (Annotation*)NULL) {
    Console::put(L"invalid annotation graph\n");
  }  

  // get the nearest offset in the annotation graph
  //
  if (!Integral::almostEqual(angr_03.getNearestOffset(2.4), (float)2.4)) {
    Console::put(L"invalid annotation graph\n");
  }  
  if (!Integral::almostEqual(angr_03.getNearestOffset(1.2), (float)2.4)) {
    Console::put(L"invalid annotation graph\n");
  }
  if (!Integral::almostEqual(angr_03.getNearestOffset(2.3999), (float)2.4)) {
    Console::put(L"invalid annotation graph\n");
  }
  if (!Integral::almostEqual(angr_03.getNearestOffset(2.4001), (float)2.4)) {
    Console::put(L"invalid annotation graph\n");
  }    
  if (!Integral::almostEqual(angr_03.getNearestOffset(3.0), (float)2.4)) {
    Console::put(L"invalid annotation graph\n");
  }

  if (!Integral::almostEqual(angr_03.getNearestOffset(4.9), (float)4.9)) {
    Console::put(L"invalid annotation graph\n");
  }  
  if (!Integral::almostEqual(angr_03.getNearestOffset(4.0), (float)4.9)) {
    Console::put(L"invalid annotation graph\n");
  }
  if (!Integral::almostEqual(angr_03.getNearestOffset(4.8999), (float)4.9)) {
    Console::put(L"invalid annotation graph\n");
  }
  if (!Integral::almostEqual(angr_03.getNearestOffset(4.9001), (float)4.9)) {
    Console::put(L"invalid annotation graph\n");
  }      
  if (!Integral::almostEqual(angr_03.getNearestOffset(6.0), (float)4.9)) {
    Console::put(L"invalid annotation graph\n");
  }

  if (!Integral::almostEqual(angr_03.getNearestOffset(8.9), (float)8.9)) {
    Console::put(L"invalid annotation graph\n");
  }  
  if (!Integral::almostEqual(angr_03.getNearestOffset(7.8), (float)8.9)) {
    Console::put(L"invalid annotation graph\n");
  }
  if (!Integral::almostEqual(angr_03.getNearestOffset(8.8999), (float)8.9)) {
    Console::put(L"invalid annotation graph\n");
  }
  if (!Integral::almostEqual(angr_03.getNearestOffset(8.9001), (float)8.9)) {
    Console::put(L"invalid annotation graph\n");
  }
  if (!Integral::almostEqual(angr_03.getNearestOffset(10.6), (float)8.9)) {
    Console::put(L"invalid annotation graph\n");
  }      

  // get nearest anchors by its offset in the annotation graph
  //
  angr_03.getAnchorSetNearestOffset(2.3, anchor_list);
  if (anchor_list.getFirst() != ancr_11) {
    Console::put(L"invalid annotation graph\n");
  }
  angr_03.getAnchorSetNearestOffset(2.4, anchor_list);
  if (anchor_list.getFirst() != ancr_11) {
    Console::put(L"invalid annotation graph\n");
  }  
  angr_03.getAnchorSetNearestOffset(2.5, anchor_list);  
  if (anchor_list.getFirst() != ancr_11) {
    Console::put(L"invalid annotation graph\n");
  }
  
  angr_03.getAnchorSetNearestOffset(4.8, anchor_list);
  if (anchor_list.getFirst() != ancr_12) {
    Console::put(L"invalid annotation graph\n");
  }  
  angr_03.getAnchorSetNearestOffset(4.9, anchor_list);
  if (anchor_list.getFirst() != ancr_12) {
    Console::put(L"invalid annotation graph\n");
  }    
  angr_03.getAnchorSetNearestOffset(5.0, anchor_list);
  if (anchor_list.getFirst() != ancr_12) {
    Console::put(L"invalid annotation graph\n");
  }    

  angr_03.getAnchorSetNearestOffset(8.8, anchor_list);
  if (anchor_list.getFirst() != ancr_13) {
    Console::put(L"invalid annotation graph\n");
  }    
  angr_03.getAnchorSetNearestOffset(8.9, anchor_list);
  if (anchor_list.getFirst() != ancr_13) {
    Console::put(L"invalid annotation graph\n");
  }    
  angr_03.getAnchorSetNearestOffset(9.0, anchor_list);
  if (anchor_list.getFirst() != ancr_13) {
    Console::put(L"invalid annotation graph\n");
  }    

  // set the feature in the annotation graph
  //
  if (!angr_03.setFeature(newid_00, feat_00, value_00)) {
    Console::put(L"invalid annotation graph\n");
  }
  if (!angr_03.setFeature(newid_00, feat_01, value_01)) {
    Console::put(L"invalid annotation graph\n");
  }  
  if (!angr_03.setFeature(newid_01, feat_02, value_02)) {
    Console::put(L"invalid annotation graph\n");
  }
  if (!angr_03.setFeature(newid_01, feat_03, value_03)) {
    Console::put(L"invalid annotation graph\n");
  }  

  // verify that the feature exists in the annotation graph
  //
  if (!angr_03.existsFeature(newid_00, feat_00)) {
    Console::put(L"invalid annotation graph\n");
  }
  if (!angr_03.existsFeature(newid_00, feat_01)) {
    Console::put(L"invalid annotation graph\n");
  }  
  if (!angr_03.existsFeature(newid_01, feat_02)) {
    Console::put(L"invalid annotation graph\n");
  }
  if (!angr_03.existsFeature(newid_01, feat_03)) {
    Console::put(L"invalid annotation graph\n");
  }

  // delete the feature in the annotation graph
  //
  if (!angr_03.deleteFeature(newid_00, feat_01)) {
    Console::put(L"invalid annotation graph\n");
  }  
  if (!angr_03.deleteFeature(newid_01, feat_03)) {
    Console::put(L"invalid annotation graph\n");
  }

  if (!angr_03.existsFeature(newid_00, feat_00)) {
    Console::put(L"invalid annotation graph\n");
  }
  if (angr_03.existsFeature(newid_00, feat_01)) {
    Console::put(L"invalid annotation graph\n");
  }  
  if (!angr_03.existsFeature(newid_01, feat_02)) {
    Console::put(L"invalid annotation graph\n");
  }
  if (angr_03.existsFeature(newid_01, feat_03)) {
    Console::put(L"invalid annotation graph\n");
  }

  if (!angr_03.setFeature(newid_00, feat_01, value_01)) {
    Console::put(L"invalid annotation graph\n");
  }  
  if (!angr_03.setFeature(newid_01, feat_03, value_03)) {
    Console::put(L"invalid annotation graph\n");
  }

  // get features in the annotation graph
  //
  if (!angr_03.getFeature(newid_00, feat_00).eq(value_00)) {
    Console::put(L"invalid annotation graph\n");
  }
  if (!angr_03.getFeature(newid_00, feat_01).eq(value_01)) {
    Console::put(L"invalid annotation graph\n");
  }
  if (!angr_03.getFeature(newid_01, feat_02).eq(value_02)) {
    Console::put(L"invalid annotation graph\n");
  }
  if (!angr_03.getFeature(newid_01, feat_03).eq(value_03)) {
    Console::put(L"invalid annotation graph\n");
  }

  // get the feature names in the annotation graph
  //
  Vector<String> fnames;

  if (!angr_03.getFeatureNames(newid_00, fnames)) {
    Console::put(L"invalid annotation graph\n");
  }
  if (fnames.length() != 2) {
    Console::put(L"invalid annotation graph\n");
  }
  if (!fnames.contains(&feat_00)) {
    Console::put(L"invalid annotation graph\n");
  }
  if (!fnames.contains(&feat_01)) {
    Console::put(L"invalid annotation graph\n");
  }  
  
  if (!angr_03.getFeatureNames(newid_01, fnames)) {
    Console::put(L"invalid annotation graph\n");
  }
  if (fnames.length() != 2) {
    Console::put(L"invalid annotation graph\n");
  }
  if (!fnames.contains(&feat_02)) {
    Console::put(L"invalid annotation graph\n");
  }
  if (!fnames.contains(&feat_03)) {
    Console::put(L"invalid annotation graph\n");
  }

  // unset the features in the annotation graph
  //
  if (!angr_03.unsetFeatures(newid_00)) {
    Console::put(L"invalid annotation graph\n");
  }
  if (!angr_03.unsetFeatures(newid_01)) {
    Console::put(L"invalid annotation graph\n");
  }  

  if (!angr_03.getFeature(newid_00, feat_00).eq(String::EMPTY)) {
    Console::put(L"invalid annotation graph\n");
  }
  if (!angr_03.getFeature(newid_00, feat_01).eq(String::EMPTY)) {
    Console::put(L"invalid annotation graph\n");
  }
  if (!angr_03.getFeature(newid_01, feat_02).eq(String::EMPTY)) {
    Console::put(L"invalid annotation graph\n");
  }
  if (!angr_03.getFeature(newid_01, feat_03).eq(String::EMPTY)) {
    Console::put(L"invalid annotation graph\n");
  }

  // set the features in the annotation graph
  //
  if (!angr_03.setFeature(anno_06, feat_00, value_00)) {
    Console::put(L"invalid annotation graph\n");
  }
  if (!angr_03.setFeature(anno_06, feat_01, value_01)) {
    Console::put(L"invalid annotation graph\n");
  }  
  if (!angr_03.setFeature(anno_07, feat_02, value_02)) {
    Console::put(L"invalid annotation graph\n");
  }
  if (!angr_03.setFeature(anno_07, feat_03, value_03)) {
    Console::put(L"invalid annotation graph\n");
  }

  if (!angr_03.existsFeature(newid_00, feat_00)) {
    Console::put(L"invalid annotation graph\n");
  }
  if (!angr_03.existsFeature(newid_00, feat_01)) {
    Console::put(L"invalid annotation graph\n");
  }  
  if (!angr_03.existsFeature(newid_01, feat_02)) {
    Console::put(L"invalid annotation graph\n");
  }
  if (!angr_03.existsFeature(newid_01, feat_03)) {
    Console::put(L"invalid annotation graph\n");
  }

  // get the annotation set by feature-value pair in the annotation graph
  //
  if (!angr_03.getAnnotationSetByFeature(feat_00, value_00, anno_list)) {
    Console::put(L"invalid annotation graph\n");
  }
  if (anno_list.length() != 1) {
    Console::put(L"invalid annotation graph\n");
  } 
  if (anno_list.getFirst() != (Annotation*)anno_06) {
    Console::put(L"invalid annotation graph\n");
  }

  if (!angr_03.getAnnotationSetByFeature(feat_01, value_01, anno_list)) {
    Console::put(L"invalid annotation graph\n");
  }
  if (anno_list.length() != 1) {
    Console::put(L"invalid annotation graph\n");
  } 
  if (anno_list.getFirst() != (Annotation*)anno_06) {
    Console::put(L"invalid annotation graph\n");
  }

  if (!angr_03.getAnnotationSetByFeature(feat_02, value_02, anno_list)) {
    Console::put(L"invalid annotation graph\n");
  }
  if (anno_list.length() != 1) {
    Console::put(L"invalid annotation graph\n");
  } 
  if (anno_list.getFirst() != (Annotation*)anno_07) {
    Console::put(L"invalid annotation graph\n");
  }

  if (!angr_03.getAnnotationSetByFeature(feat_03, value_03, anno_list)) {
    Console::put(L"invalid annotation graph\n");
  }
  if (anno_list.length() != 1) {
    Console::put(L"invalid annotation graph\n");
  } 
  if (anno_list.getFirst() != (Annotation*)anno_07) {
    Console::put(L"invalid annotation graph\n");
  }    
  
  // exit gracefully
  //
  Integral::exit();
}
