public void addDoc(String filename) {
   String name = filename.substring(filename.lastIndexOf('/') + 1);
   try {
     JuxtaDocument document = documentManager.addDocument(name, filename);
     if (document != null) {
       comparisonSet.addCollation(document);
     }
   } catch (LoggedException e) {
     e.printStackTrace();
     fail();
   }
 }
  protected void setUp() throws Exception {
    super.setUp();

    // SimpleLogger.initFileLogging(System.getProperty("user.dir") + "/juxta.log");
    SimpleLogger.initConsoleLogging();
    // SimpleLogger.setLoggingLevel(DiffAlgorithm.VERBOSE_LOGGING);
    log = new DebugLogger(System.getProperty("user.dir") + "/TestMoves.log");

    WriteFile(
        file1,
        "da fust line\nan' da secunt line\n3\nNow is the time for the fourth line\nfinally, the lassed line\nPsych! actually there is another line at the end.\n");
    WriteFile(
        file2,
        "da first line\nfinally, the last line\nan' da secunt line\n33\nNow is the tine for the forth line\nPsych! actually there is another line at the end.\n");
    WriteFile(
        file3,
        "first line\nan' da secunt line\n33\nfinally, the last line\nNow is the time for the fourth line\nPsych! actually there is another line at the end.\n");
    WriteFile(
        file4,
        "da fust line\nan' da secunt line\n3\nNow is the time for the fourth line\nfinally, the lassed line\n");
    WriteFile(
        file5,
        "da first line\nfinally, the last line\nan' da secunt line\n33\nNow is the tine for the forth line\n");
    WriteFile(
        file6,
        "From the fixt lull of heaven, she saw\nTime, like a pulse, shake fierce\nThrough all the worlds. Her gaze still strove,\nIn that steep gulph, to pierce\nThe swarm: and then she spake, as when\nThe stars sang in their spheres.\n\n�I wish that he were come to me,\nFor he will come,� she said.\n�Have I not prayed in solemn heaven?\nOn earth, has he not prayed?\nAre not two prayers a perfect strength?\nAnd shall I feel afraid?\n\n�When round his head the aureole clings,\nAnd he is clothed in white,\nI'll take his hand, and go with him\nTo the deep wells of light,\nAnd we will step down as to a stream\nAnd bathe there in God's sight.\n");
    WriteFile(
        file7,
        "From the fixed place of Heaven she saw\n Time like a pulse shake fierce\nThrough all the worlds. Her gaze still strove\n Within the gulf to pierce\nIts path; and now she spoke as when\n The stars sang in their spheres.\n\nThe sun was gone now; the curled moon\n Was like a little feather\nFluttering far down the gulf; and now\n She spoke through the still weather.\nHer voice was like the voice the stars\n Had when they sang together.\n\n(Ah sweet! Even now, in that bird's song,\n Strove not her accents there,\nFain to be hearkened? When those bells\n Possessed the mid-day air,\nStrove not her steps to reach my side\n Down all the echoing stair?)\n\n�I wish that he were come to me,\n For he will come,� she said.\n�Have I not prayed in Heaven?�on earth,\n Lord, Lord, has he not pray'd?\nAre not two prayers a perfect strength?\n And shall I feel afraid?\n\n�When round his head the aureole clings,\n And he is clothed in white,\nI'll take his hand and go with him\n To the deep wells of light;\nWe will step down as to a stream,\n And bathe there in God's sight\n");

    try {
      documentManager = new DocumentManager(null);
      DocumentManagerAccess.getInstance().setDocumentManager(documentManager);
      documentManager.loadManifest();

      comparisonSet = new ComparisonSet(documentManager, false);
      movesManager = documentManager.getMovesManager();
      movesManager.addListener(comparisonSet);

      // LinkedList documentList = documentManager.getUncollatedDocuments();

      addDoc(file1);
      addDoc(file2);
    } catch (LoggedException e) {
      e.printStackTrace();
      fail();
    }
  }
  public void testMove() {
    // The first two documents have been setup and collated by the time we get here.
    try {
      // get the collation for each document being the base first, before doing the move
      LogHeader("Baseline");
      analyze("baseline0"); // file1 is base, file2 is witness
      analyze("baseline00"); // file1 is both base and witness
      analyze("baseline1"); // file2 is base, file1 is witness
      analyze("baseline11"); // file2 is both base and witness

      // create the move and analyze the collation again
      LogHeader("Create normal move");
      createMove(0, 70, 94, 1, 14, 36);
      analyze("firstmove0"); // file1 is base, file2 is witness
      analyze("firstmove1"); // file2 is base, file1 is witness

      // add third document - shouldn't change the results; 3rd doc should not see move.
      LogHeader("Add third file");
      addDoc(file3);
      analyze("firstmove0"); // file1 is base, file2 is witness
      analyze("firstmove1"); // file2 is base, file1 is witness
      analyze("compare13"); // file1 is base, file3 is witness
      analyze("compare23"); // file2 is base, file3 is witness
      analyze("compare12"); // file1 is base, file2 is witness
      analyze("compare21"); // file2 is base, file1 is witness

      // remove the second document -now file3 is the second doc
      LogHeader("Remove file2.txt");
      documentManager.removeDocument(getDoc(1));
      analyze("remove0"); // file1 is base, file3 is witness
      analyze("remove1"); // file3 is base, file1 is witness

      // add the second document back in - should not keep the move; file2 is now the third doc
      LogHeader("reload file2.txt");
      addDoc(file2);
      analyze("read2nd0"); // file1 is base, file3 is witness
      analyze("read2nd1"); // file3 is base, file1 is witness
      analyze("read2nd2"); // file1 is base, file2 is witness

      // create a move that doesn't match and analyze again
      LogHeader("Create a random, semantically meaningless move");
      createMove(0, 10, 20, 1, 18, 22);
      analyze("mismatch0"); // file1 is base, file3 is witness
      analyze("mismatch1"); // file3 is base, file1 is witness
      removeMove(0, 10, 20, 1, 18, 22);
      analyze("read2nd0"); // file1 is base, file3 is witness
      analyze("read2nd1"); // file3 is base, file1 is witness
      analyze("read2nd2"); // file1 is base, file2 is witness

      // create a move to the same place
      LogHeader("Create a move to the same place");
      createMove(0, 0, 10, 1, 0, 10);
      analyze("sameplace0"); // file1 is base, file3 is witness
      analyze("sameplace1"); // file3 is base, file1 is witness
      removeMove(0, 0, 10, 1, 0, 10);
      analyze("read2nd0"); // file1 is base, file3 is witness
      analyze("read2nd1"); // file3 is base, file1 is witness
      analyze("read2nd2"); // file1 is base, file2 is witness

      // create two moves
      LogHeader("create two moves");
      createMove(0, 10, 20, 1, 40, 62);
      createMove(0, 70, 92, 1, 14, 36);
      analyze("twomoves0"); // file1 is base, file3 is witness
      analyze("twomoves1"); // file3 is base, file1 is witness
      removeMove(0, 10, 20, 1, 40, 62);
      removeMove(0, 70, 92, 1, 14, 36);
      analyze("read2nd0"); // file1 is base, file3 is witness
      analyze("read2nd1"); // file3 is base, file1 is witness
      analyze("read2nd2"); // file1 is base, file2 is witness

      // move entire base doc to place in witness
      LogHeader("move entire base doc");
      createMove(0, 0, 93, 1, 14, 36);
      analyze("moveentire0"); // file1 is base, file2 is witness
      analyze("moveentire1"); // file2 is base, file1 is witness
      removeMove(0, 0, 93, 1, 14, 36);
      analyze("read2nd0"); // file1 is base, file3 is witness
      analyze("read2nd1"); // file3 is base, file1 is witness
      analyze("read2nd2"); // file1 is base, file2 is witness

      // create two moves that overlap
      LogHeader("create two moves that overlap");
      createMove(0, 10, 20, 1, 20, 30);
      createMove(0, 15, 25, 1, 25, 35);
      analyze("overlap0"); // file1 is base, file2 is witness
      analyze("overlap1"); // file2 is base, file1 is witness
      removeMove(0, 15, 25, 1, 25, 35);
      removeMove(0, 10, 20, 1, 20, 30);
      analyze("read2nd0"); // file1 is base, file3 is witness
      analyze("read2nd1"); // file3 is base, file1 is witness
      analyze("read2nd2"); // file1 is base, file2 is witness

      // create a zero-length base move
      LogHeader("create a zero-length base move");
      createMove(0, 10, 10, 1, 20, 30);
      analyze("zerolengthbase0"); // file1 is base, file2 is witness
      analyze("zerolengthbase1"); // file2 is base, file1 is witness
      removeMove(0, 10, 10, 1, 20, 30);
      analyze("read2nd0"); // file1 is base, file3 is witness
      analyze("read2nd1"); // file3 is base, file1 is witness
      analyze("read2nd2"); // file1 is base, file2 is witness

      // create a zero-length witness move
      LogHeader("create a zero-length witness move");
      createMove(0, 10, 20, 1, 20, 20);
      analyze("zerolengthwitness0"); // file1 is base, file2 is witness
      analyze("zerolengthwitness1"); // file2 is base, file1 is witness
      removeMove(0, 10, 20, 1, 20, 20);
      analyze("read2nd0"); // file1 is base, file3 is witness
      analyze("read2nd1"); // file3 is base, file1 is witness
      analyze("read2nd2"); // file1 is base, file2 is witness

      // Do moves between three documents
      LogHeader("Do moves between three documents");
      createMove(0, 70, 92, 1, 33, 55);
      createMove(0, 70, 92, 2, 14, 36);
      analyze("threeway12"); // file1 is base, file2 is witness
      analyze("threeway13"); // file1 is base, file3 is witness
      analyze("threeway21"); // file2 is base, file1 is witness
      analyze("threeway23"); // file2 is base, file3 is witness
      analyze("threeway31"); // file3 is base, file1 is witness
      analyze("threeway32"); // file3 is base, file2 is witness
    } catch (ReportedException e) {
      e.printStackTrace();
      fail();
    } catch (LoggedException e) {
      e.printStackTrace();
      fail();
    }
  }
  public void testRecollateAfterMove() {
    // The first two documents have been setup and collated by the time we get here.
    documentManager.removeDocument(getDoc(0));
    documentManager.removeDocument(getDoc(0));
    addDoc(file6);
    addDoc(file7);

    try {
      LogHeader("Baseline");
      analyze("ram_baseline0"); // file6 is base, file7 is witness
      analyze("ram_baseline1"); // file7 is base, file6 is witness

      // Extra cases:
      // In damozel, end a move with "stair?)" from 1855 MS. It acts differently if the "?)" is
      // included in the move.
      // In damozel, in 1855 MS, select entire stanza "(Alas!...stair?)". There is no matching
      // insert in the 1870 Proof.
      // In damozel, 1872 Fragment to 1855 MS. Match the entire fragment to where it goes. There are
      // extra inserts and deletes.

      LogHeader(
          "move to identical offsets on both sides"); // There shouldn't be inserted inserts and
      // deletes when the moves overlap
      createMove(0, 38, 71, 1, 40, 71);
      analyze("ram_move_to_identical_offsets_on_both_sides0"); // file6 is base, file7 is witness
      removeMove(0, 38, 71, 1, 40, 71);

      LogHeader("end move with a change and white space"); // the generated insert is too long
      createMove(0, 390, 414, 1, 118, 153);
      analyze("ram_end_move_with_a_change_and_white_space0"); // file6 is base, file7 is witness
      removeMove(0, 390, 414, 1, 118, 153);

      LogHeader(
          "end move with multiple white space"); // an extra token is added to the generated insert
      createMove(0, 188, 223, 1, 673, 688);
      analyze("ram_end_move_with_multiple_white_space0"); // file6 is base, file7 is witness
      removeMove(0, 188, 223, 1, 673, 688);

      LogHeader(
          "start move with a space"); // In a move, select a space as the first character, then the
      // matching delete erroneously includes the word before.
      createMove(0, 43, 56, 1, 191, 204);
      analyze("ram_start_move_with_a_space0"); // file6 is base, file7 is witness
      removeMove(0, 43, 56, 1, 191, 204);

      LogHeader("extra delete bug");
      createMove(0, 521, 548, 1, 427, 633);
      analyze("ram_extra_delete_bug0"); // file6 is base, file7 is witness
      removeMove(0, 521, 548, 1, 427, 633);

      LogHeader("Create a move that completely encompasses a change.");
      createMove(0, 9, 18, 1, 75, 193);
      analyze("ram_encompass0"); // file6 is base, file7 is witness
      analyze("ram_encompass1"); // file7 is base, file6 is witness
      removeMove(0, 9, 18, 1, 75, 193);

      LogHeader("Create a move that overlaps the top of an insert.");
      createMove(0, 457, 485, 1, 180, 308);
      analyze("ram_overlap_top0"); // file6 is base, file7 is witness
      analyze("ram_overlap_top1"); // file7 is base, file6 is witness
      removeMove(0, 457, 485, 1, 180, 308);

      LogHeader("Create a move that overlaps the bottom of an insert.");
      createMove(0, 457, 485, 1, 566, 667);
      analyze("ram_overlap_bottom0"); // file6 is base, file7 is witness
      analyze("ram_overlap_bottom1"); // file7 is base, file6 is witness
      removeMove(0, 457, 485, 1, 566, 667);

      LogHeader("Create a move that is completely inside an insert.");
      createMove(0, 457, 485, 1, 281, 395);
      analyze("ram_inside_move0"); // file6 is base, file7 is witness
      analyze("ram_inside_move1"); // file7 is base, file6 is witness
      removeMove(0, 457, 485, 1, 281, 395);

      LogHeader("Create a move that is completely inside a change.");
      createMove(0, 121, 131, 1, 643, 655);
      analyze("ram_inside_change0"); // file6 is base, file7 is witness
      analyze("ram_inside_change1"); // file7 is base, file6 is witness
      removeMove(0, 121, 131, 1, 643, 655);

      LogHeader("Create a move that has an insert and a change");
      createMove(0, 280, 356, 1, 321, 350);
      analyze("ram_insert_change0"); // file6 is base, file7 is witness
      analyze("ram_insert_change1"); // file7 is base, file6 is witness
      removeMove(0, 280, 356, 1, 321, 350);

      analyze("ram_baseline0"); // file6 is base, file7 is witness
      analyze("ram_baseline1"); // file7 is base, file6 is witness
    } catch (ReportedException e) {
      e.printStackTrace();
      fail();
    } catch (LoggedException e) {
      e.printStackTrace();
      fail();
    }
  }