/**
   * Removes the group created in the server stored contact list by the create group test, makes
   * sure that the corresponding event has been generated and verifies that the group is not in the
   * list any more.
   */
  public void postTestRemoveGroup() {
    logger.trace("testing removal of server stored groups");

    // first add a listener
    GroupChangeCollector groupChangeCollector = new GroupChangeCollector();
    opSetPersPresence1.addServerStoredGroupChangeListener(groupChangeCollector);

    try {
      // remove the group
      opSetPersPresence1.removeServerStoredContactGroup(
          opSetPersPresence1.getServerStoredContactListRoot().getGroup(testGroupName2));
    } catch (OperationFailedException ex) {
      logger.error("error removing group", ex);
    }

    groupChangeCollector.waitForEvent(10000);

    opSetPersPresence1.removeServerStoredGroupChangeListener(groupChangeCollector);

    // check whether we got group created event
    assertEquals("Collected Group Change event", 1, groupChangeCollector.collectedEvents.size());

    assertEquals(
        "Group name.",
        testGroupName2,
        ((ServerStoredGroupEvent) groupChangeCollector.collectedEvents.get(0))
            .getSourceGroup()
            .getGroupName());

    // check whether the group is still on the contact list
    ContactGroup group =
        opSetPersPresence1.getServerStoredContactListRoot().getGroup(testGroupName2);

    assertNull("A freshly removed group was still on the contact list.", group);
  }
  /**
   * Creates a group in the server stored contact list, makes sure that the corresponding event has
   * been generated and verifies that the group is in the list.
   *
   * @throws java.lang.Exception
   */
  public void postTestCreateGroup() throws Exception {
    // first clear the list
    fixture.clearProvidersLists();

    Object o = new Object();
    synchronized (o) {
      o.wait(3000);
    }

    logger.trace("testing creation of server stored groups");
    // first add a listener
    GroupChangeCollector groupChangeCollector = new GroupChangeCollector();
    opSetPersPresence1.addServerStoredGroupChangeListener(groupChangeCollector);

    // create the group
    opSetPersPresence1.createServerStoredContactGroup(
        opSetPersPresence1.getServerStoredContactListRoot(), testGroupName);

    groupChangeCollector.waitForEvent(10000);

    opSetPersPresence1.removeServerStoredGroupChangeListener(groupChangeCollector);

    // check whether we got group created event
    assertEquals("Collected Group Change events: ", 1, groupChangeCollector.collectedEvents.size());

    assertEquals(
        "Group name.",
        testGroupName,
        ((ServerStoredGroupEvent) groupChangeCollector.collectedEvents.get(0))
            .getSourceGroup()
            .getGroupName());

    // check whether the group is retrievable
    ContactGroup group =
        opSetPersPresence1.getServerStoredContactListRoot().getGroup(testGroupName);

    assertNotNull("A newly created group was not in the contact list.", group);

    assertEquals("New group name", testGroupName, group.getGroupName());

    // when opearting with groups . the group must have entries
    // so changes to take effect. Otherwise group will be lost after loggingout
    try {
      opSetPersPresence1.subscribe(group, fixture.userID2);

      synchronized (o) {
        o.wait(1500);
      }
    } catch (Exception ex) {
      fail("error adding entry to group : " + group.getGroupName() + " " + ex.getMessage());
    }
  }
  /**
   * Renames our test group and checks whether corresponding events are triggered. Verifies whether
   * the group has really changed its name and whether it is findable by its new name. Also makes
   * sure that it does not exist under its previous name any more.
   */
  public void postTestRenameGroup() {
    logger.trace("Testing renaming groups.");

    ContactGroup group =
        opSetPersPresence1.getServerStoredContactListRoot().getGroup(testGroupName);

    // first add a listener
    GroupChangeCollector groupChangeCollector = new GroupChangeCollector();
    opSetPersPresence1.addServerStoredGroupChangeListener(groupChangeCollector);

    // change the name and wait for a confirmation event
    opSetPersPresence1.renameServerStoredContactGroup(group, testGroupName2);

    groupChangeCollector.waitForEvent(10000);

    opSetPersPresence1.removeServerStoredGroupChangeListener(groupChangeCollector);

    // examine the event
    assertEquals("Collected Group Change event", 1, groupChangeCollector.collectedEvents.size());

    assertEquals(
        "Group name.",
        testGroupName2,
        ((ServerStoredGroupEvent) groupChangeCollector.collectedEvents.get(0))
            .getSourceGroup()
            .getGroupName());

    // check whether the group is still on the contact list
    ContactGroup oldGroup =
        opSetPersPresence1.getServerStoredContactListRoot().getGroup(testGroupName);

    assertNull("A group was still findable by its old name after renaming.", oldGroup);

    // make sure that we could find the group by its new name.
    ContactGroup newGroup =
        opSetPersPresence1.getServerStoredContactListRoot().getGroup(testGroupName2);

    assertNotNull("Could not find a renamed group by its new name.", newGroup);
  }
  /**
   * Create the contact list. Later will be test to be sure that creating is ok
   *
   * @throws Exception
   */
  public void prepareContactList() throws Exception {
    fixture.clearProvidersLists();

    Object o = new Object();
    synchronized (o) {
      o.wait(3000);
    }

    String contactList =
        System.getProperty(GibberishProtocolProviderServiceLick.CONTACT_LIST_PROPERTY_NAME, null);

    logger.debug(
        "The "
            + GibberishProtocolProviderServiceLick.CONTACT_LIST_PROPERTY_NAME
            + " property is set to="
            + contactList);

    if (contactList == null || contactList.trim().length() < 6) // at least 4 for a UIN, 1 for the
      // dot and 1 for the grp name
      throw new IllegalArgumentException(
          "The "
              + GibberishProtocolProviderServiceLick.CONTACT_LIST_PROPERTY_NAME
              + " property did not contain a contact list.");
    StringTokenizer tokenizer = new StringTokenizer(contactList, " \n\t");

    logger.debug("tokens contained by the CL tokenized=" + tokenizer.countTokens());

    Hashtable<String, List<String>> contactListToCreate = new Hashtable<String, List<String>>();

    // go over all group.uin tokens
    while (tokenizer.hasMoreTokens()) {
      String groupUinToken = tokenizer.nextToken();
      int dotIndex = groupUinToken.indexOf(".");

      if (dotIndex == -1) {
        throw new IllegalArgumentException(groupUinToken + " is not a valid Group.UIN token");
      }

      String groupName = groupUinToken.substring(0, dotIndex);
      String uin = groupUinToken.substring(dotIndex + 1);

      if (groupName.trim().length() < 1 || uin.trim().length() < 4) {
        throw new IllegalArgumentException(
            groupName + " or " + uin + " are not a valid group name or Gibberish user id.");
      }

      // check if we've already seen this group and if not - add it
      List<String> uinInThisGroup = contactListToCreate.get(groupName);
      if (uinInThisGroup == null) {
        uinInThisGroup = new ArrayList<String>();
        contactListToCreate.put(groupName, uinInThisGroup);
      }

      uinInThisGroup.add(uin);
    }

    // now init the list
    Enumeration<String> newGroupsEnum = contactListToCreate.keys();

    // go over all groups in the contactsToAdd table
    while (newGroupsEnum.hasMoreElements()) {
      String groupName = newGroupsEnum.nextElement();
      logger.debug("Will add group " + groupName);

      opSetPersPresence1.createServerStoredContactGroup(
          opSetPersPresence1.getServerStoredContactListRoot(), groupName);

      ContactGroup newlyCreatedGroup =
          opSetPersPresence1.getServerStoredContactListRoot().getGroup(groupName);

      Iterator<String> contactsToAddToThisGroup = contactListToCreate.get(groupName).iterator();
      while (contactsToAddToThisGroup.hasNext()) {
        String id = contactsToAddToThisGroup.next();

        logger.debug("Will add buddy " + id);
        opSetPersPresence1.subscribe(newlyCreatedGroup, id);
      }
    }

    // store the created contact list for later reference
    GibberishSlickFixture.preInstalledBuddyList = contactListToCreate;
  }
  /**
   * Retrieves a server stored contact list and checks whether it contains all contacts that have
   * been added there during the initialization phase by the testerAgent.
   */
  public void testRetrievingServerStoredContactList() {
    ContactGroup rootGroup = opSetPersPresence1.getServerStoredContactListRoot();

    logger.debug("=========== Server Stored Contact List =================");

    logger.debug(
        "rootGroup="
            + rootGroup.getGroupName()
            + " rootGroup.childContacts="
            + rootGroup.countContacts()
            + "rootGroup.childGroups="
            + rootGroup.countSubgroups()
            + "Printing rootGroupContents=\n"
            + rootGroup.toString());

    Hashtable<String, List<String>> expectedContactList =
        GibberishSlickFixture.preInstalledBuddyList;

    logger.debug("============== Expected Contact List ===================");
    logger.debug(expectedContactList);

    // Go through the contact list retrieved by the persistence presence set
    // and remove the name of every contact and group that we find there from
    // the expected contct list hashtable.
    Iterator<ContactGroup> groups = rootGroup.subgroups();
    while (groups.hasNext()) {
      ContactGroup group = groups.next();

      List<String> expectedContactsInGroup = expectedContactList.get(group.getGroupName());

      // When sending the offline message
      // the sever creates a group NotInContactList,
      // because the buddy we are sending message to is not in
      // the contactlist. So this group must be ignored
      if (!group.getGroupName().equals("NotInContactList")) {
        assertNotNull(
            "Group "
                + group.getGroupName()
                + " was returned by "
                + "the server but was not in the expected contact list.",
            expectedContactsInGroup);

        Iterator<Contact> contactsIter = group.contacts();
        while (contactsIter.hasNext()) {
          String contactID = contactsIter.next().getAddress();
          expectedContactsInGroup.remove(contactID);
        }

        // If we've removed all the sub contacts, remove the group too.
        if (expectedContactsInGroup.size() == 0) expectedContactList.remove(group.getGroupName());
      }
    }

    // whatever we now have in the expected contact list snapshot are groups,
    // that have been added by the testerAgent but that were not retrieved
    // by the persistent presence operation set.
    assertTrue(
        "The following contacts were on the server sidec contact "
            + "list, but were not returned by the pers. pres. op. set"
            + expectedContactList.toString(),
        expectedContactList.isEmpty());
  }