private void iterateAllDocuments(Database db, Set<Document> secondReference) {
      System.out.println(
          "Thread " + Thread.currentThread().getName() + " BEGINNING ITERATION of Documents");
      Session s = db.getParent();
      DocumentCollection dc = db.getAllDocuments();
      for (Document doc : dc) {
        docCount++;
        Vector v = doc.getItemValue("$UpdatedBy");
        for (Object o : v) {
          if (o instanceof String) {
            Name n = s.createName((String) o);
            String cn = n.getCommon();
            nameCount++;
          }
        }
        if (docCount % 1000 == 0) {
          secondReference.add(db.getDocumentByID(doc.getNoteID()));
        }
        if (docCount % 2000 == 0) {
          thirdReference.add(doc);
        }

        DateTime toxic = doc.getLastModified();
        String busyWork = toxic.getGMTTime();
        DateTime toxic2 = doc.getLastModified();
        String busyWork2 = toxic2.getDateOnly();
        // System.out.println("LastMod: " + toxic.getGMTTime());
        dateCount++;
      }
      System.out.println("ENDING ITERATION of Documents");
    }
    private void iterateForms(Database db) {
      System.out.println(
          "Thread " + Thread.currentThread().getName() + " BEGINNING ITERATION of Forms");
      Vector<Form> forms = db.getForms();
      for (Form form : forms) {
        // System.out.println("Form : " + form.getName() + " (" +
        // DominoUtils.getUnidFromNotesUrl(form.getNotesURL()) + ")");
        Document d = form.getDocument();
        Vector v = d.getItemValue("$UpdatedBy");

        Name n = db.getParent().createName((String) v.get(0));
        String cn = n.getCommon();
        nameCount++;
        docCount++;
        // System.out.println("Last Editor: " + n);
      }
      System.out.println("ENDING ITERATION of Forms");
    }
    @Override
    public void run() {
      long start = System.nanoTime();

      org.openntf.domino.Session s = null;
      if (Thread.currentThread() instanceof DominoChildThread) {
        s =
            (org.openntf.domino.Session)
                ((DominoChildThread) Thread.currentThread()).getContextVar("session");
      }
      Database db = null;
      if (Thread.currentThread() instanceof DominoChildThread) {
        db =
            (org.openntf.domino.Database)
                ((DominoChildThread) Thread.currentThread()).getContextVar("database");
      }
      // Database db = s.getDatabase("", "events4.nsf");

      RunContext rc = s.getRunContext();
      System.out.println("RunContext: " + rc.toString());
      Name sname = s.getUserNameObject();
      DateFormat df = new SimpleDateFormat("yyyyMMddhhmmss");
      System.out.println(df.format(new Date()) + " Name: " + sname.getCanonical());
      if (INCLUDE_FORMS) {
        iterateForms(db);
      }
      Set<Document> secondReference = new HashSet<Document>();
      iterateAllDocuments(db, secondReference);
      System.gc();
      NoteCollection nc = db.createNoteCollection(false);
      nc.buildCollection();
      iterateSecondReferences(secondReference);
      iterateThirdReferences();

      long elapsed = System.nanoTime() - start;
      StringBuilder sb = new StringBuilder();
      sb.append("Thread " + Thread.currentThread().getName());
      sb.append(" *** ALL OPERATIONS COMPLETE elapsed time: ");
      sb.append(elapsed / 1000000 + "ms: processed ");
      sb.append(nameCount + " names, ");
      sb.append(docCount + " docs, and ");
      sb.append(dateCount + " datetimes without recycling.");
      System.out.println(sb.toString());
    }
  protected void compareNames(
      final String message,
      final lotus.domino.Name l,
      final org.openntf.domino.Name o,
      final NotesBug... notesbug)
      throws NotesException {

    assertEquals(message + ": getAddr821()", l.getAddr821(), o.getAddr821());
    assertEquals(
        message + ": getAddr822Comment1()", l.getAddr822Comment1(), o.getAddr822Comment1());
    assertEquals(
        message + ": getAddr822Comment2()", l.getAddr822Comment2(), o.getAddr822Comment2());
    assertEquals(
        message + ": getAddr822Comment3()", l.getAddr822Comment3(), o.getAddr822Comment3());

    assertEquals(
        message + ": getAddr822LocalPart()", l.getAddr822LocalPart(), o.getAddr822LocalPart());
    assertEquals(message + ": getAddr822Phrase()", l.getAddr822Phrase(), o.getAddr822Phrase());
    assertEquals(message + ": getADMD()", l.getADMD(), o.getADMD());

    assertEquals(message + ": getCommon()", l.getCommon(), o.getCommon());

    assertEquals(message + ": getCountry()", l.getCountry(), o.getCountry());
    assertEquals(message + ": getGeneration()", l.getGeneration(), o.getGeneration());
    assertEquals(message + ": getGiven()", l.getGiven(), o.getGiven());
    assertEquals(message + ": getInitials()", l.getInitials(), o.getInitials());
    assertEquals(message + ": isHierarchical()", l.isHierarchical(), o.isHierarchical());

    // assertEquals(message + ": getKeyword()", l.getKeyword(), o.getKeyword());
    assertEquals(message + ": getLanguage()", l.getLanguage(), o.getLanguage());

    if (!NotesBug.O.isPresent(notesbug))
      assertEquals(message + ": getOrganization()", l.getOrganization(), o.getOrganization());
    if (!NotesBug.OUs.isPresent(notesbug)) {
      assertEquals(message + ": getOrgUnit1()", l.getOrgUnit1(), o.getOrgUnit1());
      assertEquals(message + ": getOrgUnit2()", l.getOrgUnit2(), o.getOrgUnit2());

      assertEquals(message + ": getOrgUnit3()", l.getOrgUnit3(), o.getOrgUnit3());
      assertEquals(message + ": getOrgUnit4()", l.getOrgUnit4(), o.getOrgUnit4());
    }
    assertEquals(message + ": getPRMD()", l.getPRMD(), o.getPRMD());
    assertEquals(message + ": getSurname()", l.getSurname(), o.getSurname());

    // TODO: it seems that getCanonical + getAbbreviated returns the original string, if the name is
    // invalid
    assertEquals(message + ": getCanonical()", l.getCanonical(), o.getCanonical());
    assertEquals(message + ": getAbbreviated()", l.getAbbreviated(), o.getAbbreviated());
  }