/**
   * We create the following group structure:
   *
   * <p>Group3 / \ Group1 Group2 \ / \ Group0 Group4 / \ / User0 User1
   *
   * @throws Exception
   */
  public void createGroups() throws Exception {
    Random rand = new Random();

    // create group0 containing user0 and user1
    ArrayList<Link> G0Members = new ArrayList<Link>();
    G0Members.add(new Link(ContentName.fromNative(userNamespace, friendlyNames[0])));
    G0Members.add(new Link(ContentName.fromNative(userNamespace, friendlyNames[1])));
    groupName[0] = "group0-" + rand.nextInt(10000);
    group[0] = acm.groupManager().createGroup(groupName[0], G0Members, 0);

    // create group4 containing user1
    ArrayList<Link> G4Members = new ArrayList<Link>();
    G4Members.add(new Link(ContentName.fromNative(userNamespace, friendlyNames[1])));
    groupName[4] = "group4-" + rand.nextInt(10000);
    group[4] = acm.groupManager().createGroup(groupName[4], G4Members, 0);

    // create group1 and group2 containing group0
    ArrayList<Link> G1G2Members = new ArrayList<Link>();
    G1G2Members.add(new Link(ContentName.fromNative(groupNamespace, groupName[0])));
    groupName[1] = "group1-" + rand.nextInt(10000);
    group[1] = acm.groupManager().createGroup(groupName[1], G1G2Members, 0);
    groupName[2] = "group2-" + rand.nextInt(10000);
    group[2] = acm.groupManager().createGroup(groupName[2], G1G2Members, 0);

    // create group3 containing group1 and group2
    ArrayList<Link> G3Members = new ArrayList<Link>();
    G3Members.add(new Link(ContentName.fromNative(groupNamespace, groupName[1])));
    G3Members.add(new Link(ContentName.fromNative(groupNamespace, groupName[2])));
    groupName[3] = "group3-" + rand.nextInt(10000);
    group[3] = acm.groupManager().createGroup(groupName[3], G3Members, 0);

    // record the creation time of the original group keys
    for (int i = 0; i < numberOfGroups; i++) groupKeyCreationTime[i] = group[i].publicKeyVersion();

    // check the size of the groups
    Assert.assertEquals(2, group[0].membershipList().membershipList().size());
    Assert.assertEquals(1, group[1].membershipList().membershipList().size());
    Assert.assertEquals(1, group[2].membershipList().membershipList().size());
    Assert.assertEquals(2, group[3].membershipList().membershipList().size());
    Assert.assertEquals(1, group[4].membershipList().membershipList().size());
  }
  @BeforeClass
  public static void setUpBeforeClass() throws Exception {

    CCNTestHelper testHelper = new CCNTestHelper(GroupRecursiveKeyUpdateTestRepo.class);
    directoryBase = testHelper.getTestNamespace("testInOrder");
    userNamespace =
        GroupAccessControlProfile.userNamespaceName(UserConfiguration.defaultNamespace());
    groupNamespace =
        GroupAccessControlProfile.groupNamespaceName(UserConfiguration.defaultNamespace());
    userKeyStorePrefix = ContentName.fromNative(UserConfiguration.defaultNamespace(), "_keystore_");

    // create user identities with TestUserData
    td = new CreateUserData(userKeyStorePrefix, numberOfusers, true, "password".toCharArray());
    td.publishUserKeysToRepository(userNamespace);
    friendlyNames = td.friendlyNames().toArray(new String[0]);

    // create ACM
    handle = td.getHandleForUser(friendlyNames[1]);
    acm = new GroupAccessControlManager(directoryBase, groupNamespace, userNamespace, handle);
    acm.publishMyIdentity(
        ContentName.fromNative(userNamespace, friendlyNames[1]),
        handle.keyManager().getDefaultPublicKey());
  }